6.1 KiB
LangGraph 与 Redis:何时用、怎么用
给新项目实现用。可以换等价库,语义必须对齐。环境变量与 db/前缀见 03、13。
一、LangGraph 什么情况下用
用: 一条询价要多次停下来等人、等卡片、等主账、等 Worker 文件,然后从精确断点继续。
典型停点:补问字段、等建单结果、等 TMS 分类后的销售选择、等协同/群报价、等采用/调价、等 Excel/PDF、等成交/未成交。
不用:
| 事情 | 谁做 |
|---|---|
企微验签、inbox、解析 sender_id |
通道 HTTP / inbox |
| 意图(新询价 / 点卡 / 继续本单) | DeepSeek A |
| 抽字段、读图、读表 | DeepSeek B / 千问(经 LLM 队列) |
| 工单六态、报价版本真相 | 主账 MySQL |
| TMS HTTP | 主账适配器 |
| 转 PDF、写对象存储 | Worker LibreOffice 槽 |
自然语言进模型;图节点只编排和调用。节点里不准正则猜字段、不准用图状态假装主账已成功。
没有「等人/等文件」的一次性工具调用,不要硬套 Graph。
二、LangGraph 怎么用
-
一张状态图
节点对应业务步(解析/补问 → 建单 → 查价 → 协同 → 报价 → 采用/调价 → 成交)。停靠点(补问、等卡、等文件、等群)设为中断(现网interrupt_before一组pause_*)。 -
一条询价一个
thread_id
绑会话/工单。新开询价新 thread;旧单resume精确断点。禁止拿新消息重放已提交的建单/查价。 -
Checkpointer 在 PostgreSQL
现网运行账:ytd_runtime(新进程禁止写)。新系统:inquiry_robot_runtime。进程重启后按thread_id捞图。不要把 checkpoint 放 Redis。 -
谁启动图
- 入站 → DeepSeek A →「继续本单」→
invoke/resume。无sender_id不进图。 - Worker 做完识别或 PDF → 结构化 wake(工单号、quoteVersion、waitVersion)。用户聊天文字不能冒充「文件已生成」。
- 入站 → DeepSeek A →「继续本单」→
-
waitVersion + 卡片
补问卡、采用卡绑thread_id + waitVersion + 允许动作。过期或错版本点击丢弃。H5 TTL 30 分钟。 -
与主账边界
图可记「准备建单、TMS 结果分类」;六态成功只认主账 API。图成功、主账失败 → 未报价。 -
会话与图分工
活动工单、打断栈 → conversation session;节点与业务上下文 → checkpoint;等待点 → suspend 账。不要在图里再做第二套六态机。
现网参考形态:StateGraph + Postgres checkpointer + thread_id + 中断停靠。新项目可用 LangGraph 或等价状态机,但必须有:停点、checkpoint、按版本唤醒、禁止用户文字假冒 Worker。
三、Redis 什么情况下用
用: 短命、可丢、可重建的协调。重启丢几秒可以接受。
| 用途 | 说明 |
|---|---|
| LLM / 识别任务队列 | Stream(或 DB 任务表二选一,见下);入口只入队,Worker 认领执行 |
| 短幂等 | 同一 idempotency_key 短 TTL 内不重复入队 |
| 企微 access_token 缓存 | 避免每次打企微;挂了可回内存再拉 |
| 出站 / API 限流 | 窗口计数;超限拒绝或排队,不改工单态 |
| 热缓存 | 只读加速;没有也能从 PG/MySQL 算出 |
不用 Redis 当:
- 工单六态、报价版本、权限(主账)
- Graph checkpoint、suspend、waitVersion、inbox/outbox 持久账(PostgreSQL)
- 附件字节(对象存储)
- Worker 进程全局单例锁(现网
wecom:worker:singleton/SET NX,新系统禁止) - 按企微 userid 伪造 TMS 无价/异常(现网测试开关,新系统禁止)
真相在库里。Redis 挂了:队列可积压、限流失效、token 重拉;已建单、已报价、已成交不得丢。
四、Redis 怎么用
-
连接
只用REDIS_URL+REDIS_KEY_PREFIX(或代码里统一前缀函数)。
现网:db0,前缀ytd:prod:…。新系统:db1,前缀inquiry_robot:。禁止新进程写现网前缀。 -
键必须带环境前缀
所有 key:{REDIS_KEY_PREFIX}:…。LLM 队列 namespace 也要能随环境错开,避免测服抢走现网任务。 -
队列(若用 Stream)
XADD入队,消费者组XREADGROUP。- 按条认领:PEL + 租约心跳;Worker 挂了超时回收,别的槽再做。
- 结果短 TTL(现网约任务 300s / 结果 900s 量级,新项目可配)。
- HTTP 回调线程禁止同步等到完整 LLM(禁止
wait_result堵在请求线程);只入队或写 PG 任务表后返回,由 其它线程槽 消费。不同任务并行认领,不要一个线程串行全部 Stream。 - 同一条消息防重入靠任务认领,不靠「全机只有一个 Worker」的 Redis 锁。
-
也可以不用 Stream
LLM/识别/报价任务可以全部落 PG 任务表 + 认领字段。Redis 则只留 token 缓存和限流。二选一写进设计;不要 Stream 和表双写两套真相。 -
限流
按 scope(全局 / 用户 / 出站)滑动或固定窗口。超限返回可重试,不写主账失败。 -
Token 缓存
GET 未命中再调企微;SET 带过期。失败回退再请求,不要把业务打成「未认证工单」。 -
TTL
队列结果、幂等、限流、token 都要过期。没有 TTL 的业务事实不要进 Redis。 -
同机并存
与现网共用10.206.0.14:6379,必须换 db 和前缀。不要FLUSHDB/FLUSHALL。
五、对照(实现时贴在旁边)
| 问题 | 放哪 |
|---|---|
| 这条询价跑到哪一节点 | Graph checkpoint(PG) |
| 能不能点这张卡 | waitVersion + clarification(PG) |
| 工单是不是已报价 | 主账六态(MySQL) |
| 下一个 LLM 任务谁做 | Redis Stream 或 PG 任务表认领 |
| 会不会把企微打爆 | Redis 限流 |
| 会不会两个进程抢同一条 inbox | 任务认领 + 超时回收;服务只起一份 |
| Worker 能不能双开 | Windows 服务一份 + 发布先停再起;禁止 Redis 全局单例 |
LangGraph = 剧本和书签。Redis = 传话和限速。企微 = 舞台。主账 = 账本。模型 = 台词。