ats_iot_ai 重构复盘:从旧编排到 LangGraph 节点化拆分
这篇文章复盘 ats_iot_ai 这一轮重构的关键路径,重点覆盖三部分:
- 重构记录(发生了什么、按什么顺序推进)
- 工程收益(稳定性、可维护性、协作成本)
- 风险与后续计划(哪些问题还在,下一步怎么收敛)
文中时间线和提交号均来自本地仓库历史;敏感信息(内部域名、token、账号、绝对路径)已全部脱敏。
一、重构背景:为什么必须从“旧编排”走向节点化
旧阶段的核心问题并不是“功能不工作”,而是“功能能工作但工程不可持续”:
- 编排主逻辑长期集中在单体
orchestrator,职责耦合(路由、护栏、提示词、记忆、工具调用)。 - 兼容逻辑与新逻辑并存,随着需求增加,回归成本越来越高。
- 会话存储早期有 Python 本地持久化路径,跨服务一致性和治理边界不够清晰。
- LLM 联调在不同启动方式下会出现配置路径漂移,导致“同代码、不同运行目录”行为不一致。
因此目标不是“把文件拆小”,而是把边界重画清楚:
- Python 控制面负责编排与协议兼容。
- Java 侧收口为执行与持久化真相源(尤其是 store)。
- 编排按节点化思路拆分,逐步向 LangGraph 化执行模型靠拢。
二、关键节点时间线(可追踪)
时间均为本地 Git 记录日期(UTC+8)。
| 日期 | 提交 | 关键变化 | 说明 |
|---|---|---|---|
| 2026-02-21 | 1af4a0b |
feat(model): integrate qwen api into python orchestrator |
首次打通 Qwen 接入能力 |
| 2026-02-27 | 248ce25 |
收敛为单一 ReAct 循环并移除策略栈 | 从多策略堆叠走向单主循环 |
| 2026-03-02 | 2cfc73e |
抽取 prompt pipeline runtime | 节点化拆分第一步(Prompt) |
| 2026-03-02 | eb13f84 / 2d0e86c |
抽取 guardrail pipeline | 护栏从主循环中剥离 |
| 2026-03-03 | bb2363e / d38342b |
memory facade runtime | 短期记忆读写从主干解耦 |
| 2026-03-04 | 97555b0 |
抽离 ToolService,统一 call_tool 接口 | 工具调用入口标准化 |
| 2026-03-04 | 84311b0 |
remove orchestration internals and keep api-compatible orchestrator shell |
形成“API 兼容壳 + 内部节点化运行时” |
| 2026-03-04 | efa2522(master) |
会话存储改为调用 Java 接口 | store 真相源迁移到 Java |
| 2026-03-04 | da9a726、74778bd |
Merge branch 'master' into feature/langgraph-llamaindex-refactor |
将主分支 store 迁移成果并入 refactor 分支 |
LLM 联调修复节点(QWEN_API_KEY_FILE)
这部分主要是联调治理而非单一功能提交:
- 现象:同一代码在不同启动目录下,
QWEN_API_KEY_FILE使用相对路径时会出现“本地可用、脚本启动不可用”。 - 处理:启动配置改为显式传入文件路径,并在联调脚本/环境中统一约定;缺失时走明确报错,不再隐式降级。
- 收益:减少“偶发不可复现”的接入问题,把故障点从模型调用链收敛到配置校验阶段。
三、前后对比:结构和职责怎么变了
1) 编排结构
重构前:
- 大量流程集中在单文件主循环,修改一个分支容易影响其他分支。
- Prompt/Guardrail/Memory/Tool 分层边界弱,测试常依赖端到端覆盖。
重构后:
- 形成节点化拆分:Prompt、Guardrail、Memory、ToolService 各自独立演进。
orchestrator逐步收敛为流程调度入口和兼容壳,内部实现可替换。- 为 LangGraph 风格状态流转打下可迁移结构(节点职责清晰、边界可观测)。
2) API 与前端兼容
重构前:新旧实现切换风险高,常需要同步调整调用方。
重构后:
- 明确保留 API 兼容壳(尤其是事件流与对话接口契约)。
- 迁移内部实现时,外部调用语义不变,降低联调冲击面。
3) 存储边界
重构前:Python 侧承担部分本地存储语义,跨语言一致性治理成本高。
重构后:
- 主分支将 store 迁移到 Java 后,再合并到 refactor 分支。
- Python 侧更聚焦编排,Java 侧承担持久化真相源,职责边界更稳。
四、本轮收益(工程视角)
- 可维护性提升:从“单体流程修改”变为“节点级变更”,评审和回归颗粒度更细。
- 兼容性可控:API 兼容壳使内部重构不必强绑定外部调用方升级节奏。
- 协作效率提升:Python/Java 边界更清楚,排障路径更短。
- 发布风险下降:store 收口后,状态一致性问题更容易定位与治理。
- 联调稳定性提升:LLM key 路径问题从隐式运行时失败转为显式配置校验。
五、风险与后续计划
当前仍存在的风险
- 节点化不等于完全图化:目前是“按 LangGraph 思路拆分”,仍有一部分历史兼容逻辑需要继续清理。
- 双分支并进期间,merge 冲突和行为漂移风险仍在。
- store 迁移后,Python 与 Java 之间的错误语义映射需要持续统一(超时、重试、业务错误码)。
后续计划
- 把剩余兼容分支做成可观测的 feature flag,逐步下线历史路径。
- 持续补齐“节点级”测试与回归基线,减少只能依赖全链路冒烟的情况。
- 在 LangGraph 化阶段引入更明确的状态转移图与中断恢复策略,避免再次回到“主循环膨胀”。
- 对 Qwen 接入补充启动期自检(key 文件可读性、超时和重试参数合法性),把问题前置到服务启动阶段。
六、结语
这次重构的核心价值,不是“做了多少重命名”,而是把系统从“能跑”推进到“可持续演进”:
- 旧编排主干被拆分为可治理的节点职责。
- API 兼容壳保证了迁移阶段的稳定交付。
- store 真相源迁移到 Java 并顺利并入 refactor 分支,跨服务边界更清晰。
- LLM 接入的路径类问题得到工程化治理,联调成本显著下降。
后续工作重点会放在“彻底图化 + 历史兼容清理 + 观测与回归体系固化”。
ats_iot_ai 重构复盘:从旧编排到 LangGraph 节点化拆分
https://willfordzhan.github.io/2026/03/05/ats-iot-ai-refactor-retrospective-20260305/