切换主题
11. Graph 复盘流程:流程变长后,Service 不能一直堆 if
上一章练习参考答案
第一题,关键词规则可能误伤“我当时为什么会想买”“这笔买入是否符合计划”这类历史复盘问题。所以规则要结合时间语义和意图,不要只看单个词。
第二题,不应该直接放行。可以要求用户改写成已发生训练交易的复盘问题。模拟也可能引导到实时决策。
第三题,输出层要检查买卖方向、仓位建议、收益承诺、未来涨跌预测、替用户下结论等危险表达。
新问题:流程越来越长
现在 ReviewCoachService 已经做了很多事:
- 保护栏判断。
- 读取交易。
- 判断信息是否完整。
- 计算风险。
- 读取 K 线。
- 检索知识。
- 读取记忆。
- 组装报告。
这还只是前半程。后面还要加中断恢复、多智能体、Routing、审计日志。
如果全部堆在一个方法里,Service 会越来越像一锅粥。你改一个节点,可能影响全流程。
所以第十一章引入 Graph 思维。
把复盘拆成节点
复盘流程可以拆成这样:
text
接收请求
-> 保护栏判断
-> 读取交易
-> 上下文完整性检查
-> 风险计算
-> K 线窗口
-> 知识检索
-> 记忆读取
-> 报告生成
-> 输出检查Graph 的价值不是把代码画复杂,而是让每个节点有清晰输入输出。
比如“上下文完整性检查”节点只负责决定:
- 继续复盘。
- 进入追问。
- 返回错误。
它不应该顺手生成整份报告。
在伴生工程里怎么理解
当前 ReviewCoachService.review() 还是普通方法,但你可以把每个代码块看成未来 Graph 节点:
java
if (guardrailService.isLiveAdviceRequest(request.question())) {
return blocked(request);
}
TradeRecord trade = tradeRepository.findById(request.tradeId()).orElseThrow();
if (!trade.hasRiskPlan()) {
return needsMoreContext(trade);
}
RiskMetrics risk = riskCalculator.calculate(trade);
List<KlineBar> klineWindow = request.includeKline()
? klineWindowRepository.windowFor(trade.tradeId())
: List.of();当流程稳定后,你再把这些步骤迁移到 Spring AI Alibaba Graph,成本会低很多。
什么时候需要 Graph
不是所有项目都要一开始上 Graph。
如果你的流程只有三步,普通 Service 更清楚。但如果出现这些信号,就该考虑 Graph:
- 节点会根据状态跳转。
- 某些节点需要中断等待人工补充。
- 某些节点可以并行执行。
- 每个节点都要记录输入输出。
- 流程会被产品频繁调整。
PA 复盘教练后期一定会遇到这些情况,所以先建立 Graph 思维。
这一章真正解决了什么
Graph 解决的是“复杂流程可维护”。
它不是为了炫技。它是为了让复盘流程从一个超长方法,变成一组可测试、可替换、可追踪的节点。
练习题
- 当前复盘流程里,哪些节点适合并行执行?
- 哪个节点最适合做中断恢复?为什么?
- 你会把保护栏做成 Graph 的第一个节点,还是最后一个节点?