Files
inquiry_robot/prompt/06-Python智能体.md
T

7.5 KiB
Raw Blame History

提示词:Python 智能体 / Worker 端

你负责与现网询价智能体 功能等价 的运行时。代码全新组织,不要做成单文件上帝模块。每个模块、Handler、Graph 节点、队列/槽代码必须有详细中文注释(文件头 + 函数职责/副作用/线程;见 05 注释节)。无注释不验收。

必须提供的进程

只允许下面这些自研进程(详见 01 目标进程):

  1. 一个 HTTP:合并现 8810/8809/8811。询价入口、H5、主账唤醒、企微应用回调。请求线程只验签、入 inbox/任务表、返回;禁止同步 LibreOffice / 等完整 LLM。
  2. 一个 Worker:消费 LLM、识别、报价(Excel→PDF)、微盛存档。队列 + 按任务认领(处理中/超时回收)+ 重试。并发:LibreOffice 1 槽,其余 HTTP 类 2~3 槽。Windows 服务只起一份;禁止 Redis 全局 Worker 单例锁(现网 wecom:worker:singleton)。
  3. AIBOT 客户端:连本机 8813 桥;桥进程可仍是 Node .cjs。
  4. 企微 inbox 消费与 outbox 外发:放在 HTTP 进程的快循环,或 Worker 里与 soffice 隔离的槽,不得和转 PDF 串行互堵。

不要:独立 bridge_api / wecom_robot 端口;五个 NSSM Worker。群机器人 8812 默认不做。

禁止卡顿(必须多线程 / 多槽)

实现验收:企微回调与 H5 在慢活进行时仍能秒回;一份 PDF 不能拖死收消息、查价、出站。

  1. 请求线程只做短事:验签、去重、入 inbox/任务表、202/明文成功码、返回。禁止在回调 / H5 / 唤醒 HTTP 里同步 invoke 完整 Graph、等 LLM、跑 soffice。
  2. 尽量用多线程:HTTP 用线程池(uvicorn workers 或等价);Worker 进程内用线程槽并行——HTTP 类(模型、识别、主账、存档、outbox)至少 2~3 槽;inbox 消费与 outbox 外发独立线程,不得和转 PDF 排成一条队列。
  3. 唯一例外:LibreOffice 1 个槽(本机两台 soffice 会互抢卡死)。这不是「整进程单线程」。
  4. I/O 等待要让出:调企微、主账、TMS 经主账、对象存储、模型 HTTP 用超时 + 线程池;禁止无限阻塞、禁止热循环 sleep 轮询把槽占满。Graph resume 放在 Worker 槽里跑,不要占回调线程。
  5. 禁止用一把进程大锁串行所有工单。防重入只锁「同一条任务 / 同一个 thread_id 的写冲突」,不同工单必须能同时跑。
  6. 共享状态要线程安全:checkpoint、认领、outbox 用 DB 事务或按条锁,不要无锁改全局 dict。
  7. Windows 上线程优先于再开多个 Python 进程(已规定只有一个 Worker 进程)。需要并行就加槽/线程,不要再拆 NSSM。

卡住整机的写法一律视为缺陷,不是「先跑通再优化」。

模块边界

NormalizedInbound
  → 冻结只读状态快照
  → 允许的意图集合
  → DeepSeek A 唯一 route_decision
  → 确定性 RouteDecision
  → 唯一 handler
  → 执行到下一个 wait 边界
  → 持久化 version + 幂等键

模块划分(源码,不是进程)

进程可以只有 HTTP + Worker;包必须按功能切开。现网把编排、企微业务、识别堆进超大文件,新项目禁止复现。

建议包(名称可改,边界不能混):

包 只做什么 不准塞什么
channel/wecom 验签、XML/JSON 解析、sender_id、inbox 写入 Graph、LLM、建单
channel/h5 表单上传、clarification 页 六态、TMS
channel/outbox 企微发送、限流、重试 抽字段
routing DeepSeek A、RouteDecision 副作用(建单/发消息)
handlers/ 每类意图一个模块:会话、补问、建单、TMS 展示、协同、采用/调价、成交、异常 一个文件处理全部卡片
graph/ 图定义、节点各文件、pause/resume、wake 企微 HTTP、soffice
llm/ 网关、队列、各 mode schema 业务六态
jobs/ 认领循环、识别槽、LibreOffice 槽、Archive 槽 回调路由
ledger/ 主账 HTTP 客户端 直连 TMS、直连 MySQL
storage/ 对象存储 工单状态
config/ 只读环境变量 业务 if/else

规则:

  • 新功能先归包再写代码。入口(main、FastAPI app、Worker 启动)只组装依赖,不写业务分支。
  • Graph 节点分文件(或按阶段分子包),禁止单文件堆全部节点。
  • Handler 一类卡片/一类意图一个文件;公共校验放 schema/ 或 policy/,不要复制粘贴进每个 handler。
  • 跨包只通过明确接口(函数/协议/事件),禁止互相 import 私有内部函数绕过边界。
  • 单文件超过约 400~600 行且已含两类职责:拆,不要继续往下加。

堆在一起的上帝模块一律视为缺陷,与卡顿同样不可验收。缺详细中文注释同样不可验收。

身份

入站已带企微 userid(sender_id)。禁止在收到聊天后再请求企微换 ID。无 sender_id 不进 Graph。工单 owner、会话、卡片权限、outbox touser 只用该字段。角色查主账,不查企微。H5 不从 URL 读 userid。细则见 09。

状态

状态 存储
活动工单、打断栈 conversation session
图节点、业务上下文 Graph checkpoint
等待点 waitVersion suspend 账
补问/卡片绑定 clarification,TTL(H5 30 分钟)
正式六态 只调用主账 API
LLM/识别/报价任务 各自任务表 + 认领状态(谁在做、超时释放),不是进程级单例

运行账 PostgreSQL:PG_HOST/PG_DATABASE/PG_DSN 走环境变量(测试 ytd_test_runtime,正式 ytd_runtime,见 13)。开发期间 inbox/outbox/checkpoint/任务表缺结构:直接加迁移并执行到当前 PG_DATABASE,不要问能不能加表。禁止动现网 ytd_runtime。

LangGraph / Redis 何时用、怎么用:见 14-LangGraph与Redis.md。 图:一单一个 thread_id,checkpoint 在 PG,停点中断,Worker 结构化 wake。Redis:REDIS_URL(测试 /1 + ytd:test:),只做 Stream 或限流/token;checkpoint 与六态不准进 Redis。

LLM

实现队列(Redis Stream 或 DB 任务表)、按条认领、重试、熔断、审计。不要全局 SET NX 单例。模式至少:

  • ordered_actions(DeepSeek A,strict tool)
  • 文本字段抽取(DeepSeek B)
  • 附件文本 / 图片读取(千问)
  • 群报价抽取
  • 报价工作表映射

环境变量名与 03-配置与密钥清单.md 对齐;测试/正式取值见 13(YTD_ENV、域名、端口、库)。禁止把 ai.ytd-scm.com 写死在代码里。

字段

实现与 inquiry-required-fields-v1.json 等价的条件激活(JSON 放在新仓库)。SEA 箱型箱量保持单原始字段 + B 模型投影 containerItems。协同点击用不可变询价原话重跑 B,去重补问。

出站

  • 主账:登录或 Token,所有写操作要幂等键(message_id / request_id / quoteVersion)。
  • 企微:只通过 outbox;失败重试;过期出站丢弃不计业务成功。询价与正式同一 Agent 1000010;运维 1000014,测试告警正文加 [test]。
  • 对象存储:S3 兼容;生成文件后登记主账附件再发企微。

测试

每个业务线:完整字段不补问;缺一项只补该项;TMS 有价/无价/1003/技术失败;重复回调不建第二单。禁止依赖真实密钥才能跑单测(TMS 用 fixture 模式)。不要按企微 userid 在 Redis 里伪造 TMS。