跳转至

产品闭环分析:从信息孤岛到数据闭环

分析日期:2026-02-13 分析范围:lead-tracking、callytics-infrastructure、studio-api 三大模块 分析目标:识别产品闭环缺失点,制定改进路线


1. 核心结论

1.1 一句话总结

你的系统是一个极其优秀的「通话分析器」,但不是一个「销售闭环系统」。 三个 agent 一致认为:数据采集能力强,但数据之间是孤岛,老板看到的是 "发生了什么",而不是 "我该做什么"。

1.2 问题本质

系统是三个各自优秀但互不对话的子系统。Lead-tracking 做好了采集,callytics 做好了 AI 分析(prompt 写得非常棒),studio-api 做好了展示。但它们之间的连接线——phone 匹配、history 注入、outcome 回写、事件触发——全部缺失或只在运行时临时计算。

打通这些连接线不需要重写任何系统,只需要 把已有的点连成线


2. 当前架构(三个信息孤岛)

2.1 整体数据流

graph LR
    subgraph "Island 1: Lead Tracking"
        E[Lark Suite 邮箱] -->|IMAP 每5分钟| P[IMAP Poller Lambda]
        P -->|解析邮件| LT[(LeadTracking-v2<br/>DynamoDB)]
    end

    subgraph "Island 2: Call Analysis"
        RC[RingCentral 通话] -->|Webhook| SQS[SQS Queue]
        SQS --> DL[Download Lambda]
        DL -->|录音| S3[(S3 Bucket)]
        S3 --> TR[Deepgram 语音转文字]
        TR -->|文本| AI[Bedrock AI 分析]
        AI -->|结构化数据| CA[(call-analysis<br/>DynamoDB)]
    end

    subgraph "Island 3: Studio API"
        API[studio-api]
        API -->|读取| LT
        API -->|读取| CA
        API -->|运行时 phone 匹配| API
        WEB[studio-web] -->|展示| BOSS[老板看到数据]
    end

    LT -.-|无持久链接| CA

2.2 各模块存储的数据

erDiagram
    LeadTracking_v2["LeadTracking-v2"] {
        string id PK "leadEmail + receivedAt"
        string leadEmail
        string phone "10-digit format"
        string firstName
        string lastName
        string bookedDate
        string bookedTime
        string leadType "Web Lead or Online Intro"
        string receivedAt
        string outcome "INTRO_BOOKED etc (手动或AI自动)"
        string outcomeUpdatedAt
        string outcomeUpdatedBy
        string outcomeHistory "array"
    }

    call_analysis["call-analysis"] {
        string telephonySessionId PK
        string callStartTime
        string fromPhoneNumber "E.164 format"
        string toPhoneNumber "E.164 format"
        string callDirection
        number callDuration
        string staff_name "AI-detected"
        string customer_type "AI-classified"
        string primary_category "AI-classified"
        string primary_subcategory "AI-classified"
        string primary_outcome "AI-classified"
        string follow_up_needed "AI-determined"
        string executive_summary "AI-generated"
    }

    LeadTracking_v2 ||--o{ call_analysis : "no direct FK"

核心问题:两个表之间没有 Foreign Key

  • Lead 的 phone 存为 10 位(7328561597
  • Call 的 phone 存为 E.164(+17328561597
  • 每次展示都靠 studio-api 在运行时做 phone 匹配
  • 结果不持久化,无法追溯

3. 8 个关键断裂点

3.1 断裂点总览

graph TD
    G1["GAP 1: Phone 格式不一致<br/>Lead=10位 vs Call=E.164"]
    G2["GAP 2: 无 Call→Lead 持久关联<br/>每次运行时重新匹配"]
    G3["GAP 3: CUSTOMER_HISTORY 未注入<br/>Prompt 有占位符但代码没实现"]
    G4["GAP 4: AI Outcome 不写回 Lead<br/>AI说intro_booking但Lead.outcome=null"]
    G5["GAP 5: Outcome 变更无事件<br/>无 SNS/EventBridge 触发"]
    G6["GAP 6: AI vs 手动 Outcome 无校验<br/>可能冲突无人发现"]
    G7["GAP 7: 同一人多条 Lead<br/>无 phone 去重机制"]
    G8["GAP 8: 通话无生命周期标签<br/>不知道是首次还是跟进"]

    G1 -->|阻塞| G2
    G2 -->|阻塞| G3
    G2 -->|阻塞| G4
    G4 -->|导致| G5
    G4 -->|导致| G6
    G7 -->|恶化| G2
    G8 -->|影响| G4

    style G1 fill:#ff6b6b,color:#fff
    style G2 fill:#ff6b6b,color:#fff
    style G3 fill:#ff6b6b,color:#fff
    style G4 fill:#ffa94d,color:#fff
    style G5 fill:#ffa94d,color:#fff
    style G6 fill:#ffd43b,color:#333
    style G7 fill:#ffd43b,color:#333
    style G8 fill:#ffd43b,color:#333

3.2 详细说明

# 断裂点 严重度 代码位置 具体问题
1 Phone 格式不一致 CRITICAL lead-tracking/poller.ts:65 normalizePhone() 存 10 位,call-analysis 存 E.164
2 无 Call→Lead 持久关联 CRITICAL call-history.ts:142-156 运行时 phone 匹配,不存 leadId
3 CUSTOMER_HISTORY 未注入 CRITICAL prompt-builder.ts:35-61 {CUSTOMER_HISTORY_WILL_BE_INJECTED_HERE} 但代码没实现
4 AI Outcome 不写回 Lead HIGH list.ts:78-84 AI 分析的 customer_type/outcome 不存回 LeadTracking
5 Outcome 变更无事件 HIGH update-outcome.ts:130-141 只写 DynamoDB,无 SNS/EventBridge
6 AI vs 手动 Outcome 无校验 MEDIUM types.ts:51-56 AI 说 follow_up_needed=true 但 Lead 标记 CLOSED
7 同一人多条 Lead MEDIUM poller.ts:159 id = email#timestamp 无法防止同一 phone 重复创建 Lead
8 通话无生命周期标签 MEDIUM call-history.ts:174-196 分了 before/after 但不标注 stage

3.3 GAP 3 详解:最大的已有但未实现的功能

sequenceDiagram
    participant RC as RingCentral
    participant Lambda as AI Analysis Lambda
    participant Prompt as standard-v1.0.0.txt
    participant Bedrock as Amazon Bedrock

    RC->>Lambda: 通话录音 + 转录文本
    Lambda->>Lambda: buildAnalysisPrompt()
    Note right of Lambda: ✅ 注入了 STAFF_LIST
    Note right of Lambda: ❌ 没有注入 CUSTOMER_HISTORY
    Lambda->>Prompt: 替换占位符
    Note over Prompt: {CUSTOMER_HISTORY_WILL_BE_INJECTED_HERE}<br/>← 这行原样保留在 prompt 里!
    Lambda->>Bedrock: 发送 prompt + transcript
    Bedrock-->>Lambda: AI 分析结果
    Note over Lambda: AI 无法看到此客户的历史通话<br/>无法识别回访客户<br/>无法检测升级模式

prompt-builder.ts 第 35-61 行的代码:

  • ✅ 检查了 {STAFF_LIST_WILL_BE_INJECTED_HERE} 并替换
  • 完全没有处理 {CUSTOMER_HISTORY_WILL_BE_INJECTED_HERE}
  • 占位符文本原样发送给 Bedrock

4. 文档愿景 vs 实际实现对比

4.1 7 种 Call Type 的实现状况

graph LR
    subgraph "文档定义的 7 种 Call Type"
        LC[Lead Call]
        FC[Follow-up Call]
        SC[Service Call]
        RFC[Referral Call]
        WBC[Win-back Call]
        RMC[Reminder Call]
        RTC[Retention Call]
    end

    subgraph "Prompt 中的实现"
        IB[intro_booking]
        MPR[membership_purchase]
        SVC[service 子类]
        RP[reactivation_purchase]
        BC[booking_confirmation]
        REF[referral_program]
    end

    LC -->|50%| IB
    LC -->|50%| MPR
    FC -.->|0% 缺失| NONE1[❌ 无对应]
    SC -->|60%| SVC
    RFC -.->|20% 降级| REF
    WBC -->|80%| RP
    RMC -.->|30% 混淆| BC
    RTC -.->|0% 缺失| NONE2[❌ 无对应]

    style NONE1 fill:#ff6b6b,color:#fff
    style NONE2 fill:#ff6b6b,color:#fff
    style REF fill:#ffa94d,color:#fff
    style BC fill:#ffd43b,color:#333

4.2 客户分级的缺失

文档的 A/B/C/D 分级 Prompt 的 customer_type 差距
A 级(高意愿+高匹配) prospective_client Prompt 无法区分 A 和 C,都叫 prospective
B 级(有意愿+有顾虑) prospective_client 无顾虑类型标注,无 objection 分类
C 级(低意愿+可激活) prospective_client 无激活时机评估
D 级(不匹配) prospective_client 无"建议放弃"信号

影响

文档强调 "80% 的精力放在 A/B 级客户上",但 AI 无法区分客户等级,老板不知道该把资源集中在谁身上。


5. 理想状态:详细工作流

5.1 完整 Lead 生命周期

关于自动分配

下图中 Lead 分配给 Staff 的步骤暂不自动化。当前由 Staff 在 Dashboard 上自行查看新 Lead 并手动拨打。未来可考虑自动分配。

graph TD
    %% ==================== STEP 1: Lead 到达 ====================
    subgraph "STEP 1: Lead 到达"
        EMAIL[Lead 通知邮件<br/>from Lark Suite]
        POLL[IMAP Poller Lambda<br/>每 5 分钟]
        PARSE[解析邮件内容]
        DEDUP{phone 去重检查}
        NEW_LEAD[创建新 Lead<br/>stage = new]
        MERGE[合并到已有 Lead<br/>更新 receivedAt]

        EMAIL --> POLL
        POLL --> PARSE
        PARSE --> DEDUP
        DEDUP -->|新 phone| NEW_LEAD
        DEDUP -->|已存在| MERGE
    end

    %% ==================== STEP 2: Staff 看到 Lead ====================
    subgraph "STEP 2: Staff 看到并拨打"
        DASH[Dashboard 显示新 Lead<br/>带 Hot/Warm/Cold 标签]
        SLA[Response Time SLA 倒计时<br/>目标: 5分钟内首次拨打]
        CALL[Staff 拨打电话]

        NEW_LEAD --> DASH
        MERGE --> DASH
        DASH --> SLA
        SLA --> CALL
    end

    %% ==================== STEP 3: 通话录制 ====================
    subgraph "STEP 3: 通话发生"
        RC_CALL[RingCentral 录制通话]
        WEBHOOK[Webhook 事件]
        SQS_Q[SQS Queue]

        CALL --> RC_CALL
        RC_CALL --> WEBHOOK
        WEBHOOK --> SQS_Q
    end

    %% ==================== STEP 4: AI 分析(增强版)====================
    subgraph "STEP 4: AI 分析(含历史注入)"
        DOWNLOAD[下载录音 to S3]
        TRANSCRIBE[Deepgram 语音转文字]
        LOOKUP["🆕 查询 LeadTracking<br/>by phone number"]
        HISTORY["🆕 获取该 phone 最近 3 通电话"]
        BUILD["🆕 构建 prompt<br/>注入 STAFF_LIST<br/>注入 CUSTOMER_HISTORY"]
        BEDROCK[Amazon Bedrock AI 分析]
        SAVE_CALL[保存到 call-analysis<br/>含 customer_type, outcome,<br/>coaching, follow_up 等]
        SAVE_LINK["🆕 保存 leadId 关联"]

        SQS_Q --> DOWNLOAD
        DOWNLOAD --> TRANSCRIBE
        TRANSCRIBE --> LOOKUP
        LOOKUP --> HISTORY
        HISTORY --> BUILD
        BUILD --> BEDROCK
        BEDROCK --> SAVE_CALL
        SAVE_CALL --> SAVE_LINK
    end

    %% ==================== STEP 5: Outcome 自动回写 ====================
    subgraph "STEP 5: Outcome 自动回写"
        STREAM["🆕 DynamoDB Streams<br/>on call-analysis"]
        INFER["🆕 Outcome Inference Lambda"]
        MAP{"🆕 AI outcome<br/>→ Lead outcome 映射"}
        UPDATE_LEAD["🆕 更新 LeadTracking:<br/>outcome, stage,<br/>lastContactTime, callRef"]

        SAVE_LINK --> STREAM
        STREAM --> INFER
        INFER --> MAP
        MAP -->|intro_booking| UPDATE_LEAD
        MAP -->|membership_purchase| UPDATE_LEAD
        MAP -->|no match| SKIP[不更新]
    end

    %% ==================== STEP 6: 老板看完整漏斗 ====================
    subgraph "STEP 6: 老板看到完整漏斗"
        TODAY["今日概要<br/>12通话 / 3 booking / 2待跟进"]
        FUNNEL["完整漏斗<br/>47 Leads → 43 Calls → 18 Booked"]
        PERF["Staff 绩效卡<br/>Sarah: 33% 转化率"]
        FOLLOWUP["Follow-up 任务队列<br/>带 SLA 倒计时"]
        COACHING["Coaching 趋势<br/>本周弱点: 异议处理"]

        UPDATE_LEAD --> TODAY
        UPDATE_LEAD --> FUNNEL
        UPDATE_LEAD --> PERF
        UPDATE_LEAD --> FOLLOWUP
        UPDATE_LEAD --> COACHING
    end

    %% ==================== 未来: 行动触发 ====================
    subgraph "FUTURE: 自动行动触发"
        EVENT["🆕 EventBridge Rule<br/>on outcome change"]
        SMS[发送确认 SMS]
        TASK[创建 Follow-up 任务]
        ALERT[通知 Staff]

        UPDATE_LEAD -.->|未来| EVENT
        EVENT -.-> SMS
        EVENT -.-> TASK
        EVENT -.-> ALERT
    end

5.2 AI 分析增强:CUSTOMER_HISTORY 注入流程

sequenceDiagram
    participant SQS as SQS Queue
    participant Lambda as AI Analysis Lambda
    participant LT as LeadTracking-v2
    participant CA as call-analysis
    participant Bedrock as Amazon Bedrock

    SQS->>Lambda: 新通话事件

    Lambda->>Lambda: 下载录音, 转录

    rect rgb(200, 255, 200)
        Note over Lambda,CA: 🆕 新增: 查询历史
        Lambda->>CA: 查询 fromPhoneNumber 最近 3 通电话
        CA-->>Lambda: [{callStartTime, category, outcome, summary}]
        Lambda->>LT: 查询 phone 对应的 Lead 信息
        LT-->>Lambda: {firstName, receivedAt, bookedDate, outcome}
    end

    rect rgb(200, 220, 255)
        Note over Lambda,Bedrock: 🆕 增强: 构建完整 prompt
        Lambda->>Lambda: 替换 {STAFF_LIST_WILL_BE_INJECTED_HERE}
        Lambda->>Lambda: 🆕 替换 {CUSTOMER_HISTORY_WILL_BE_INJECTED_HERE}
        Note right of Lambda: "最近 3 通电话:<br/>- 2/11: intro call, booked<br/>- 2/8: price inquiry, no book<br/>Lead info: Jane Smith, 2/7到达"
        Lambda->>Bedrock: 完整 prompt + transcript
    end

    Bedrock-->>Lambda: AI 分析结果

    rect rgb(255, 220, 200)
        Note over Lambda,LT: 🆕 新增: 回写 Lead
        Lambda->>CA: 保存 call-analysis (含 leadId)
        Lambda->>LT: 更新 Lead: outcome, stage, lastContactTime
    end

为什么 CUSTOMER_HISTORY 不包含 SMS/Text 数据

Dashboard "All" 视图中同时展示了通话记录和 SMS 记录,但 CUSTOMER_HISTORY 注入只查询了通话数据。原因:

  1. SMS 没有持久化 — studio-api 每次加载 Lead 列表时实时调 RingCentral Message Store API 获取 SMS 数据,只提取 firstMessageTime(最早的 outbound 短信时间),内容不存储到任何 DynamoDB 表
  2. AI Lambda 没有 RingCentral OAuth token — 只有 studio-api 通过用户建立的 connection 才能访问 RingCentral API,AI 分析 Lambda 无法直接调用
  3. SMS 没有 transcript — 短信是纯文本,不经过 Transcribe,注入 prompt 的价值远低于通话分析摘要

如果未来需要将 SMS 纳入客户历史,前提是先实现 SMS 持久化(将 RingCentral SMS 数据定期同步到 DynamoDB),这可以作为 Phase 2+ 的考量。

5.3 Outcome 映射规则

graph LR
    subgraph "AI 分析输出(Prompt Taxonomy)"
        AI_IB["intro_booking<br/>+ outcome.result = success"]
        AI_MP["membership_purchase_related<br/>+ outcome.result = success"]
        AI_OTHER["所有其他 subcategory<br/>或 result ≠ success"]
    end

    subgraph "Lead Outcome(studio-api 定义)"
        L_BOOKED[INTRO_BOOKED]
        L_SKIP[不更新 — 保持当前状态]
    end

    AI_IB --> L_BOOKED
    AI_MP --> L_BOOKED
    AI_OTHER --> L_SKIP

当前映射范围有限

Phase 1 只实现了最高优先级的一条映射规则。LeadOutcomeValue 类型定义了 5 种值(INTRO_BOOKED | SELF_BOOKED | INVALID_LEAD | NO_CALL_LIST | CLOSED),但其中 SELF_BOOKED 需要 CRM 集成,INVALID_LEAD / NO_CALL_LIST / CLOSED 是手动设置的终态。

映射保护规则(shouldUpdateLeadOutcome

  • 只在 Lead outcome 为 null / undefined(尚未设置)时才自动写入
  • 手动终态 CLOSEDINVALID_LEADNO_CALL_LIST 不会被自动覆盖
  • 已有相同值时不重复写入
  • 每次自动更新记录 updatedBy: "system" 以区分手动/自动

6. 老板视角:Before vs After

6.1 Before(当前)

graph TD
    BOSS[老板登录 Dashboard]

    BOSS --> L_LIST[Lead 列表<br/>姓名/电话/来源/时间]
    BOSS --> C_LIST[通话列表<br/>日期/时长/员工/分类]
    BOSS --> METRICS[指标: 通话数/Booking数/取消数]

    L_LIST -.->|"需要手动关联"| C_LIST
    L_LIST -.->|"需要手动更新 Outcome"| L_LIST

    style BOSS fill:#4a90d9,color:#fff
    style L_LIST fill:#e9e9e9,color:#333
    style C_LIST fill:#e9e9e9,color:#333
    style METRICS fill:#e9e9e9,color:#333

老板的 "So What?" 反应:

系统展示的数据 老板的反应 缺失的关键
"今天有 12 通 intro call,3 个 booking" "那 3 个人来了吗?买了吗?" 到店 + 成交追踪
"Lead Jane Smith 3 天前打来" "为什么没人回她电话?她是热的还是冷的?" 响应时间 + 温度标签
"Sarah 今天接了 8 通电话" "她产生了多少收入?" 收入归因
"有 2 个 cancellation" "为什么取消?能挽回吗?" (这个 prompt 其实做得不错!)
"Coaching: Sarah 应该这样说..." "她有在改进吗?" 时间维度的技能追踪

核心结论

系统告诉老板 "What happened",但老板需要 "What should I do next"

6.2 After(理想)

graph TD
    BOSS[老板登录 Dashboard]

    BOSS --> TODAY["📊 今日概要<br/>12通话 | 3 booking | 2待跟进<br/>明星员工: Sarah (33%转化)"]
    BOSS --> FUNNEL["📈 完整漏斗<br/>47 Leads → 43 Calls → 18 Booked<br/>→ 12 到店 → 8 成交 = $4,800"]
    BOSS --> TASKS["✅ Follow-up 队列<br/>5个待跟进 | 2个即将超时<br/>Jane Smith: CC未采集, 剩余4h"]
    BOSS --> LEADS["🔥 Lead 列表<br/>🟢 Hot 3 | 🟡 Warm 8 | 🔴 Cold 5<br/>响应时间: 平均 34 分钟"]
    BOSS --> PERF["👤 Staff 绩效<br/>Sarah: 12通话→4 booking (33%)<br/>弱点: 异议处理 | 趋势: ↑ 改善中"]
    BOSS --> JOURNEY["🛤️ Lead 旅程<br/>Jane: 2/7到达 → 2/8首次联系(27min)<br/>→ 2/9预约 → 2/12到店 → 2/12成交"]

    style BOSS fill:#4a90d9,color:#fff
    style TODAY fill:#d4edda,color:#333
    style FUNNEL fill:#d4edda,color:#333
    style TASKS fill:#fff3cd,color:#333
    style LEADS fill:#d4edda,color:#333
    style PERF fill:#d4edda,color:#333
    style JOURNEY fill:#d4edda,color:#333

7. Prompt 升级建议

7.1 需要新增的 Call Type

新增 分类 理由
followupcall revenue_impacting 区分首次接触 vs 后续跟进,独立衡量跟进效果
retention_call revenue_impacting 主动关怀不活跃会员,而不是等他们取消
referral_call revenue_impacting (从 other 升级) 直接影响 Leads 数量,是低成本获客渠道
appointment_reminder service (独立于 booking_confirmation) pre-event 确认 ≠ online booking follow-up

7.2 需要新增的输出字段

字段 类型 说明
intent_level high / medium / low 客户转化意向评估
call_sequence first_contact / follow_up / retention 通话在 Lead 生命周期中的阶段
objection_type price / time / trust / none 客户主要异议类型
recommended_next_action string AI 建议的下一步行动

8. 实施路线图

详细的每个 Phase Before/After 描述和实施清单,请参阅 分阶段路线图


9. Debate 记录

9.1 共识区(三个 Agent 全部同意)

  1. 必须打通 Lead → Call 的数据链路 — 这是最高优先级,没有这个其他都白搭
  2. 必须实现 CUSTOMER_HISTORY 注入 — prompt 占位符已经写好了,但代码没实现,这是巨大浪费
  3. Follow-up Call 必须作为独立类型存在 — 不能把首次接触和后续跟进混为一谈
  4. Call outcome 应该自动写回 Lead — 手动更新 outcome 是不可持续的

9.2 争议区(Agent 们有不同观点)

9.2.1 争议 1:A/B/C/D 分级要不要加到 Prompt 里?

  • Agent 2(强烈支持): "这是 80/20 法则的体现,直接告诉销售'这个人值不值得花 20 分钟'"
  • Agent 3(谨慎支持): "先做一个简单的 Hot/Warm/Cold 三级标签就够了,A/B/C/D 太复杂,老板看不懂"
  • Agent 1(中立): "现在连 Lead 和 Call 都没打通,先做基础数据链路,分级是第二步"

判断: Agent 1 说得对——先打通数据,再做分级。但 Agent 3 的 Hot/Warm/Cold 简化方案比 Agent 2 的 A/B/C/D 更实用。

9.2.2 争议 2:模块化架构值不值得做?

  • Agent 2: "文档描述了完美的模块化,但现在客户只有 OrangeTheory,做模块化是过早优化"
  • Agent 3: "模块化是销售策略,不是技术架构。先把功能做出来,卖的时候再包装成套餐"

判断: 同意 Agent 3——模块化是 pricing 策略,不是当前的技术需求。先把功能做好,package 是商业层面的事。

9.2.3 争议 3:实时通话辅助值不值得做?

  • Agent 3(提出): "Real-time call assist 是终极差异化——销售接电话时,AI 实时提示话术"
  • Agent 2: "这是 12+ 周的工作量,且需要 live transcription,技术复杂度远超当前能力"

判断: 现阶段不值得做。投入产出比太低,而且现有的 post-call coaching 已经很强了,先把闭环做好。

9.2.4 争议 4:Referral Call 要不要从 "other" 升级到 "revenue_impacting"?

  • Agent 2(强烈支持): "文档说 referral 是'低成本获客高效渠道',放在 other 类别是对 referral 价值的贬低"
  • Agent 1(中立): "取决于 OrangeTheory 是否真的有 referral program"
  • Agent 3: "如果老板看到 referral call 数量为零,他会问'我们没在做 referral 吗?'——这本身就是有价值的 insight"

判断: 应该升级。Referral 影响 Leads 数量,直接关联收入公式 新客收入 = Leads × 转化率 × 客单价


9.3 通过的想法

想法 结论 理由
CUSTOMER_HISTORY 注入 ✅ 立即做 Prompt 已设计好,代码缺实现,ROI 最高
Phone 格式统一 ✅ 立即做 基础数据一致性,阻塞其他改进
AI Outcome 自动回写 ✅ 立即做 消除手动更新瓶颈
Follow-up Call 类型 ✅ Phase 3 无法区分首次和跟进是重大分析盲区
Retention Call 类型 ✅ Phase 3 系统完全被动,需要主动干预能力
Hot/Warm/Cold 标签 ✅ Phase 2 比 A/B/C/D 简单,老板更容易理解
Referral 升级到 revenue ✅ Phase 3 直接影响 Leads 数量,不该在 other 类别

9.4 保留/推迟的想法

想法 结论 理由
Lead 自动分配给 Staff ⏸️ 推迟 当前团队小,手动可行,自动化收益不大
A/B/C/D 完整分级 ⏸️ 简化为 Hot/Warm/Cold 4 级太复杂,3 级更实用
模块化架构 ⏸️ 推迟 当前只有 1 个客户,是 pricing 策略不是技术需求
ML 预测 Lead 转化率 ⏸️ 数据不足 需要 200+ 标注数据集,目前没有

9.5 否定的想法

想法 结论 理由 谁否定的
实时通话辅助 ❌ 不做 12+ 周工作量,需 live transcription,技术复杂度远超收益 Agent 2 + 综合判断
ML 预测 Lead 转化率 ❌ 数据不足 需要 200+ 标注数据集,目前没有 Agent 3(自己提出也自己承认太早)
完整 CRM 对接 ❌ 风险高 OTF 有自己的系统,API 不明确 Agent 1
5 层模块化架构 ❌ 过早优化 文档理想态,当前只有 1 个客户 Agent 2 + Agent 3
Staff Development Learning Paths ❌ 太远 需 UX + 内容 + ML,10+ 周 所有 Agent 同意太远期

10. Agent 1 关键代码级发现

10.1 发现 1:CUSTOMER_HISTORY 是最大的已有但未实现的功能

prompt-builder.ts:35-61 — 处理了 {STAFF_LIST_WILL_BE_INJECTED_HERE},完全没有处理 {CUSTOMER_HISTORY_WILL_BE_INJECTED_HERE}

AI 已经被设计为能理解客户历史(prompt 里写了怎么用),但 Lambda 代码从来没有注入这些数据。这是一个 "花了 80% 的钱但漏了最后 20%" 的问题。

10.2 发现 2:studio-api 已有 Lead-Call 匹配,但只在运行时

call-history.ts:142-156 的 phone 匹配逻辑:

  • 前端每次请求 Lead 列表时,API 实时查 call-analysis 表
  • 用 phone number 匹配 fromPhoneNumbertoPhoneNumber
  • 但结果不持久化——下次请求还要重新匹配

10.3 发现 3:Lead Outcome 已有 5 种状态但全靠手动

// studio-api/apps/api/src/routes/leads/types.ts
type LeadOutcomeValue =
  'INTRO_BOOKED' | 'SELF_BOOKED' | 'INVALID_LEAD' | 'NO_CALL_LIST' | 'CLOSED'

有 outcome history 追踪(谁在什么时候改的),但:

  • 没有从 AI 分析自动推断
  • 没有 outcome 变更事件触发
  • 没有与 AI 的 primary_outcome 交叉验证

10.4 发现 4:前端有 Lead 分组逻辑但很原始

lead-grouping.ts 按 phone + 3 天窗口分组,能检测 pre-contact calls,但没有生命周期阶段标签。


11. 核心 Metrics(改进后可追踪的指标)

指标 当前状态 改进后 意义
Response Time 无法追踪 Lead 到达 → 首次通话 影响转化率的第一要素
Lead Contact Rate 无法追踪 有通话的 Lead / 总 Lead 员工执行力
Booking Rate 手动计算 AI 自动统计 intro_booking 通话转预约效率
Follow-up Effectiveness 无法区分 跟进电话的独立转化率 持续跟进的价值
Staff Conversion Rate 每个员工的 Lead → Booking 率 绩效差异化管理
Coaching Trend 团队弱点趋势 + 改善速度 培训 ROI
Lead Temperature Accuracy Hot/Warm/Cold 预测 vs 实际转化 AI 分级准确性

12. 附录 A:关键文件索引

组件 文件路径 关键行数 用途
Lead 采集 lead-tracking/src/poller.ts 112-190 邮件解析和存储
Lead Schema lead-tracking/lib/leadtracking-stack.ts 17-50 DynamoDB 表和 GSI
AI Prompt 构建 callytics-infra/lambda/ai-analysis-processor/src/core/prompt-builder.ts 35-61 Prompt 占位符替换
AI 字段映射 callytics-infra/config/schemas/orangeTheory/ai-mappings/ai-mapping-v1.0.0.json 全文件 AI 输出 → DynamoDB 字段
Standard Prompt callytics-infra/config/schemas/orangeTheory/prompts/standard-v1.0.0.txt 全文件 1248 行 AI 分析指令
Lead 列表 API studio-api/apps/api/src/routes/leads/list.ts 88-259 Lead + Call 查询和匹配
Call 匹配逻辑 studio-api/apps/api/src/routes/leads/call-history.ts 102-164 Phone-based call 分发
Outcome 更新 studio-api/apps/api/src/routes/leads/update-outcome.ts 44-164 手动 outcome 更新
Lead 类型定义 studio-api/apps/api/src/routes/leads/types.ts 1-70 响应格式定义
前端 Lead 分组 studio-web/src/pages/lead-tracker-old/data/lead-grouping.ts 1-137 前端分组逻辑

13. 附录 B:Lead Outcome 定义(实际代码)

代码中没有 stage 字段。Lead 状态通过 outcome: LeadOutcomeValue 单一字段跟踪,定义在 studio-api/apps/api/src/routes/leads/types.ts

type LeadOutcomeValue = 'INTRO_BOOKED' | 'SELF_BOOKED' | 'INVALID_LEAD' | 'NO_CALL_LIST' | 'CLOSED';
Outcome 含义 设置方式
(null/undefined) 新 Lead,尚未处理 默认状态
INTRO_BOOKED 已预约体验课 自动:AI 判断 intro_booking + successmembership_purchase_related + success
SELF_BOOKED 客户自行在线预约 手动:Dashboard 用户标记
INVALID_LEAD 无效 Lead(空号/非目标) 手动:Dashboard 用户标记(终态,不可被自动覆盖)
NO_CALL_LIST 不可联系 手动:Dashboard 用户标记(终态,不可被自动覆盖)
CLOSED 已关闭/已转化 手动:Dashboard 用户标记(终态,不可被自动覆盖)