Files
ai-kefu-jc/docs/2026-08-19-ai-role-boundary-changelog.md
T
2026-09-29 14:15:12 +08:00

9.7 KiB
Raw Blame History

改动文档:AI 职能边界(价格红线 + 转介机制)

  • 日期:2026-08-18 ~ 2026-08-19
  • 分支:chany_dev_dev,提交 3028685(三层防线)+ 9433f96(句子粒度门控)
  • 状态:106 项测试全绿(基线 77),本地真实 GLM 冒烟 7 路径通过,WS 探针实证打字机恢复
  • 实施档案:superpowers/plans/2026-08-18-ai-role-boundary.md(两轮对抗评审 + 13.1-13.7 全过程)

1. 背景与解决的问题

定位反转:改造前 system.md 明文要求 AI 报价("宁可给一个不完美的价格估计",且报价是好回复示例)——用户实测 AI 张口就是 "$25k"。改造后 AI 定位为:

信息型助手 + 线索收集器——介绍车、挖意向、收联系方式。不承担销售职能: 不做任何承诺(价格/时间/库存)、不说绝对化的话、不代表公司做决定。

价格/优惠/交付时效/实质请求一律迂回引导留资,由客户经理承接——与询盘邮件体系闭环(AI 收集意向+联系方式 → 邮件 → 客户经理报价/安排)。

2. 核心架构:三层防线(冒烟实测逐层验证)

客户消息(问价/磨价/问时效/要安排/报预算)
  │
  ├─ 第1层 prompt:system.md 职能边界章节
  │    三类请求处理(信息直答 / 价格时效迂回 / 实质转介)
  │    预算路径(推荐车型但零数字复现→反问意向→引导留资)
  │    节奏豁免(价格红线立即生效;零上下文询价按钮首触先挖一轮需求)
  │    红线五条(无价格数字/无占位符/无交付时间/无承诺/安排主体是客户经理)
  │    追问坚持策略 + 六种磨法应对手册(态度软立场硬)
  │
  ├─ 第2层 提醒:当轮红线注入(BOUNDARY_TRIGGER_RE)
  │    价格/时效/安排词 + 施压话术(roughly/说个大概/求你了——磨价轮不裸奔)
  │    预算路由(BUDGET_TRIGGER_RE → 推荐+反问 playbook,不一刀切要号)
  │    前置到空画像早退之前(Get Quotation 首条消息即有防护)
  │    与 D6 联动(已留资→"经理会发给你",禁止再索要)
  │
  └─ 第3层 过滤墙:句子粒度门控流式(确定性保证)
       token 攒到句子边界 → 逐句检测价格形态
       ├─ 干净句子 → 立即流出(打字机效果保留,WS 探针实证渐进到达)
       └─ 违规句子 → 一个字不流:掐断生成(省token)、接过渡话术收尾
            (有干净前缀→自然转折"Actually, for the exact price…";
             无前缀→整段标准迂回话术;已留资→不重复要号变体)

为什么三层:GLM 有不守 prompt 的前科(本项目已实测两次),价格又是最强诱导——冒烟数据证明单靠第 1+2 层守不住(预算复述 6/6 全破、压力轮 1/3 报出真实价格),按方案预设的 >10% 破防率阈值激活第 3 层;第 3 层最初为整段缓冲(牺牲打字机),后升级为句子门控(两全)。

3. 文件清单

新增

文件 内容
app/services/boundary_filter.py 价格形态检测($/货币单位/k形式/动词邻接/交付时间/预算复述/金融裸数),白名单排除(年份/车型编号L7/里程30k km/3万公里/质保期/kWh);无损句子切分(标点边界/小数保护/CJK免空格);迂回话术与过渡话术(中英路由/已留资变体/轮换)
scripts/breach_rate.py 破防率观测(只读,锚定式匹配)——改造前基线 18% 存档于 2026-08-18-breach-baseline.txt
tests/test_boundary_filter.py 17 项单测(五模式命中/白名单/切分/话术路由)
docs/superpowers/plans/2026-08-18-ai-role-boundary.md 完整实施档案(含两轮评审 12 条 + 最终评审 8 条发现的处置)

修改

文件 改动
app/prompts/system.md 插入职能边界章节(+58行,位于语言规则后最高优先级);删除/反转 9 处旧价格规则("宁可给价格估计"规则、3 个含价好示例、"报价范围"要求、推进成交定义、3轮节奏两处加豁免);价值交换章节并入职能边界;术语统一"客户经理/manager"
app/prompts/evaluator.md 问价/优惠/运费/试驾 = 意向积极信号(标签更准)
app/services/conversation.py BOUNDARY_TRIGGER_RE/BUDGET_TRIGGER_RE 触发词表;_build_context_reminder 重构(边界检查前置到空画像早退前 + 预算路由 + D6 联动分支);流式区重构为句子门控(缓冲按句→判定→流出/拦截);拦截记 Boundary filter replaced warning
tests/test_lead_email_trigger.py +10 项(边界提醒 8 例 + 流式门控集成 2 例)

测试 77 → 106;前端零改动(事件协议不变);无 schema 变更;邮件体系零影响。

4. 行为对照

场景 改前 改后
"Tang 多少钱 / 有优惠吗" 直接报价 "$25k 起步" 迂回:先问意向车型,同回复引导留资,零数字
"运费/关税多少" 视作报价的一部分回答 同上迂回
"多久能到货" 给时间估计 一律不给时间,引导留资
"我预算2万有什么推荐" 报价推荐 推荐车型但零数字复现(不说"2万/20K")→ 反问意向 → 引导留资
"just tell me roughly"(磨价) 磨两下就报区间 坚持:换理由不重复原话→第三次推 WhatsApp 按钮;过滤器兜底
"能约试驾吗 / 帮我留一台" 自行应承 转介:"对接客户经理安排,留个联系方式"
"Get Quotation" 快捷按钮首触 立即报价 价格红线立即生效 + 先一轮了解需求再引导留资
已留联系方式后问价 (无此状态) "经理会把报价发你 WhatsApp",不再索要
正常问续航/里程/配置 正常回答 照常回答(30k km / 3万公里 / 85kWh 白名单保护,实测未误杀)
回复呈现 逐 token 打字机 保留:逐句渐进流出(实测首句 t=2.3s,第二句 t=5.5s)

5. 关键决策记录(全部用户拍板存档)

决策 内容
职能定位 需求了解+留资;介绍车、挖意向、收联系方式;不是销售、无承诺权(价格/时间/库存)、无绝对化表述、不代表公司做决定
预算处理 可推荐车型,不复述预算数字(含 20K 等改写形式),反问意向后引导留资
交付时效 一律不直接回答,同样引导留资
询价按钮首触 价格红线立即生效,但先用一轮了解需求再要号(低质量线索 vs 转化节奏的取舍)
方案 B 激活 按预设计划的 >10% 破防率阈值(冒烟 6/6+1/3 击穿)→ 输出过滤上墙
打字机恢复 句子粒度门控方案(用户确认)——干净句子流出、违规句不流,两全

6. 实测驱动的演进链

阶段 发现 处置
冒烟第1轮 预算复述 6/6 全破("budget of 20K")、压力轮 1/3 报真实价、50% 输出"[价格区间]"占位符 prompt 加固(具体替代措辞)
冒烟第2轮(加固后) 依旧 6/6 破——GLM 把复述预算当礼貌确认 方案 B 激活:整段缓冲过滤,违规归零
最终评审 里程误杀(30k km)、裸预算复述漏检(恰是旗舰形态且观测不可见)、已留资重复要号 过滤器收严(F1-F6:白名单/预算模式/金融/质保/联系变体)
用户反馈 打字机效果没了 句子粒度门控(13.7)——渐进流出恢复,红线不降级

7. 部署注意事项 ⚠️

  1. 重启即生效:prompt 在启动时加载、触发词表在代码中——所谓"词表热调"实为重新部署。
  2. 无 schema 变更、邮件体系零影响;询盘邮件正文里的 AI 回复将全是过滤后文本(破防原文只在日志)。
  3. 体验变化预告:回复从逐字打字机变为逐句出现(首句 ~1s,人格回复 1-2 句所以观感接近);AI 从此不报任何价格——提前告知销售团队,报价承接节奏要跟上。
  4. 上线后观测:docker compose logs app | grep "Boundary filter" = 真实破防率(GLM 想报但被墙拦的频率);改造前基线 18% 已存档,以此对比第 1+2 层的自律率。
  5. 触发词调参:漏词案例(新问法/多语言)回流补 BOUNDARY_TRIGGER_RE;误触发低害(多一条提醒)。
  6. 回滚:git revert 9433f96 3028685 两提交即完整回滚。

8. 已知限制与残余(台账)

项 状态
单句回复仍需等该句生成完(~1s)——那句本身可能含价,无更快解 接受(物理约束)
句子切分为启发式(小数已保护;切歪只影响节奏不影响安全) 接受
多语言问价(法/斯瓦希里/阿拉伯语)触发词盲区 第1层全局红线 + 第3层过滤器兜底(价格形态与语言无关)
极端假阳性:"这车跑了两万"(无"公里"后缀的里程表述)会被当价格拦截 罕见,方向安全(多拦不泄露)
破防率脚本与过滤器模式不再严格同步(过滤器更严) 上线后以日志行为准,脚本留作历史基线
过渡话术单一池(不轮换) 观察重复感,需要时扩池

9. 未包含(后续批次)

与之前清单一致:批次 2(widget 会话持久化/前端历史渲染/WS 限流)、批次 3(admin 卡单筛选/UI 留资卡片)、健康轨(超时清理会话、SQLite 备份、删 Redis、ADMIN_PASSWORD、GLM 超时重试)。可基于 Boundary filter 日志做 admin 侧"破防监控面板"(若需要)。