docs: 实施计划评审修正——判定分支重排/两既有测试更新/防自锁四处禁令+提醒句改写/集成正向断言
Co-Authored-By: Claude Code <noreply@anthropic.com>
This commit is contained in:
@@ -48,40 +48,46 @@ def test_reask_wall_channel_precision():
|
|||||||
|
|
||||||
- [ ] **Step 2: 跑红** `python -m pytest tests/test_boundary_filter.py::test_reask_wall_channel_precision -v` → TypeError(asks_contact 不收第二参)
|
- [ ] **Step 2: 跑红** `python -m pytest tests/test_boundary_filter.py::test_reask_wall_channel_precision -v` → TypeError(asks_contact 不收第二参)
|
||||||
|
|
||||||
- [ ] **Step 3: 实现**。boundary_filter.py 把 asks_contact 替换为(保持 REASK_PATTERNS 不动,新增渠道映射层):
|
- [ ] **Step 3: 实现**。boundary_filter.py 把 asks_contact 替换为(保持 REASK_PATTERNS 不动,新增渠道映射层)。
|
||||||
|
⚠️ 分支顺序是评审修正版(plan review Issue 1:初版顺序会让 Step 1 的两条断言必挂——"泛词+仅邮箱"和"精确+泛同句"两个分支被兜底吞掉)。判定顺序固定:①在手精确词→丢;②泛词+有号码渠道→丢;③命中但句中无任何渠道词→保守丢;④其余→放行:
|
||||||
|
|
||||||
```python
|
```python
|
||||||
# 渠道精确化(2026-10-08 spec §4.4): REASK 模式命中后按渠道词分辨——
|
# 渠道精确化(2026-10-08 spec §4.4): REASK 模式命中后按渠道词分辨——
|
||||||
# 索要已在手的渠道才丢,索要缺失渠道放行(双要补邮箱场景);泛渠道词
|
# 索要已在手的渠道才丢,索要缺失渠道放行(双要补邮箱场景);泛渠道词
|
||||||
# (number/phone/contact/电话/联系方式/号码)只要手上有任何号码渠道即丢,
|
# 只要手上有任何号码渠道即丢(宁丢勿放);精确+泛同句共存时按①②自然
|
||||||
# 宁丢勿放防重复索要;精确+泛同句共存时任一命中判丢。
|
# 实现任一命中判丢。中文泛词不用 \b(CJK 无词边界,"电话"前 \b 永不成立)。
|
||||||
_PRECISE_CHANNEL_RE = re.compile(
|
_PRECISE_CHANNEL_RE = re.compile(r"whatsapp|e-?mail|邮箱|微信|wechat", re.I)
|
||||||
r"whatsapp|e-?mail|邮箱|微信|wechat", re.I)
|
_GENERIC_CONTACT_RE = re.compile(r"\b(?:number|phone|contact)\b|电话|联系方式|号码", re.I)
|
||||||
_GENERIC_CONTACT_RE = re.compile(
|
|
||||||
r"(?:^|\b)(?:number|phone|contact|电话|联系方式|号码)", re.I)
|
|
||||||
|
def _precise_channels_in(s: str) -> set:
|
||||||
|
out = set()
|
||||||
|
for m in _PRECISE_CHANNEL_RE.finditer(s):
|
||||||
|
w = m.group(0).lower()
|
||||||
|
out.add("email" if w in ("e-mail", "email", "邮箱")
|
||||||
|
else "wechat" if w in ("微信", "wechat") else "whatsapp")
|
||||||
|
return out
|
||||||
|
|
||||||
|
|
||||||
def asks_contact(sentence: str, confirmed_channels: set | None = None) -> bool:
|
def asks_contact(sentence: str, confirmed_channels: set | None = None) -> bool:
|
||||||
"""输出句是否在索要联系方式(已留资时用于丢弃)。
|
"""输出句是否在索要联系方式(已留资时用于丢弃)。
|
||||||
|
|
||||||
confirmed_channels=None → 原行为(命中即丢,向后兼容);
|
confirmed_channels=None → 原行为(命中即丢,向后兼容);
|
||||||
传入已确认渠道集合(如 {"whatsapp","phone"}) → 渠道精确化。"""
|
传入已确认渠道集合 → 渠道精确化(①②③④判定,见上注释)。"""
|
||||||
s = sentence or ""
|
s = sentence or ""
|
||||||
if confirmed_channels is None:
|
hit = any(p.search(s) for p in REASK_PATTERNS)
|
||||||
return any(p.search(s) for p in REASK_PATTERNS)
|
if confirmed_channels is None or not hit:
|
||||||
if not any(p.search(s) for p in REASK_PATTERNS):
|
return hit
|
||||||
return False
|
has_number = bool(confirmed_channels & {"whatsapp", "phone", "wechat"})
|
||||||
has_number_channel = bool(
|
precise = _precise_channels_in(s)
|
||||||
confirmed_channels & {"whatsapp", "phone", "wechat"})
|
has_generic = bool(_GENERIC_CONTACT_RE.search(s))
|
||||||
for m in _PRECISE_CHANNEL_RE.finditer(s):
|
if precise & confirmed_channels: # ① 句中有在手精确渠道词
|
||||||
w = m.group(0).lower()
|
return True
|
||||||
ch = ("email" if w in ("e-mail", "email", "邮箱")
|
if has_number and has_generic: # ② 泛词 + 手上有号码渠道
|
||||||
else "wechat" if w in ("微信", "wechat") else "whatsapp")
|
return True
|
||||||
if ch not in confirmed_channels:
|
if not precise and not has_generic: # ③ 命中但无渠道词 → 保守丢
|
||||||
return False # 索要缺失的精确渠道 → 放行
|
return True
|
||||||
if has_number_channel and _GENERIC_CONTACT_RE.search(s):
|
return False # ④ 精确词全缺失/泛词但无号码 → 放行
|
||||||
return True # 泛词 + 手上有号码 → 丢
|
|
||||||
return True # 命中但无精确渠道词(纯泛词/其他形态) → 保守丢
|
|
||||||
```
|
```
|
||||||
|
|
||||||
- [ ] **Step 4: 跑绿**(该测试 + 现有全部 REASK 测试不回归)
|
- [ ] **Step 4: 跑绿**(该测试 + 现有全部 REASK 测试不回归)
|
||||||
@@ -98,6 +104,14 @@ if has_contact and asks_contact(sentence, _confirmed_channels):
|
|||||||
elif has_contact and asks_contact(pending, _confirmed_channels):
|
elif has_contact and asks_contact(pending, _confirmed_channels):
|
||||||
```
|
```
|
||||||
|
|
||||||
|
- [ ] **Step 5b: 更新两处被新语义打破的既有测试**(plan review Issue 2):
|
||||||
|
`tests/test_lead_email_trigger.py` 的 `test_reask_wall_drops_ask_sentence_when_contact` 与
|
||||||
|
`test_reask_wall_all_dropped_falls_back_to_closing`(场景=客户留 phone、AI 问
|
||||||
|
"Got your WhatsApp?"、期望丢句)——新语义下 WhatsApp 是缺失渠道 → 放行。
|
||||||
|
改法:测试场景改为 AI 问**已在手的渠道**(如 "Got your phone number?")保持
|
||||||
|
丢句语义;同时各补一条"有 phone 在手问 WhatsApp → 放行并流出"的断言
|
||||||
|
(钉死 spec 未明说的语义决定:号码渠道间互视为可补全)。
|
||||||
|
|
||||||
- [ ] **Step 6: 全量绿 + commit**
|
- [ ] **Step 6: 全量绿 + commit**
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
@@ -212,7 +226,13 @@ def test_contact_completion_note_serial_priority():
|
|||||||
|
|
||||||
- [ ] **Step 5: 接线 _build_context_reminder**(有画像路径 parts 拼接处追加 note;空画像早退路径不注入——没联系方式谈不上补全)+ stream 方法流式前写回计数键
|
- [ ] **Step 5: 接线 _build_context_reminder**(有画像路径 parts 拼接处追加 note;空画像早退路径不注入——没联系方式谈不上补全)+ stream 方法流式前写回计数键
|
||||||
|
|
||||||
- [ ] **Step 6: 集成测试**(spec §6-6 计数持久化)——用同文件现有 manager 流程测试风格构造两轮对话:第一轮后查 DB `raw_info` 含 `_cc_asked`、第二轮 reminder 不再含追问句
|
- [ ] **Step 5b: 改写 conversation.py:646 确认路径提醒句的硬禁令**(plan review Issue 3——防自锁不只 system.md 一处):
|
||||||
|
该句现为"绝对禁止再索要任何联系方式!",与新轻补 note 同轮注入时 GLM 收到
|
||||||
|
自相矛盾指令。改为:"绝对禁止再索要客户**已提供过**的联系方式;缺失渠道
|
||||||
|
仅可按上述轻补指引提一次。" 同步更新 `tests/test_lead_email_trigger.py`
|
||||||
|
中 :356/:475/:881 附近的"绝对禁止再索要"类文案断言。
|
||||||
|
|
||||||
|
- [ ] **Step 6: 集成测试**(spec §6-6 计数持久化)——用同文件现有 manager 流程测试风格(CaptureAI 捕获注入 context)构造两轮对话:**第一轮正向断言**(context 含追问句原文——防"写了计数却没拼进 reminder"的接线失误)+ 第一轮后查 DB `raw_info` 含 `_cc_asked`、第二轮 reminder 不再含追问句
|
||||||
|
|
||||||
- [ ] **Step 7: 全量绿 + commit**
|
- [ ] **Step 7: 全量绿 + commit**
|
||||||
|
|
||||||
@@ -249,7 +269,12 @@ def test_system_md_dual_contact_wording():
|
|||||||
assert "国家代码追问句" in src and "邮箱轻补句" in src
|
assert "国家代码追问句" in src and "邮箱轻补句" in src
|
||||||
```
|
```
|
||||||
|
|
||||||
- [ ] **Step 2: 跑红** → **Step 3: 改 system.md 七处**(话术全文见 spec §4.1;⚠️ 第 6 处"已留资时不用任何索要句"改写是防自锁关键,逐字改为"已留资时不再索要**已在手的渠道**(改确认式);**缺失渠道**可按【联系方式引导策略】轻补一次")→ **Step 4: 跑绿 + 全量绿**(现有 system.md 文案断言若冲突同步更新)
|
- [ ] **Step 2: 跑红** → **Step 3: 改 system.md 七处**(话术全文见 spec §4.1;⚠️ 第 6 处"已留资时不用任何索要句"改写是防自锁关键,逐字改为"已留资时不再索要**已在手的渠道**(改确认式);**缺失渠道**可按【联系方式引导策略】轻补一次")。
|
||||||
|
⚠️ **plan review Issue 3 补充——防自锁是四处不是一处**:除 L7 外,system.md
|
||||||
|
还有三处同款硬禁令必须同步改写(否则更显眼的老禁令抑制新行为):
|
||||||
|
- 红线节(约 :59)"不再三索要已留资客户的联系方式"→ 补"(缺失渠道可轻补一次)"
|
||||||
|
- 系统提醒配合节(约 :201)同款表述同步
|
||||||
|
- 对话流程节(约 :166)"拿到联系方式后…别再提联系方式"→ 补"(缺失渠道轻补一次除外)" → **Step 4: 跑绿 + 全量绿**(现有 system.md 文案断言若冲突同步更新)
|
||||||
|
|
||||||
- [ ] **Step 5: 模板句过墙断言**(spec §6-4,防自锁报警线):
|
- [ ] **Step 5: 模板句过墙断言**(spec §6-4,防自锁报警线):
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user