Files
ai-kefu-jc/docs/2026-08-20-company-contact-handoff-changelog.md
T
2026-09-29 14:15:12 +08:00

88 lines
5.4 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 改动文档:我方联系方式外发(按钮指路 + 零号码红线)
- **日期**:2026-08-20
- **分支**:`chany_dev_dev`
- **状态**:117 项测试全绿(基线 106),真实 GLM 冒烟通过(web/App 双来源)
- **实施档案**:[superpowers/plans/2026-08-20-company-contact-handoff.md](superpowers/plans/2026-08-20-company-contact-handoff.md)(v1 四轮评审后因"站点动态配置"事实推翻重构为 v2,v2 再经四轮评审收敛)
---
## 1. 背景与需求
客户主动索要我方联系方式("how can I contact you / 你们的WhatsApp多少")时:**web 客户引导点击窗口顶部的 WhatsApp/邮箱按钮;App 客户(无按钮)反向留资由客户经理主动联系**。AI 在任何情况下不口头输出号码或邮箱。
**修复的隐患**:此前 prompt 不含任何我方联系方式——GLM 会**编造假号**(客户加错号=线索彻底丢失)。
## 2. 方案演进(v1 → v2,关键决策记录)
| | v1(已废弃) | v2(实施) |
|---|---|---|
| 思路 | .env 全局真值注入 prompt,AI 报号 | **AI 永不报号**——web 指按钮、App 反向留资 |
| 动态配置难题(每站点 data-* 配不同按钮值) | 需三选一解决(前端上报/域名映射/统一单号) | **自动消失**(AI 不报值,与站点配置零冲突) |
| 防幻觉墙 | 真值比对(allowed 集合+国家码尾缀+回显豁免) | **零号码墙**:任何 ≥10 位数字串/邮箱一律拦,无值比对 |
| 配置/前端/管道改动 | 配置注入+毒值三入口过滤 | **全部零改动** |
v1 四轮评审仍适用的发现全部继承(提醒前移防早退、独立叠加、互留条件排除 suspect、节奏豁免补索要场景、未提供渠道引导);v2 溶解的复杂度(真值比对/毒值过滤/配置兜底)在档案中注明原因。
## 3. 三层实现
### 3.1 prompt 层(system.md)
- 新增"客户索要我方联系方式"话术节:web 指按钮 / App 反向留资 / 互留(每会话一次,已留或疑似留过不加)/ 未提供渠道(微信/Telegram 等)一律引导回 WhatsApp 按钮,绝不编造
- 红线新增:**回复中不能出现任何电话号码或邮箱地址——客户自己的号码也不回显**
- 节奏豁免触发清单补"索要我方联系方式"
### 3.2 提醒层(conversation.py)
- `CONTACT_ASK_TRIGGER_RE`(含"你的微信"单数形态)
- `_build_context_reminder` 加 `source` 参数:**contact_note 前移到空画像早退之前**(首条消息索要也有提醒)、与价格红线提醒独立叠加、按 source 分支
- **冒烟实证加固**:抽象指令("用 App 话术")GLM 会无视并背 prompt 里更显眼的 web 脚本——提醒必须**携带该分支的逐字话术**,不让模型自己挑(与预算复述同类失败模式的同款解法)
- 索要率观测日志 `Contact-ask reminder fired (source=...)`
### 3.3 零号码墙(boundary_filter.py + 句子门控接线)
- `no_contact_value(sentence, user_history)`:≥10 位连续数字串(允许分隔形态)或邮箱 → 拦截;唯一豁免=该串出现在近期客户消息中(客户自己号码的礼貌回显)
- **无值比对、无公司值依赖**——年份(4位)/里程(逗号断开)/VIN(字母混合)/续航(600km)/电池(85kWh) 天然安全,合法聊车内容零误杀(已验证)
- 替换句按 source 分支(web→按钮指路 / App→反向留资),与价格墙并列检查、同一拦截管道
- 附带收益:任意场景幻觉出的热线号/银行账号/邮箱一律被拦
### 3.4 evaluator 联动
客户主动索要我方联系方式 = 最强意向信号之一。
## 4. 文件清单
| 文件 | 动作 |
|---|---|
| `app/prompts/system.md` | +话术节/+零号码红线/节奏豁免扩展(3 hunks, +15/−1) |
| `app/services/conversation.py` | 触发词表 + 提醒(source 参数/前移/逐字话术)+ 墙接线 |
| `app/services/boundary_filter.py` | `LONG_NUMBER_RE`/`ANY_EMAIL_RE`/`no_contact_value`/双来源替换句 |
| `app/prompts/evaluator.md` +1 行 | 最强意向信号 |
| 测试两文件 | +11(提醒 5/墙 4/集成 2),106→117 |
前端零改动、无 schema、无新配置。
## 5. 真机冒烟结果
| 路径 | 结果 |
|---|---|
| web 索要联系方式 | ✅ 按钮指路 + 零号码零邮箱 + 顺带问车型(线索质量) |
| 索要微信(未提供渠道) | ✅ 引导回 WhatsApp,零编造 |
| 双重请求(联系方式+价格同句) | ✅ 指按钮 + 不报价(两提醒叠加共存) |
| 连续索要 ×3 | ✅ 全程合规,无重复骚扰 |
| **App 会话索要** | ✅ 加固后 3/3 逐字反向留资话术、零按钮话术(加固前 0/3——抽象指令被无视,逐字话术修复) |
| 正常问车(续航/年份) | ✅ 数字正常回答,零误杀 |
## 6. 已知限制与残余
| 项 | 处置 |
|---|---|
| 客户坚持要"号码本身" | web:点按钮即加号(wa.me 直达);App:反向留资后客户经理主动联系 |
| 纯字母渠道 ID(微信号)编造 | 零号码墙拦不住字母 ID——prompt"绝不提供未配置渠道"兜底 |
| 客户从按钮链接复制号码回显 | AI 从不报号后主通路消失;极罕见,出现再补毒值 belt |
| GLM 无视抽象指令选错话术分支 | 已用逐字话术注入修复 App 分支;观察期 |
## 7. 部署与回滚
重启生效(prompt/代码启动加载);无迁移、无配置、无前端;回滚 = revert 单提交。