Co-Authored-By: Claude Code <noreply@anthropic.com>
26 KiB
HESUPIPE 建材 AI 客服 实施计划
For agentic workers: REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (
- [ ]) syntax for tracking.
Goal: 复制 D:\refactor\ai-kefu 汽车AI客服到本项目并完成建材(HESUPIPE 管道外贸)行业定制。
Architecture: 方案A"完整拷贝+定制"——保留参考项目全部架构(FastAPI+SQLite+智谱GLM、WebSocket/REST 双通道、三重输出墙、联系方式管道、邮件+UniService推送、管理后台、170+测试),只定制约15%行业相关内容(4个提示词、多语言正则墙、前端文案、品牌更名)。
Tech Stack: Python 3.13 / FastAPI / SQLAlchemy(async)+aiosqlite / 智谱GLM(glm-4-flash) / 原生HTML-JS-CSS前端 / pytest+pytest-asyncio / Docker+OpenResty
设计文档: docs/superpowers/specs/2026-09-29-building-materials-ai-kefu-design.md(本计划的所有决策依据)
参考项目: D:\refactor\ai-kefu(只读,绝不修改)
重要约束:
- ⚠️ 绝不拷贝参考项目的
.env(含真实密钥)和data/cc_ai_kefu.db(含生产数据) - 开发期
PUSH_ENABLED=false、NOTIFY_EMAIL 用测试邮箱(Task 11 验收通过后才切生产) - 每个任务结束必须
pytest -q全绿后才能 commit
Task 1: 项目拷贝、清理与测试基线
Files:
-
Create: 整个项目骨架(从参考项目拷贝)
-
Delete:
static/blog.html、redis 相关配置 -
Step 1: 拷贝项目(排除密钥/数据/缓存)
cd /d/refactor
MSYS_NO_PATHCONV=1 robocopy "D:\\refactor\\ai-kefu" "D:\\refactor\\ai-kefu-jc" /E \
/XD .git data __pycache__ .pytest_cache .ruff_cache .playwright-mcp .superpowers .vscode \
/XF .env
⚠️ Git Bash 下 MSYS 会把 /E /XD 等开关当路径转换导致 robocopy 报"无效参数",
必须加 MSYS_NO_PATHCONV=1 前缀(实测验证;替代写法是 //E //XD //XF 双斜杠)。
robocopy 返回码 0-7 都算成功(1=有文件拷贝),≥8 才是失败。
docs/superpowers/ 下会合入参考项目的汽车 specs/plans 归档,与本项目的建材设计文档共存,无冲突(文件名不同)。
git 仓库说明:本项目在设计阶段已 git init 并有 3 个 docs commit 在案;
robocopy 的 /XD .git 只排除源目录的 .git,不影响目标已有仓库。Step 6 前用
git rev-parse --is-inside-work-tree 确认输出 true 即可(若在全新环境重跑本计划则先 git init)。
- Step 2: 验证拷贝结果
cd /d/refactor/ai-kefu-jc && ls app/ static/ tests/ scripts/
# 预期:四个目录都在;确认不存在 .env 和 data/cc_ai_kefu.db
test ! -f .env && echo OK-no-env
mkdir -p data
- Step 3: 清理无用件
rm static/blog.html
移除 redis 三处:
requirements.txt删除redis>=5.0.0行docker-compose.yml删除整个 redis service 块(cc-ai-kefu-redis).env.example删除REDIS_URL/REDIS_PASSWORD行及注释
- Step 4: 安装依赖并建 .env 占位
pip install -r requirements.txt -r requirements-dev.txt
cp .env.example .env
.env 中 ZHIPU_API_KEY 先留占位(跑测试不需真实 Key,LLM 全 mock)。
- Step 5: 基线测试——未改任何代码前必须全绿
python -m pytest -q
预期:170+ passed(参考项目全绿,拷贝后应同样全绿)。若有 Windows 环境性失败,先修复环境再继续(参考项目 conftest.py 头部有 Windows aiosqlite 清理说明)。
- Step 6: Commit
git add -A && git commit -m "chore: 从汽车AI客服项目拷贝骨架并清理(blog页/redis)"
Task 2: 公司事实卡 company_facts.md
Files:
-
Modify:
app/prompts/company_facts.md(整体重写) -
Test:
tests/test_company_facts.py(更新断言) -
Step 1: 抓取官网资料
用 WebFetch 依次抓取(提取硬事实,忽略模板化文案):
-
https://hesupipe.com/(已抓取过:公司概况/十大产品线/联系方式) -
https://hesupipe.com/about-us/(或等价关于页) -
产品分类页(HDPE/PVC/PPR 等主要品类页,取规格范围)
-
https://hesupipe.com/certificates/(认证清单) -
https://hesupipe.com/sales-network/(销售网络/出口国家) -
新闻页 1-2 篇真实项目案例(如智利农业供水管项目)
-
Step 2: 重写事实卡
保留参考项目事实卡的结构框架和使用规则段(防编造的"统一兜底/不扩展"原则原样保留),替换内容段。结构:
# HESUPIPE 公司事实卡
## 公司概况
(1998年成立/2007年起出口/河南郑州/高新技术企业——只写官网可验证的)
## 产品线总表
(HDPE管道及管件/HDPE波纹管/PVC管道及管件/PVC电工套管/PPR管道/球墨铸铁管/法兰阀门/HDPE渔网箱/门窗类——每类一行主要规格范围,如 DN20-DN1200)
## 应用领域
(市政给水/燃气油气/排水排污/农业灌溉/电气保护/疏浚/海水养殖)
## 认证
(证书页实际列出的,逐条;没有就整节省略,不编)
## 销售网络与出口市场
(官网实际提及的国家/地区)
## 使用规则(原样保留参考项目的兜底原则)
(未列出的一律说"转客户经理确认";禁止推测/扩展/编造)
红线自查:不含价格、交期、MOQ、产能数字;不收录"world-class"类模板化空话。
- Step 3: 更新 test_company_facts.py 断言
改为断言建材关键词(如 HESUPIPE、HDPE 或实际产品词)存在、汽车词(BYD/Hesu Auto/vehicle)不存在。
- Step 4: 跑测试
python -m pytest tests/test_company_facts.py -q
预期:PASS
- Step 5: Commit
git add -A && git commit -m "feat: HESUPIPE 公司事实卡(官网硬事实+防编造规则)"
⚠️ 审核关卡(设计文档§4.2):事实卡完成后请需求方业务侧过目确认后方可上线(可异步,不阻塞后续任务)。
Task 3: 系统提示词 system.md 重写
Files:
-
Modify:
app/prompts/system.md(整篇重写,框架保留) -
Step 1: 重写 system.md
保留参考项目的六段结构,逐段建材化:
- 语言规则(最高优先级):保留"客户用什么语言就用什么语言回复,默认英语";新增:拒绝价格/交期/MOQ/样品费等实质问题时,回复中必须包含固定英文短句
Please leave your contact and our manager will send the full quotation.(保证输出墙正则可靠命中) - 职能边界:AI 只做需求了解+留资;价格/交期/MOQ/装柜方案/样品费/认证清单/库存→转客户经理;问实质问题时若已知意向品类:"确认品类+引导留资"一气呵成
- 红线:不出现价格数字(含复述客户预算);不输出电话/邮箱;不再三索要已留资客户的联系方式
- 说话风格:外贸销售式简短口语;时效承诺用 "reply within 12 hours"(不提中国作息)
- 对话推进:预算路径改为
"Which application? Water supply, gas, drainage or irrigation?";规格追问(口径/压力/标准);围绕已说品类推进 - 好差示例:6-8 组管道场景(例:客户说 "PE100 water pipe DN110",差:泛问 what do you need;好:确认 SDR11/SDR17? + 询问工程量;中文话术示例同步改管道语境)
-
Step 2: 自查清单
-
所有汽车词(car/vehicle/BYD/Toyota/test drive/提车/试驾/续航)已清零:
grep -in "car\b\|vehicle\|byd\|toyota\|test drive\|试驾\|提车\|续航" app/prompts/system.md预期无输出 -
红线覆盖:MOQ、lead time、container loading、sample fee、certificate、price range
-
固定英文拒绝短句原样出现(与 boundary_filter 的 DEFLECTIONS 措辞协调但不冲突——prompt 是"含义",墙是"兜底")
-
Step 3: 跑全量测试(system.md 变更影响的测试)
python -m pytest -q
预期:PASS(若有断言 system.md 内容的测试,同步更新)
- Step 4: Commit
git add -A && git commit -m "feat: 系统提示词建材化(管道外贸人设+多语言拒绝短句)"
Task 4: 提取与评估提示词(extractor.md / evaluator.md)
Files:
-
Modify:
app/prompts/extractor.md、app/prompts/evaluator.md -
Step 1: 重写 extractor.md 字段定义
中文键画像字段改建材语义(设计文档§4.3):
-
意向品类(HDPE给水管/PVC排水管/PPR…) -
规格要求:自由文本保留客户原话(如 "DN110 PE100 SDR11"),明确指示不拆分不过度结构化 -
标准要求:单独一列(ISO4427/ASTM/EN/SCH 系列,客户提到才记) -
采购数量、用途(给水/燃气/排污/灌溉/…)、项目类型、目标国家、预算提及、联系方式字段原样保留参考项目机制 -
Step 2: 重写 evaluator.md 评估语义
三级保留;示例改管道采购:明确品类+规格+数量=interested;仅泛泛浏览=pending;明确无采购计划=not_interested。
- Step 3: 新增 extractor 字段静态断言测试(spec §9.1 第4条落地;严格 TDD 可提前到 Step 1 之前先写先跑红)
tests/test_company_facts.py 风格,新建断言:extractor 提示词加载后包含
意向品类、规格要求、标准要求 字段定义,且不含 车型/意向品牌 汽车字段。
- Step 4: 跑全量测试并 Commit
python -m pytest -q && git add -A && git commit -m "feat: 提取/评估提示词建材化(规格自由文本+标准单列)"
Task 5: 多语言输出墙 boundary_filter.py(TDD 核心)
Files:
-
Modify:
app/services/boundary_filter.py -
Test:
tests/test_boundary_filter.py -
Step 1: 先写失败的多语言墙测试
在 tests/test_boundary_filter.py 追加(沿用该文件现有参数化风格):
# ---- 多语言价格墙(建材市场扩充): 必须拦截 ----
MULTILINGUAL_PRICE_HITS = [
"El precio es 500 dólares", # 西语 词前置
"Costo por tonelada 320", # 西语
"O preço é 1200 reais", # 葡语(巴西)
"Цена 500 за тонну", # 俄语
"Стоимость 800 долларов", # 俄语
"السعر 500 دولار", # 阿语
"€500 per ton", # 欧元符号
"£420 per container", # 英镑符号
"500 dólares", # 数字+货币词后缀
"Delivery in 15 días", # 西语时间承诺
"Срок 2 недели", # 俄语时间承诺
]
# ---- 建材规格形态: 不得误杀 ----
SPEC_NON_HITS = [
"DN800 double wall corrugated pipe",
"PN16 pressure rating",
"SDR11 and SDR17 both available",
"PE100 material",
"600mm diameter",
"SCH40 and SCH80",
"3/4 inch and 2 inch sizes",
"ISO4427 certified",
"20ft container load", "40ft HQ",
"5.8m and 11.8m lengths",
"PE80 PE100 grades",
# Task 3 质量审查发现: customs 是 custo 超集,高频外贸词,不得误杀
"customs paperwork for 20ft containers",
"HS code 3917 for customs clearance",
]
断言:前者每个 violates_boundary(s) 为 True;后者每个为 False。
- Step 2: 跑测试确认失败
python -m pytest tests/test_boundary_filter.py -q
预期:多语言 HITS 用例 FAIL(现有正则拦不住)
- Step 3: 扩充 PRICE_PATTERNS
在 PRICE_PATTERNS 列表追加(保持参考项目"注释说明设计意图"的风格):
# ---- 多语言墙(建材市场: 欧/英/南美/俄语区/中东) ----
# 货币符号: €/£ 参考项目只有 $
re.compile(r"[€£]\s?\d"),
# 价格名词前置(西/葡/俄/阿): 词后 0-20 非数字字符内出现数字
# ⚠️ 拉丁词必须加 \b 词边界——custo 是英文 customs 的子串,外贸高频
# "customs paperwork for 20ft" 会被误杀(Task 3 质量审查发现)
re.compile(r"\b(?:precio|costo|custo|preço|цена|стоимость|سعر|ثمن)\b[^\d\n]{0,20}\d", re.I),
# 货币名词后置(数字+货币词)
re.compile(r"\d[\d,.]*\s*(?:d[óo]lares?|euros?\b|рублей|руб\.?)", re.I),
# 多语言时间承诺(与英文 days/weeks 组同构)
# ⚠️ 不收 horas/hours/小时——system.md 的 "reply within 12 hours" 依赖此豁免
re.compile(r"\d+\s*[- ]?(?:d[ií]as?|semanas?|дн(?:ей|я)|недел[ьи]|أيام)\b"),
同时审查现有汽车特定排除项:
-
\d[\d,.]*\s*(usd|美元|块钱|万块?(?!\s*(公里|km)))的公里|km排除 → 建材语境已无里程语义,但保留无害;确认不误杀建材形态 -
(两|三|四|五|六|七|八|九|十)\s*万(?!\s*(公里|km))保留(中文预算) -
时间承诺
\d+\s*[- ]?(day|week|month)s?\b保留(英文交期承诺) -
Step 4: 跑测试至全绿
python -m pytest tests/test_boundary_filter.py -q
预期:PASS(含原有全部用例不回归)
- Step 5: 迂回话术建材化 + ES 话术池(spec §6 第3层)
- 行业残留清零(用户可见输出,实测在参考项目 L54/L57):
DEFLECTIONS_EN_CONTACT的 "Anything else about the cars?" → "...about pipes?"DEFLECTIONS_ZH_CONTACT的 "还想了解什么车?" → "还想了解什么管道产品?"- 全文件扫一遍 DEFLECTIONS/PIVOTS/NO_CONTACT 各池,确认无其他汽车措辞
- 新增 ES 话术池(南美第一大流量,spec §6.3):
- 新增
DEFLECTIONS_ES、DEFLECTIONS_ES_CONTACT、PIVOTS_ES、PIVOTS_ES_CONTACT(西语版话术,如 "El precio exacto te lo envía nuestro gerente por WhatsApp, ¿me lo dejas?") deflection_for()/pivot_for()现为"汉字→ZH,否则 EN"二分支,扩展为三分支: 汉字 → ZH;西语特征(re.search(r"[áéíóúñ¿¡]", msg)粗匹配,与参考项目 汉字检测同构)→ ES;否则 → EN
- 新增
- 测试:
tests/test_boundary_filter.py追加——西语消息选 ES 池、英文选 EN、 中文选 ZH;"cars"/"什么车" 不再出现在任何话术池
- Step 6: 同步 scripts/breach_rate.py
把上述新词表同步进 breach_rate.py 的统计模式(保持与墙一致,供上线观察期用)。
Step 6b: 打包前序任务遗留的提示词微修(Task 3/4 质量审查移交,随本任务 commit):
- extractor.md 字段说明末尾补一行(Task 4 Important):「字段值统一用中文概括(如 Kenya→肯尼亚、irrigation→灌溉);唯一例外是规格要求——必须原样保留客户原文,绝不翻译」
- evaluator.md:「询问价格/索要联系方式」两条移出 interested 必要条件列表,单独设「积极信号(加分项,非必要条件)」小节(Task 4 Minor 1)
- evaluator.md interested 示例补「聊了几轮后」(Task 4 Minor 2)
- extractor.md 标准要求示例改 "ASTM D3035" 并补「编号原样保留」(Task 4 Minor 4)
- system.md line 181「固定英文短句」统一为「引导留资模板句」(Task 4 Minor 5)
- system.md line 18 与语言规则段确认无残留字面张力(Task 3 复审 nano-nit 已修 line 19,复核即可) 修完跑 test_extractor_evaluator_prompts.py 相关断言(必要时同步微调断言)。
- Step 7: 全量测试 + Commit
python -m pytest -q && git add -A && git commit -m "feat: 多语言输出墙(€/£/西葡俄阿价格词+时间承诺+ES话术池)+话术建材化+防误杀"
Task 6: 会话编排与联系方式管道建材化
Files:
-
Modify:
app/services/conversation.py、app/services/contact_pipeline.py -
Test:
tests/test_contact_pipeline.py、tests/test_context_seeding.py -
Step 1: 先写失败的阿语数字测试
tests/test_contact_pipeline.py 追加:
def test_arabic_digits_normalized():
# 阿语数字(中东买家)提取后应转 ASCII,CRM 可直接拨
confirmed, _ = split_validate({"whatsapp": "+٩٦٦٥٠١٢٣٤٥٦٧"})
assert confirmed["whatsapp"] == "+966501234567"
(具体 API 名以参考项目实际函数签名为准——split_validate/canon 归一化入口。)
- Step 2: 跑测试确认失败
python -m pytest tests/test_contact_pipeline.py -q -k arabic
预期:FAIL(号码原样保留阿语数字)
- Step 3: 实现数字归一化
contact_pipeline.py 顶部加:
# Unicode 十进制数字 → ASCII(阿语٠-٩/波斯语۰-۹), 中东买家号码 CRM 可直接拨
_DIGIT_TRANSLATE = str.maketrans("٠١٢٣٤٥٦٧٨٩۰۱۲۳۴۵۶۷۸۹", "01234567890123456789")
在归一化入口(normalize_contacts/digits_only 调用链的最前端)对值做 v.translate(_DIGIT_TRANSLATE)。注意:正则 \d Unicode 模式本就匹配阿语数字,位数校验能过——本步只解决"存进去的形式"。
- Step 4: conversation.py 建材化
BOUNDARY_TRIGGER_RE:确认已含 MOQ/lead time/delivery time/sample/certificate 类词;补container loading|装柜|起订(以实际正则现状为准增补)- context 种子白名单:
vehicle_name/vehicle_id→product_name/product_id _build_context_reminder/_enrich_short_message中的车型话术 → 产品方案话术- 同步更新
tests/test_context_seeding.py的键名 - 话术跨层同步(Task 3 质量审查 Minor 4):conversation.py 约 592 行的注入提醒与 boundary_filter.py 的 NO_CONTACT_WEB 仍是 "our manager replies fast!",与 system.md 的 "reply within 12 hours" 口径不一致——统一为 12 小时句(或两版并存亦可,但须明确决定)
- Step 5: 全量测试 + Commit
python -m pytest -q && git add -A && git commit -m "feat: 会话编排建材化+阿语号码转ASCII"
Task 7: 服务端杂项更名
Files:
-
Modify:
app/main.py、app/services/email_service.py、app/api/routes/chat_rest.py、app/services/rate_limit.py、app/config.py(如有 DB 默认名) -
Step 1: 逐文件更名
| 文件 | 改动 |
|---|---|
app/main.py |
FastAPI(title="AI汽车客服") → title="HESUPIPE AI 客服" |
app/services/email_service.py |
发件人 【XYH】 → 【HESUPIPE】;确认无汽车字段引用 |
app/api/routes/chat_rest.py |
docstring "HESU app" → HESUPIPE;种子键名若此处再有引用同步 |
app/services/rate_limit.py |
docstring "Mirrors hesu's" 更新 |
app/config.py + .env.example |
DATABASE_URL 默认 data/hesupipe_ai_kefu.db |
- Step 2: 全局残留扫描
grep -rin "汽车\|vehicle\|byd\|toyota\|hesu auto\|borderlesscar\|VOLT\|XYH\|cc-ai-kefu\|cc_ai_kefu\|car\b\|cars\|什么车\|车型\|车价" app/ tests/ scripts/ --include="*.py" | grep -v "docs/"
预期:无输出(docstring/注释里的行业残留一并清零;car\b|cars|什么车|车型 抓 boundary_filter 话术池等用户可见输出)。
- Step 3: 全量测试 + Commit
python -m pytest -q && git add -A && git commit -m "chore: 服务端品牌与行业残留更名清零"
Task 8: 部署配置更名
Files:
-
Modify:
docker-compose.yml、deploy.sh、openresty.conf、.env.example -
Step 1: 更名
| 文件 | 改动 |
|---|---|
docker-compose.yml |
容器名 cc-ai-kefu→hs-ai-kefu;端口 8016:8000→8017:8000(redis 服务已在 Task1 删) |
deploy.sh |
健康检查 URL 8016→8017 |
openresty.conf |
upstream cc_ai_kefu→hesupipe_ai_kefu;127.0.0.1:8016→8017;alias /www/cc_ai_kefu/→/www/hesupipe_ai_kefu/;日志名同步(含注释掉的 HTTPS 段) |
.env.example |
APP_PORT=8017;PUSH_EXTERNAL_KEY_PREFIX=ai-kefu-jc;PUSH_ENABLED=false(开发期) |
- Step 2: 残留扫描
grep -rn "cc_ai_kefu\|cc-ai-kefu\|8016" docker-compose.yml deploy.sh openresty.conf .env.example
预期:无输出。
- Step 3: 测试 + Commit
python -m pytest -q && git add -A && git commit -m "chore: 部署配置更名(hs-ai-kefu/8017/hesupipe_ai_kefu)"
Task 9: 前端建材化(文案/主题/GDPR + 静态断言同步)
Files:
-
Modify:
static/chat.html、static/widget.js、static/js/chat.js、static/js/theme.js、static/admin.html、static/widget-test.html -
Test:
tests/test_invite_static.py、tests/test_theme_static.py -
Step 1: 了解静态测试的真实性质(避免走错路)
tests/test_invite_static.py/test_theme_static.py 是结构回归网,不是文案断言——
它们断言的是邀请卡面板出厂 hide、pointer-events、回流顺序、theme.js 与 widget.js
调色板逐字同步、无残留旧色 hex 等结构性质。所以本任务的测试策略是:
直接改前端文件,然后跑结构回归测试防破坏(它们会在你漏改某处色值/结构时指路)。
- Step 2: 前端文案与配置
| 文件 | 改动 |
|---|---|
chat.html |
标题 HESUPIPE Support;描述管道场景;欢迎语 "What kind of piping project are you working on?";热门话题 Get Quotation / Pipe Specifications / Delivery & Shipping;WhatsApp +8615937108317;邮箱 hesu@hesuu.com |
widget.js |
默认 title/whatsapp/email 同上;邀请卡文案管道化(pipe specs, MOQ, delivery timing);话题按钮同步 |
js/chat.js |
WhatsApp/email fallback 默认值同步 |
admin.html |
VOLT → HESUPIPE(title/header/头像字母) |
js/theme.js |
默认品牌色橙 #f08a31 → HESUPIPE 品牌蓝(从 hesupipe.com CSS 取实际主色值)。⚠️ 色值有三处要同步:theme.js 的 DEFAULT_COLOR、widget.js 的 DEFAULT_PALETTE(内联副本,测试强制两份一致)、css/style.css 的 :root 槽位值——漏任何一处 test_theme_static 会红 |
widget.js |
GDPR 行:首次对话邀请卡/首条消息附加 "By chatting, you agree to our privacy policy."(链接指向 hesupipe.com 隐私政策页,URL 实施时与需求方确认,可先 https://hesupipe.com/privacy-policy/ 占位) |
| 头像 | kefu.png/kefu-small.png 替换(需求方提供 logo 或用品牌蓝底 "H" 字母临时生成) |
- Step 3: 跑静态断言与全量测试至绿
python -m pytest tests/test_invite_static.py tests/test_theme_static.py -q
python -m pytest -q
- Step 4: 残留扫描 + Commit
grep -rin "HESU Support\|hesu auto\|vehicle\|VOLT\|borderlesscar\|1903717\|f08a31" static/ | grep -v blog
git add -A && git commit -m "feat: 前端HESUPIPE品牌化+管道文案+GDPR提示"
Task 10: 全量回归与收尾扫描
Files: 无新增(验证任务)
- Step 1: 全仓行业残留终扫
grep -rin "汽车\|vehicle\|byd\|toyota\|test drive\|试驾\|提车\|hesu auto\|borderlesscar\|VOLT\|XYH\|cc_ai_kefu\|cc-ai-kefu\|car\b\|cars\|什么车\|车型\|车价" app/ static/ tests/ scripts/ *.yml *.sh *.conf 2>/dev/null
预期:仅 docs/ 归档 changelog 里有(允许——历史档案)。
- Step 2: 全量测试
python -m pytest -q
预期:全绿(170+,含新增多语言/阿语数字用例)
- Step 3: 本地起服务冒烟
python -m uvicorn app.main:app --port 8017 &
curl -s http://127.0.0.1:8017/health
# 预期 {"status":"ok"} 类响应; 浏览器开 http://127.0.0.1:8017/ 与 /admin 目检
- Step 4: Commit(如有收尾改动)
Task 11: 真人验收(真实 LLM + mock 推送联调)
Files:
-
Create:
docs/test-checklist.md(基于参考项目同名文件改写) -
临时:
.env填真实智谱 Key -
Step 1: 编写真人验收清单
按设计文档 §9.2 全项写入 docs/test-checklist.md(问价×2语言/MOQ/样品/交期/认证→转留资;留资→画像+邮件[测试邮箱]+mock推送;换号→更正邮件;已留资不再索要;规格聊天不误杀;后台三视图核对)。
- Step 2: 起 mock UniService 并配置联调
python scripts/mock_uniservice.py & # 本地假CRM, 默认端口 9099
.env:PUSH_ENABLED=true、PUSH_API_URL=http://127.0.0.1:9099/open/v1/inquiry/push、
PUSH_API_KEY=test-key-123(mock 脚本期待的固定 Key,不设会 401)、
NOTIFY_EMAIL=测试邮箱、真实智谱 Key。
- Step 3: 逐项真人验收
按清单实聊(英文+西语+中文三种语言各至少一轮完整留资流程)。核对:邮件收到、mock 推送 accepted、admin 后台画像/意向/日志正确。
- Step 4: 修复发现的问题直至清单全过 + Commit
git add -A && git commit -m "test: 真人验收清单+联调修复"
Task 12: 交付物(嵌入代码/说明/CLAUDE.md)
Files:
-
Create:
docs/embed-guide.md、CLAUDE.md、README.md -
Step 1: 官网嵌入说明 docs/embed-guide.md
内容:一段可粘贴的挂件代码(script 标签+data-* 配置示例:位置/主题色/WhatsApp/自动邀请),贴到 WordPress 哪里(页脚模板或主题设置)、隐私政策页要求。给官网管理员一页读完即可操作。
- Step 2: CLAUDE.md 血缘记录
记录:上游参考项目 D:\refactor\ai-kefu、85%同源、上游修bug需对照其 docs/ changelog 手动同步、本项目 external_key 前缀 ai-kefu-jc、开发期 PUSH 关闭约定、上线观察期跑 breach_rate.py。
- Step 3: README.md
项目简介/本地启动(pip install、.env、uvicorn)/测试(pytest)/部署(deploy.sh+openresty)/管理后台入口。
- Step 4: Commit
git add -A && git commit -m "docs: 官网嵌入指南+CLAUDE.md血缘+README"
上线切换(验收全过后,需求方操作确认)
.env切生产:PUSH_API_URL指真实 UniService、真实 API Key、NOTIFY_EMAIL=客户经理邮箱- 服务器部署:
deploy.sh(端口 8017)+ openresty 域名配置(需求方提供,如 ai.hesupipe.com) - 官网按
docs/embed-guide.md嵌入挂件 - 第一周观察期:跑
scripts/breach_rate.py看漏放/误杀,发现即补正则(设计文档 §9.3)