三大模块全景
对话策略项目目前由三个独立模块组成——共用一份「事实手册」(brand_profile + customer memory),共用一个意向分析上游,但生成路径、模型、人设、约束都不同。
破冰 / 培育 / 决策
高意向评论 → DM 私信,把潜客从冷启动聊到加微。
dm.ice_break.systemdm.nurture.systemdm.decision.systemchatReply / generateColdOpenerqwen3-235b(对话路)反向评论生成
同行视频下留一条评论,钩对方私信咨询(不主动 DM,避开 stranger-DM 风控)。
comment.reverse-comment-system-py-singleworker/scripts/local_reverse_comment_agent.pypickCandidates(peer-filter + off-topic 正则)<<unhookable>>(重级土建 / 家电品牌选购 / 物流维权 一票否决)+ <<retry>>(错称呼 / 「家人们」/ 凭空猜户型 → 重写)评论意向四轴分类
评论池入口打分 → 决定走 DM 还是反评、还是丢弃。服务于破冰 + 反评两条下游链路。
analyze.comments.systemanalyze.decision_signal.systemanalyzeComments(src/lib/llm.ts)deepseek-v4-flash(分析路)deriveIntent() short-circuit 到 label='无关'(家电 / 数码 / 促销询券防漏网)三模块横切对照表
| 维度 | 破冰模块 | 反评模块 | 意向模块 |
|---|---|---|---|
| 触达通道 | DM 私信(一对一) | 同行视频下公开留评(一对多旁观) | —(不直接触达,只打分分流) |
| 上游输入 | 意向打分 ≥ 阈值的评论 | 同行视频评论池 + peer-filter + off-topic | 全量 douyin comments |
| Langfuse prompt | dm.ice_break.systemdm.nurture.systemdm.decision.system |
comment.reverse-comment-system-py-single |
analyze.comments.systemanalyze.decision_signal.system |
| 实现位置 | TS · chatReply / generateColdOpener |
Python agent · local_reverse_comment_agent.py |
TS · analyzeComments |
| 模型 | qwen3-235b(对话路) |
配置项(Python 端可换) | deepseek-v4-flash(分析路) |
| 骨架颗粒度 | 6 段 + 8 slot(高自由度,LLM 负责风格 + 应变) | skeleton + 4 步话术 + 5 slot(低自由度,LLM 必须按骨架走) | 4 轴 JSON(结构化输出,下游公式合成分数) |
| 自检层 | sanitizeReply(协议字节)+ post ban check(v16) |
<<unhookable>>(一票否决)+ <<retry>>(重写) |
deriveIntent() + off_topic short-circuit |
| 数据出口 | message_queue: pending_approval → 审批 → ADB / WDA → DM |
reverse_comment_queue → WDA 留评 → status 回写 |
高意向 → DM 候选池 / 中意向 → 反评候选池 / 无关 → 丢回 |
| 当前版本 | v34 · 当前生产(v26 上线后四轮迭代 / v25 末轮 95.6%) |
v20 · 当前生产(v4 销售路线后持续迭代) |
v11 · 当前生产(v1 单值 → v10 四轴) |
| 7d 调用量 | 1,160 · Langfuse observations | 273 · 受 30d cooldown 约束 | 2,373 · 上游本就该最忙 |
| 改动风险 | 中(有 ban check 兜底,单条翻车不致命) | 高(公开通道翻车 → 整个号当天废) | ★ HIGH(同时影响 DM + 反评候选池分布) |
「当前版本」「7d 调用量」两行 + 顶部三张卡片由 scripts/build-dialogue-strategy-progress.ts 自动从 Langfuse 拉取(production label 版本 + 近 7 天 observations),数据更新于 2026-06-17。
三模块案例汇总
每个模块拿出最有代表性的 3 组证据 + 一条端到端链路示意。三模块共用同一个评论池入口(意向打分上游),但生成器、自检方式、出口完全不同——下面分 A / B / C 三块各自展开。
A · 破冰模块案例:v25 末轮 95.6%,现已迭代到 v30
v25 末轮 95.6%
v25 末轮真实生产:583 / 610。剩下 27 条全是账号 cookie 缺失没发出,不是 prompt 自身翻车——凭据齐就稳。v26(2026-05-29 13:03 promote)之后骨架不动、五天内又迭代四轮到 v30,本周观察 v30 价格口径灰度结果。Langfuse 上 dm.ice_break.system 7d 调用 1,160 次。
人设守住了
5/14 把人设从「小艾」改成「小艳」,同时把同音字、谐音字全加进黑名单。连查 30 条真实对话,没有一条出现「小艾」「AI 助手」「作为大模型」。
协议字节 0 漏
DeepSeek V3 系列偶尔漏 function_call / tool_use 字节当正文发。sanitizeReply 这层挡在 prompt 外,命中即降级,换模型也不去掉。
取上下文
视频文案 + 评论 + 客户 memory(自然语言短句)。
取 prompt
Langfuse 取 production label 当前版本(v30)。
LLM 生成
chat 走 qwen3-235b,analysis 走 deepseek-v4-flash。
后置安检
ban check + 协议字节扫,命中即拦下不发。
落库发送
写 conversations / messages,回写 contacted 防重复。
B · 反评模块案例:v4 切销售路线 → v14 持续迭代
视角换了一刀就稳
v1-v3 一直让模型用"内容创作者评论"的语气,结果留评像水军、钩不到 DM。v4(2026-05-13 与夏夏 Lark 对齐)把视角统一切到"销售来对方视频底下接活"——4 步话术固定:称呼 + 视频引用 + 销售肯定 + 反问 + 私信钩子。v5-v14 在这个骨架上持续打磨称呼锁、unhookable 触发面、私信钩子句式,现版本 v14(最近 5/18 promote)。Langfuse 上 7d 调用 273 次。
<<unhookable>> 拦得稳
原评论涉及承重墙 / 自建房 / 家电品牌选购 / 物流维权时,模型必须只输出 <<unhookable>>。运营再也不会拿到"我们卖油烟机"这种翻车文案。
称呼锁守住性别
昵称末位男性后缀(哥/叔/师傅)→ 原样保留整名;末位女性后缀(姐/姨/嫂)→ 原样保留;含典型男/女字 → "{昵称}哥/姐";性别不明 → 裸名直呼;英文 emoji → "朋友"。错性别即 <<retry>>。
挑候选
pickCandidates 用 peer-filter + off-topic 正则在同行视频评论池过滤。
写队列
命中候选写 reverse_comment_queue,每个 sec_uid 30 天 cooldown。
Python 生成
local_reverse_comment_agent.py 拉 Langfuse prompt,注入 skeleton。
骨架自检
命中 <<unhookable>> 拒;命中 <<retry>> 重写。
WDA 留评
iPhone WebDriverAgent 串行在同行视频下留评 + 回写状态。
C · 意向模块案例:v10 四轴稳定输出
四轴结构化输出(v10)
每条评论输出 {type, specificity, freshness, category, keywords, type_reason, category_reason} 七字段 JSON。下游 deriveIntent() 用前 3 轴合成 score,公式留在代码层——PM 改不到 prompt 也能调权重。v10 是 v1(单值 intent)到现在的第 10 次大改。Langfuse 7d 调用 2,373 次(是另两模块上游,量最大)。
off_topic short-circuit
category 命中 off_topic 时 deriveIntent() 直接 short-circuit 到 label='无关'。家电 / 数码 / 促销询券("618 蹲一波")一次性拦截,不进高意向队列。
正则与 LLM 双层防线
peer-filter(同行画像)+ off-topic 正则在 LLM 调用前先过一遍——省 token,也兜住 LLM 偶发漏判。规则在 src/lib/peer-filter.ts 共享给反评和破冰两条链路。
拉评论池
Cron 抓 douyin comments 最近一批,待打分。
正则预筛
peer-filter + off-topic 正则先扫一遍,过滤同行 / 家电 / 促销。
LLM 四轴
analyze.comments.system 给 deepseek-v4-flash,输出四轴 JSON。
合成 score
deriveIntent() 按公式算 score + label,off_topic 直接到"无关"。
分流
高意向 → DM 候选;中意向 → 反评候选;无关 → 丢回评论池。
三模块拆解
这不是一条 prompt 从头写到尾,而是多个 prompt 在不同时机被取出、装配、生成、净化、安检。下面 6 张图按"双通道全景 → 三模块内部架构 → 破冰 7 步深挖 → Prompt 解剖 → 模型路由 → 三条规则"逐层放大。Panel ① 给共享/分叉结构、Panel ② 把三模块并列展开、Panel ③ ④ 是破冰深度 zoom-in(反评 + 意向的等价细节嵌在同一个 Panel 里)。
① 全景图:对话策略的运转逻辑
整套对话策略的核心洞察:LLM 是"会自由发挥的销售实习生",它知道怎么聊,但不知道我们家具体卖什么、价格多少、品牌哪几个。因此方向反过来——中央放一份「事实手册」(brand_profile + customer memory),所有 prompt 在装配时从手册取值。LLM 只负责说话风格,事实层归 PMM。这是这条通道在多品牌、多活动节奏下能稳定运转的根因。
闹钟
评论池 + 三路分析(便宜模型先筛)
- analyze.intent 意图分 0–1,过阈值才放行
- analyze.signals 决策信号检测("想看方案/报个价")
- analyze.stage 装修阶段分类(写回
conversations.stage) - Langfuse trace + token 成本归因全程跟踪
状态机 · 公告板
conversations.stage· 同一条评论 4h 内只允许 claim 一次
· stage 字段由 analyze.stage 写回,
chatReply 按字段取对应 prompt Supabase conversations
+ message_queue
Prompt 装配
骨架 6 段 + 8 个 slot 注入
LLM 生成
净化 + 安检
+ post ban check · v16
入队送出
→ 运营审批 → ADB / WDA → 抖音
挑候选
写
reverse_comment_queuePython agent 生成
comment.reverse-comment-system-py-single骨架自检
<<unhookable>> 一票否决+
<<retry>> 重写WDA 留评
→ 回写
reverse_comment_queue.status事实手册 · brand_profile + memory(所有 slot 的单一来源)
PMM 改一次手册,所有 stage 的生成瞬间生效,不动代码。
双通道 7 跳架构 · 上半 = 破冰模块 DM 主通道 / 下半 = 反向评论模块公开通道 · 共用 ② 三路分析(意向模块)+ ③ 公告板 + ★ 事实手册
详见 src/lib/prompts.ts + src/lib/memory.ts + src/lib/reverseComment.ts + worker/scripts/local_reverse_comment_agent.py
② 三模块各自的内部架构
把 Panel ① 全景图里"分析层之后的部分"放大,三个模块并列展示各自从上游输入到出口落地的运行链。颜色与 Section 0 模块卡对齐:蓝=破冰 / 紫=反评 / 绿=意向。
conversations.stagedm.ice_break.system / nurture / decision production labelqwen3-235b · chatReply / generateColdOpenermessage_queue · pending_approval → 运营审批 → ADB / WDA → 抖音 DMreverse_comment_queue,每 sec_uid 30 天去重local_reverse_comment_agent.py · Langfuse get_prompt comment.reverse-comment-system-py-single<<unhookable>> 一票否决 / <<retry>> 错称呼即重写reverse_comment_queue.status = postedanalyze.comments.system production labeldeepseek-v4-flash · 输出 type / specificity / freshness / category 四轴 JSON每列 6 步同形结构(触发 → 取 prompt → 装配 → LLM → 自检 → 出口),但实现栈各自一套——同形不同实现是这套架构能各自演进又不互相牵扯的关键。
③ 一条破冰穿过对话策略链路的 7 步
触发
Vercel Cron 拉一批新评论,按账号分批入队。
/api/cron/analyze意图打分
analyzeComments 调 analyze.intent.system 给买家意图打分。
deepseek-v4-flash路由
命中高意向阈值 → 进 generateColdOpener;否则丢回评论池。
stage 判定取模板
Langfuse 拉 dm.ice_break.system 的 production label。
prompt @v30装 slot
persona + brand_profile + 客户 memory + 视频上下文注入。
slot inject生成
chatReply 按"对话路"调风格化模型出文案。
qwen3-235b净化 + 安检
sanitizeReply + 后置 ban check,命中即拦下不发;过关写 message_queue。
post-process反评模块 · 7 步类比
候选挑选
pickCandidates 在同行视频评论池里过滤同行 / 家电 / 硬装。
pickCandidatescooldown
每 sec_uid 30 天去重,写 reverse_comment_queue。
装 skeleton
Python agent 拉 Langfuse,注入 skeleton + source_comment + video_title + nickname。
py-singleLLM 生成
Python agent 调 LLM 出 4 步话术(1 段连贯、禁止换行)。
LLM (cfg)骨架自检
命中 <<unhookable>> 拒;命中 <<retry>> 重写。
WDA 留评
iPhone WebDriverAgent 在同行视频下串行留评。
worker WDA回写状态
reverse_comment_queue.status = posted,留评 URL 待对方私信回流。
意向模块 · 5 步类比
拉评论池
Cron 抓 douyin comments 最近一批,待打分。
comments fetch正则预筛
peer-filter + off-topic 正则先过一遍,省 token。
peer-filterLLM 打分
analyzeComments 调 analyze.comments.system。
deepseek-v4-flash四轴合成
deriveIntent() 用 type+specificity+freshness 合 score;off_topic short-circuit 到"无关"。
deriveIntent分流
高意向 → DM 候选池;中意向 → 反评候选池;无关 → 丢。
dispatch④ Prompt 内部解剖:6 段骨架 + 8 个 slot 注入 + 1 道外层安检
装配时注入的 slot
{{persona}} — 当前账号绑定的销售身份卡{{brandConfig}} — 板材 / 五金 / 品牌矩阵(PMM 维护){{pricingTable}} — 锚价 / 活动价 / 配置系数表{{trustClaims}} · v26 — ENF / 假一赔三 / 品牌三选一{{showroomHooks}} · v26 — 样板房 3 条钩子{{customerMemory}} — 跨会话客户画像(自然语言短句){{videoContext}} — 这条视频的标题 / 评论原文{{conversationHistory}} — 当前会话历史(按 stage 截断)反评模块 · 4 步话术结构 + 2 类自检
<<retry>>。反评装配时注入的 slot
{{skeleton}} — 本次必须采用的话术骨架{{source_comment}} — 对方此前的公开评论(理解意图){{video_title}} — 对方此条视频标题{{author_nickname}} — 对方抖音昵称(推断称呼用){{no_title_clause}} — 标题缺失时的兜底子句意向模块 · 四轴 anatomy + short-circuit
deriveIntent() 里直接到 label='无关'——家电 / 数码 / 促销询券防漏网。意向 prompt 的 slot 和输出
{{batchSize}} — 本批评论条数{{commentList}} — 格式化后的评论列表(带 video 上下文)type_reason / category_reason 推理字段deriveIntent() 用前 3 轴合成 score;公式留代码层,PM 改不到peer-filter.ts 给反评 + 破冰共用,避免重复维护⑤ 模型路由:对话路与分析路各走各的
对话路 · qwen3-235b
LLM_CHAT_MODEL 单独覆盖。generateColdOpener→dm.ice_break.systemchatReply(stage=ice_break)→dm.ice_break.systemchatReply(stage=nurture)→dm.nurture.systemchatReply(stage=decision)→dm.decision.system
分析路 · deepseek-v4-flash
LLM_ANALYSIS_MODEL 单独覆盖。analyzeComments→analyze.intent.systemdetectDecisionSignals→analyze.signals.systemclassifyDecorationStage→analyze.stage.system
LLM_MODEL 仍可一键回滚到统一模型,作为兜底。⑥ 三条不变的规则
- 规则一 · 双层架构:prompt 写规则,brand_profile 写数据。PMM 改一次 brand_profile,所有 stage 的生成瞬间生效,不用动代码。
- 规则二 · staging → production label:新版本先 promote staging,跑 audit-data + few-shot 回归通过,才 promote production。线上失控时切回上一版 label,不走代码 revert。
- 规则三 · 每类翻车留一道永久防护:v10 智能称呼 · v14 self_check · v16 后置 ban check · v22 报价放行 · v23 softening。同一种坑不踩第二次。
演进路上踩过的坑 & 现在要管的风险
破冰模块从 v10 一路打补丁到 v30(当前生产),每出一类翻车就在 prompt 里加一段永久防护;反评模块从 v1 内容创作者视角换到 v4 销售路线后持续迭代到 v14;意向模块从 v1 单值 intent 拆轴到 v10 四轴。现在三个骨架都稳了,下面要管的不再是"AI 会不会说错话",而是数据治理、法务边界、灰度纪律——下面 6 个风险三个模块都受影响。
A · 三模块各自的特定风险
brand_profile 冷启动
v26 新增 4 段 slot、v30 又把价格口径切成每平方米 284 一平(依赖 budgetTable),但线上 brand_profile 字段仍偏空。PMM 没一次性填齐就 promote,破冰文案会大面积命中 fallback。
skeleton 池窄 + 趋同
当前只有 1 套 skeleton(销售路线),所有视频品类共用。骨架太窄会导致留评趋同,被同行运营识破"批量发评论的脚本"。本周要扩到 8 套并按 video tag 路由。
off_topic 词表盲点
"618 / 双 11 / 蹲一波 / 满减券 / 家电品牌 / 自建房" 词表是手写维护。新型促销 / 新品牌冒出来时漏过,下游 DM 和反评候选池会被噪音塞爆。
B · 三模块共通的全局风险
换模型的协议字节
三模块都依赖 Langfuse + LLM。破冰下游有 sanitizeReply + ban check 兜底;反评 / 意向没有同等强度防护。任何换模型动作都要先做协议字节回归再放灰度。
法务边界
"假一赔三"等承诺类、"全国唯一"等绝对化措辞,三模块的 prompt 都涉及。法务过一遍后统一进全局禁词表,比每个模块各自维护可靠。
版本回滚 / label 漂移
三模块共用 Langfuse staging → production label。promote 前 audit-data 必须 pass;线上失控时回退 label 而不是改代码。改意向模块还要额外 dry-run 看分布。
三模块下一步
三个模块全部在线上最新版(破冰 v30 / 反评 v14 / 意向 v10)。下一步是把刚 promote 的版本观察稳,再各自推下一轮——破冰跑 v30 价格口径灰度、反评扩 skeleton 池、意向上多模态。任一模块改动都先 staging → audit-data → 灰度。
v30 价格口径灰度 → v31
- 已落地 · v26(2026-05-29 13:03 promote)后五天四轮迭代:v26 直辖市 IP 脱敏修正 → v27/v28 prompt-health 收 5 条告警 + 3 道 systemic 守卫 → v29 §(B) 面积+总价强制走预算三档 → v30 价格口径投影→每平方米 284 一平(全面禁 投影 / 568 旧价)。
- 本周 · v30 vs v25 灰度对比:v25 末轮基线 95.6%(583/610),盯主指标加微率、次指标 DM 触线率 + 报价口径一致性(不再出现投影/568)。
- 下周 · 数据稳的话全量稳定 v30;不稳则 label 回切上一版保业务,问题在 staging 上修。
- 规模化 · 多品牌复用:只换 brand_profile,prompt 骨架不动;v31 准备把 nurture / decision 两段也按 v26 同款 slot 重构。
v14 稳态 → 扩 skeleton 池
- 今日 · v14 当前生产(最近一次 promote 2026-05-18):单 skeleton + 4 步话术 +
<<unhookable>>/<<retry>>自检全跑通;7d 273 次调用。 - 本周 · skeleton 池扩到 8 套:按视频品类(柜体 / 硬装 / 软装 / 收纳 / 户型槽点 / …)各自一套切入路径,picker 按 video tag 路由。
- 下周 · 留评回流率指标接 Langfuse trace:把"留评 → 对方私信回复"配对,看哪类 skeleton 钩对方私信效率最高。
- 规模化 · 多账号 Python agent 并发跑,
reverse_comment_queue加 per-account 配额隔离。
v10 稳态 → v11 多模态
- 今日 · v10 当前生产(最近 promote 2026-05-28):type / specificity / freshness / category 四轴 + reasons;off_topic short-circuit 拦家电 / 数码 / 促销询券;7d 2,373 次调用(量最大)。
- 本周 · off_topic 词表回归:补"家电 / 硬装 / 促销 / AI 指令"4 大类正则盲点(peer-filter 共享给反评 + 破冰)。
- 下周 · v11 草案:加 product_category 字段(柜体 / 硬装 / 软装 / 家电预留 / 重级土建),让下游 pickCandidates 走分类 filter 而不是堆正则。
- 规模化 · 多模态升级:把视频封面 / 视频标题一起喂给模型,处理短评论"价格?"这类无文本上下文的客户。
附录:如果同事追问细节
这部分可以不主动讲,但可以用来回答深一层的问题。
A · 三模块各自的版本演进
v10 → v30 版本演进
v10+ 智能称呼 3 层 · v14 §(p) self_check · v16 后置 ban check · v22+ §(H) 报价类放行 · v23 §softening · v25 末轮 95.6%(583/610)· v26 §(B) 预算 / §(T) 信任 / §(C) 收口三段 + 4 slot + 直辖市 IP 脱敏 · v27/28 prompt-health 收告警 + 3 道 systemic 守卫 · v29 §(B) 面积+总价强制走预算三档 · v30 价格口径投影→每平方米 284 一平(禁投影/568)。Langfuse 上累计 30 个版本。
v1 → v14 视角换血 + 持续打磨
v1-v3 内容创作者视角(留评像水军、钩不到 DM)· v4 切销售视角(2026-05-13 与夏夏 Lark 对齐)· v5-v14 打磨称呼锁、unhookable 触发面、私信钩子句式 · TS multi-skeleton 路径下线,统一走 Python single-skeleton;fallback 字字对应 PYTHON_REVERSE_COMMENT_FALLBACK。Langfuse 上累计 14 个版本。
v1 → v10 四轴稳定
v1 只输出 intent 单值,下游难以 short-circuit;v2 拆成 type / specificity / freshness / category 四轴 + keywords + reasons,v3-v10 持续在 off_topic 词表、reasons 句式、batchSize 上打磨。Langfuse 上累计 10 个版本。改动直接影响破冰和反评的候选池分布,risk HIGH。
B · 三模块共通的工程约定
chat / analysis / agent 三栈
破冰:chatReply 走 qwen3-235b;意向:analyzeComments 走 deepseek-v4-flash;反评:Python agent 单独配。全局 LLM_MODEL 仍可一键回滚到统一模型。
自然语言而非 KV
跨会话 memory 合成一句自然语言:"这位客户在杭州、110㎡、关心环保",写进破冰 system prompt。反评不读 memory(公开通道无配对客户);意向只看当条评论上下文。
label 切回上一版
Langfuse 把 production label 切回上一版即时回退,不走代码 revert——避免 prompt 与 fallback 文件不一致。三模块同一套规则。
C · 速记 6 条
- 速记 1(全局):截至 2026-06-01 三模块都在线上最新版——破冰
v30/ 反评v14/ 意向v10;共用一份事实手册 + 同一份意向打分上游。 - 速记 2(破冰):v25 末轮 95.6%(583/610);v26 新增 §(B) 预算 / §(T) 信任 / §(C) 收口三段 + 4 slot,5/29→6/1 又迭代到 v30(价格口径投影→每平方米 284 一平,禁投影/568)。
- 速记 3(破冰):每一类翻车都留一道永久防护——v10 / v14 / v16 / v22 / v23 / v25 / v26 / v29 / v30 一路打到现在;Langfuse 上 30 个版本。
- 速记 4(反评):v4 切销售视角后持续打磨到 v14;TS multi-skeleton 已下线,统一走 Python single-skeleton +
<<unhookable>>/<<retry>>自检。 - 速记 5(意向):v10 四轴 type / specificity / freshness / category + off_topic short-circuit;7d 调用 2,373 次 = 全模块最忙的上游;改动 risk HIGH,必 dry-run ≥15 条历史评论。
- 速记 6(共通):所有版本走 staging → production label;线上失控回退 label 而不是改代码。