Files
ai-kefu-admin/CLAUDE.md
T
浅念 9ad02a778f fix: 终审修复——墙执行侧接租户管道(端到端回归锁)+seed补email组+措辞与死依赖清理
C-1(必须修): 墙的执行侧没接租户管道——runtime.compiled_wall 全库只有
AIService 的 $DEFLECTION_POOL 一处消费,conversation.py 执行侧全走模块级
DEFAULT_WALL(jiancai 出厂),auto 租户会话实际跑的是 jc 墙。修复:
- manager 构造时 self._wall = runtime.compiled_wall(与 AIService 同源);
- 6 处过滤调用(violates_boundary/no_contact_value/asks_contact 的句内
  与 pending 尾巴两路)、CC 墙模板/替换句、no_contact 收尾选择、
  pivot/deflection、兜底句、contact_ask 触发日志判定全部传 wall=self._wall;
- _build_context_reminder/_contact_completion_note/_cc_confirm_note/
  _cc_script/_cc_wall_template/_lang_note_for 加 wall=None 尾参
  (None = 模块级默认墙,旧测试直调语义不变;流式侧 _contact_completion_note
  双胞调用同传 wall,写回与注入不漂移);
- 模块级 DEFAULT_WALL 视图常量(BOUNDARY_TRIGGER_RE/_CC_*/_EMAIL_NOTE_* 等)
  保留——boundary_filter 出厂默认与旧测试锚定,boundary_filter 模块级
  DEFAULT_WALL 照旧,conversation 会话流内一律租户墙;
- 端到端回归锁 tests/test_wall_execution_tenant.py(两租户真 runtime +
  脚本化假 AI): jc 独有 [€£] pattern 句在 jiancai 拦截替换(收尾=jc
  pivots 池)/auto 放行逐字流出;同一邮箱违规句两租户各自精确收到自己
  no_contact["web"](12 hours vs replies fast!);contact_ask 提醒注入
  各自墙文案互不渗漏。已验证模拟旧 DEFAULT_WALL 行为时三测全败。

I-1: 两租户 seed 补 email 组(以 brand_values.json 实际值为准:
auto=notify_email 环境值,jiancai=品牌邮箱——其 notify_email 记录是
notify@example.com 占位): auto {sender_name: XYH, notify_emails:
[18339827479@163.com]}, jiancai {sender_name: HESUPIPE, notify_emails:
[hesu@hesuu.com]};seed 存裸名,From 头渲染时外层再包【】。补测
test_seed_tenants_ship_email_group: env NOTIFY_EMAIL patch 成异值证明
seed 槽胜出。

M-1/M-2: README/CLAUDE.md "platform.db 热加载"改为"文件级 registry_reload
热加载(Phase 2 升级为 platform.db)";requirements.txt 删 alembic
(全库零引用,grep 实证唯一命中即该行)。

M-3/M-4(挂账): CLAUDE.md Phase 2 清理单补两项——/health 分级健康
(Phase 4 部署批次)、PromptProvider.from_dir FileNotFoundError 带路径上下文。

全量回归: 463 passed(459 基线 + 4 新增),根目录与 tests/ 子目录同数。

Co-Authored-By: Claude Code <noreply@anthropic.com>
2026-10-13 00:18:54 +08:00

67 lines
6.6 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.
# CLAUDE.md — all-kefu 工作约定
## 项目定位
本项目 all-kefu 是**统一多租户 AI 客服平台**:一套引擎 + 租户配置包,消除"每客户复制一套代码"的旧模式。项目由 ai-kefu / ai-kefu-jc 两个复制分叉项目合并而来,**jc 为主线**(代码以 ai-kefu-jc 为基础迁移,再做租户化改造)。
## 硬约束
- **uvicorn 必须以 `--workers 1` 运行**。内存中的 token 缓存、限流状态、配置缓存、每租户 engine 缓存均假设单进程,多 worker 会导致状态割裂。任何启动脚本/部署配置不得改动此项。
- **Windows 环境**:跑 python / pytest 前设置 `PYTHONUTF8=1`(GBK 控制台遇 emoji / 中文 payload 会直接崩,血泪教训)。
## 本地开发访问方式
- 路由按 Host 解析租户:`/` 与 `/static` 也需要已知租户域名(未知 Host 一律 404,唯一豁免 `/health`,供部署健康检查 curl 用)。
- 本地访问二选一:改 hosts 把 `chat.agent.hnxinyouhe.com` / `chat2.agent.hnxinyouhe.com` 指到 `127.0.0.1`;或 curl 显式带 `-H "Host: chat2.agent.hnxinyouhe.com"`。
- uvicorn 起在 8018:`PYTHONUTF8=1 .venv/Scripts/python -m uvicorn app.main:app --port 8018 --workers 1`。
## 开发流程
- 改动 `seed_profiles` 后必须跑全量 pytest(出厂配置影响面大)。
- 全量回归命令:`PYTHONUTF8=1 .venv/Scripts/python -m pytest -q`(根目录与 tests/ 子目录均可跑,pytest.ini 已锚定根路径)。
## Phase 1 完成状态(2026-10-12 收尾核对)
**测试基线:459 passed**(根目录与 tests/ 子目录各跑一遍,数字一致;唯一 warning 为 starlette TestClient 对 httpx 的弃用提示,无害)。收尾提交前基线即此数,后续任务回归以此为准。
**零同步 IO 审计**(`grep -rn "requests\.\|urllib\|time\.sleep" app/`):
- 命中数 **0**——app/ 内无 requests 调用、无 urllib、无 time.sleep。
- 全库唯一 HTTP 出站点为 `app/engine/services/lead_push_service.py` `_do_post`,使用 `httpx.AsyncClient`(async with 上下文),异步路径成立。
- `app/engine/providers/glm.py` 的同步 token 生成与兜底同步调用分别经 `loop.run_in_executor` / `asyncio.to_thread` 下卸,事件循环不被阻塞。
- `app/engine/services/rate_limit.py` 的 `import time` 仅用 `time.time()` 读时钟(纯 CPU,非 IO);app/ 源码内无 `open()` 文件读取。
**spec §6.2 合并清单核对**(逐项,全部在位):
- 取自 jc:cc_completion 完整判定树+状态机+extractor `cc_reply`+e164 出站渲染(`app/engine/services/cc_completion.py`,conversation.py 双门控消费);多语言墙(€/£、西/葡/俄/阿词表在 `seed_profiles/jiancai/wall.json`、ES 迂回池 boundary_filter+wall.json、建材防误杀白名单为 pattern 级 comment+后顾断言 DN800/SDR11/PN16/"euro pallets" 排除);dual-contact 分步双要(cc_settled 串行门控邮箱轻补)+`_email_asked`;CC 强制墙(conversation.py cc_wall 裁决段)+零号码墙回显豁免收窄(boundary_filter.py:旧豁免移除,改 allow_number 回显确认轮白名单+防自锁线);XFF 服务端优先(chat_rest `_server_ip`/chat.py 握手期提取,均取第一段)、阿语数字归一(contact_pipeline 捕获源头 translate)、`resolve_region_code`(ip_service.py)。
- 上游吸收:input-placeholder 可配置化(品牌配置组,public.py 下发,widget/chat data-placeholder 管道);7 个测试文件(test_channel_hygiene / test_chat_rest_ip / test_lead_push_cc / test_cc_integration / test_ip_service_region / test_prompt_static / test_placeholder_static,commit d1aed8e)。
- 三不带:blog.html(static/ 无此文件)、Redis(app+scripts 零命中)、旧版 whatsapp-cc-completion(零命中,jc 版 cc_completion.py 取代)。
**当前能力一览**:多租户引擎(TenantRuntime 隔离边界,engine 不感知 platform);站点模型(tenant_config.Site,一租户多站点覆盖);词表/提示词/品牌全配置化(seed_profiles 出厂包 + 文件级 registry_reload 热加载,Phase 2 升级为 platform.db);Host 路由(host_middleware,未知 Host 404);WS 防串库(租户化 client key + 会话站点标);WS 每 IP 连接上限(conn_limiter,租户级 ws_conn_limit 配置)。
## Phase 2 清理单(前序审查挂账,集中列此)
1. **FakeAI 三份拷贝收敛进 conftest**——下次吸收测试时先做(出处:上游吸收审查,tests/ 内多处 FakeAI 定义重复)。
2. **rate_limit 与 ws_conn_limit 的 0 语义统一 + 配置类型校验**——试金石批次(出处:配置接线审查)。
3. **name_to_region_extras / context_seed_map 等散装 resolver 收拢为 config_views 单入口**(出处:配置接线审查"种子映射消双路径"遗留)。
4. **AIService.from_runtime 类方法**——组装正典化(出处:引擎改造审查)。
5. **boundary_filter 视图常量退役**——admin 重写后旧测试迁移时(出处:引擎改造审查)。
6. **push enabled 布尔空槽语义**——admin 配置显式化时解决(出处:push 审查)。
7. **contact.template_languages 运行期接线**——后台批次(出处:配置 schema 审查)。
8. **话术含引号/换行的转义**——编辑器批次(`_format_deflection_pool` docstring 有注)。
9. **产品决策项**:国名纠正 e164 变化时是否补发更正邮件(上游行为更优);REST/WS 服务端 IP 口径是否统一(出处:上游吸收审查)。
10. **avatar 从 seed_profiles 迁 uploads 卷**——上传功能落地时(出处:品牌下发审查)。
11. **/health 分级健康**——Phase 4 部署批次(进程存活之外按依赖分级上报,健康检查可区分"进程活"与"依赖通";出处:终审审查 M-3)。
12. **PromptProvider.from_dir 的 FileNotFoundError 带路径上下文**——提示词目录缺失时异常信息含实际路径,定位不用猜(出处:终审审查 M-4)。
## Phase 2 计划编写注意
- conftest 跨循环纪律:`async_db` 夹具用 NullPool;TestClient 必须走 portal 桥接事件循环;禁止 `asyncio.run` 直开租户 session_factory(三个坑都在 tests/conftest.py 有既成解法,照抄勿发明)。
- `build_app` / `app_client` / `TenantTestClient` 夹具已就绪,新测试优先复用而非自建 app 实例。
## 文档索引
- 设计文档(spec):`docs/superpowers/specs/2026-10-12-unified-kefu-platform-design.md`
- Phase 1 实施计划:`docs/superpowers/plans/2026-10-12-phase1-engine-merge-tenantization.md`
- 部署坑手册:Phase 4 补 `docs/deploy-production.md`(尚未存在)