# CLAUDE.md “/; HESUPIPE 管道建材 AI 客服(hesupipe.com,河南和硕集团)。 FastAPI + SQLite + 智谱 GLM,嵌入外贸官网,做"AI 需求了解 + 留资获客 + 邮件/UniService CRM 推送",AI 不回答价格/交期/MOQ 等实质问题,一律引导留资转客户经理。 ## 血缘与上游同步(重要) 本项目**复制自**参考项目 `D:\refactor\ai-kefu`(Hesu Auto 汽车出口 AI 客服,同集团姊妹 业务),约 **85% 代码同源**。复制时的架构决策见 `docs/superpowers/specs/2026-09-29-building-materials-ai-kefu-design.md`(方案 A:完整拷贝 + 建材化定制)。 **同步规则**:上游修 bug / 改正则 / 调提示词机制后,本项目需**手动同步**。 1. 看上游 `D:\refactor\ai-kefu\docs\` 下的 changelog 文件(按日期命名,如 `2026-09-28-lead-push-changelog.md`)——本项目 `docs/` 下有同批文件的拷贝(截至 复制日 2026-09-29),对比两边目录即可发现上游新增的变更记录; 2. 评估该修复是否适用于本项目(建材差异部分见下),适用则同步代码 + 同步测试; 3. 同步后在本次提交信息里注明"同步自上游 "。 **禁止反向操作**:不要把本项目的建材定制覆盖回上游。 ## 与上游的关键差异清单(改这些地方时别照抄上游) | 差异点 | 本项目 | 上游(ai-kefu) | |---|---|---| | 行业与提示词 | 4 个提示词全部建材化:`system.md`(管道外贸人设+MOQ/交期/样品/认证红线)、`company_facts.md`(HESUPIPE 事实卡)、`extractor.md`(意向品类/规格要求/标准要求/采购数量等字段)、`evaluator.md`(管道采购意向分级) | 汽车(Hesu Auto)语义 | | boundary_filter 多语言墙 | 墙按建材市场扩充:`€`/`£`+数字、西葡俄阿价格词(precio/costo/custo/preço/цена/стоимость/سعر/أسعار/ثمن,含复数与阿语定冠词 ال 连写形态)+天数词(días/дней/أيام 等);迂回话术池 EN/ZH/**ES**;规格防误杀(DN/PN/SDR/PE100/SCH/ISO4427/20ft 不拦) | 只中英 + `$` + 零号码墙 | +| 线索键前缀 | `PUSH_EXTERNAL_KEY_PREFIX=ai-kefu-jc`(与汽车*--*项目线索空间隔离,**勿改回 ai-kefu**) | `ai-kefu` | | 端口 | 8017 | 8016 | | Docker 容器名 | `hs-ai-kefu` | (上游原名不同) | | 品牌 | HESUPIPE,品牌蓝 `#066fc0`(theme.js 与 widget.js 中的主题派生单元整块同步,`tests/test_theme_static.py` 强制一致) | HESU,橙色 | | DB 文件 | `data/hesupipe_ai_kefu.db` | `data/cc_ai_kefu.db` | | openresty 路径 | `hesupipe_ai_kefu` | (上游路径) | | context 种子键 | `product_name` / `product_id` | `vehicle_name` / `vehicle_id` | 主题派生单元(调色板函数块)在 `static/widget.js` 与 `static/js/theme.js` 中逐字相同, 只可整块替换,不可单边修改——`tests/test_theme_static.py` 会强制校验。 ## 开发约定 - **推送开关**:开发/测试期 `.env` 保持 `PUSH_ENABLED=false`,防止测试线索推爆生产 CRM。 生产环境必须 `true`(需求方已确认最终状态为启用)。全量验收通过后一次性切换。 - **合并门槛**:`pytest` **230 项全绿**。LLM 全 mock,验证代码正确性。 - **真实 LLM 验收**:mock 测不了 AI 表现(守边界/语言跟随/不回显号码)。用真实智谱 Key + `scripts/mock_uniservice.py`(本地 9099,`PYTHONUTF8=1` 启动,期待 `X-Api-Key: test-key-123`) 联调,验收清单与现状见 `docs/test-checklist.md`(2026-09-29 已通过,含 4 项不阻塞残差)。 - **提示词改动**:`app/prompts/` 下 4 个 .md 是 AI 行为的源头;改动后跑 pytest(有文案断言) 并视改动性质补一轮真实验收。 - **环境坑(Windows)**:mock_uniservice 必须以 `PYTHONUTF8=1` 启动,否则 GBK 控制台遇 emoji payload 即崩溃;中文文档用 Write 工具写,别用 bash heredoc。 ## 常用命令 ```bash # 测试(合并门槛,230 项) pytest # 本地启动(端口 8017) pip install -r requirements.txt cp .env.example .env # 填 ZHIPU_API_KEY 等 uvicorn app.main:app --host 0.0.0.0 --port 8017 # 本地联调推送(PUSH_ENABLED=false 时不影响;验证推送链路用) PYTHONUTF8=1 python scripts/mock_uniservice.py # 监听 9099,X-Api-Key: test-key-123 # 生产部署(服务器上) bash deploy.sh # docker compose 构建并启动,健康检查 7654/health ``` - 聊天演示页 `/`,管理后台 `/admin`,健康检查 `/health`。 - 挂件嵌入官网指引:`docs/embed-guide.md`。 ## 部署注意事项(血泪教训,勿重蹈覆辙) 线上完整手册见 `docs/deploy-production.md`(环境/反代配置/发版流程/踩坑实录)。 以下是最容易再犯的坑: 1. **⚠️ compose 项目名(互删事故根因,勿删 `name:` 行)**:1Panel 站点目录都叫 `index`,docker compose 默认以目录名为项目名——曾与汽车项目 (`chat.agent.hnxinyouhe.com/index`)撞名成同一 project "index",导致 **任一目录 down/up 互删对方容器**(起一个、另一个 502)。已在 compose 固定 `name: hs-ai-kefu` 根治。**任何部署到 1Panel 的新项目都必须显式设置 compose 项目名**;汽车项目(仍叫 index)若再出新互斥,同样加 `name:` 解决。 2. **挂件静态文件打进镜像**:改 `static/` 必须 `docker compose build`,仅 `up -d` 不生效。 3. **1Panel 反代**:面板配完反代需确认主 conf(`conf.d/<域名>.conf`)里有 `include .../proxy/*.conf;` 行;WebSocket 走 `proxy/ws.conf`(单套升级头, 重复两套会被 uvicorn 拒成 426);改后 `nginx -t` 再 reload。 4. **同页面嵌多个挂件**(如官网同时挂汽车+建材客服):两挂件源自同一代码, `sessionStorage` 邀请卡 key(`widget_invite_dismissed_`)与 host id (`cc-widget-host`)**同名互相干扰**——需要同页共存时先给全局命名加项目前缀。 5. **服务器上不许有未提交改动**:`git status` 应干净;改动请进 git 再部署, 避免回到 stash 时代(pull 冲突)。 ## 上线观察期(第一周必做) 上线不是终点。**上线后第一周**跑 `scripts/breach_rate.py` 观测双向偏差: - **漏放**:AI 回复里出现价格/交期/MOQ 数字而墙没拦下(多语言新词表已随建材化扩充, 仍可能有长尾语言形态漏网); - **误杀**:正常建材规格聊天(DN800/PN16/SDR11 之类)被墙误拦。 发现即补正则 + 补测试,流程见设计文档 §9.3。已知 4 项不阻塞残差(西语模板句翻译、 样品措辞、extractor 占位词、多轮压力下偶发漂移)记录在 `docs/test-checklist.md`, 靠此观察期收敛。