LangGraph 实战 Demo7:反思式多Agent协作 — 让AI学会“自我审视与迭代“

本文是 LangGraph入门实战:6个企业级Demo带你搞懂工作流编排 的第7篇补充,在掌握前6个Demo的基础上,深入讲解 Reflective Multi-Agent 模式。

一、从一个真实痛点说起

你有没有这样的经历:

让AI写一篇文章,第一次出来的东西总是差强人意——逻辑不顺、论据不足、语言干瘪。但如果你把AI的初稿扔回去,告诉它"这里不好,那里不行",它改出来的第二版就会好很多。

人类写作就是这样:初稿 → 评审 → 修订 → 再评审,循环往复直到满意。

那问题来了:能不能让AI自己完成这个循环?

  • 写作者写初稿
  • 评论家评审打分
  • 修订者根据意见修改
  • 评论家再评审……
  • 直到质量达标

这就是Reflective Multi-Agent(反思式多智能体)模式——让多个AI角色互相博弈,通过"生成→评审→修订→再评审"的循环,驱动输出质量持续提升。

这个模式有多重要?Andrew Ng 在2024年提出的四大 Agentic Pattern 中,Reflection(反思)排第一位。


二、先想清楚:为什么不用一个Agent一次搞定?

你可能会想:给大模型一个更长的Prompt,让它一次写出高质量文章不就行了?

现实是:一个角色很难同时做好"创作"和"审视"两件事。

就像你自己写作文——写的时候觉得挺顺,过一天再看发现一堆问题。创作和审视需要不同的思维模式,混在一起互相干扰。

所以核心思路是:拆成不同角色,各司其职,循环迭代。

Writer(写作者) → 只管写,不管评 Critic(评论家) → 只管评,不管改 Reviser(修订者) → 只管改,不管评

三个角色串行协作,Critic 和 Reviser 形成循环,直到 Critic 说"分数够了"才退出。


三、设计流程图:先画图再写代码

在写任何代码之前,先想清楚流程图长什么样:

START → Writer → Critic ──分数达标──→ Finalize → END │ │ 分数不够 ▼ Reviser → Critic(回到评审,形成循环)

关键点:

  • Writer → Critic是固定边:写完必定评审
  • Critic 是唯一的决策点:分数够了走 Finalize,不够走 Reviser
  • Reviser → Critic是循环回路:改完再评,形成反思循环
  • 需要一个最大循环次数,防止死循环

这和前6个Demo中 Demo5(自我纠错Agent)的循环结构一脉相承,但多了"多角色分工"和"评分驱动"两个关键升级。


四、State 设计:工单上要写什么?

流程图想清楚了,接下来定义 State——节点之间传递的那张"工单":

classReflectiveWritingState(TypedDict):topic:str# 输入:写作主题current_draft:str# 当前最新稿件(每轮覆盖)initial_draft:str# 初稿(写入后不变,用于对比)critique:str# 最新评审意见(每轮覆盖)score:int# 最新评分(驱动条件边)best_draft:str# 历史最优稿件best_score:int# 历史最高评分prev_score:int# 上一轮评分(退化检测用)revision_history:Annotated[list[str],reducer_list]# 修订历史(追加)critique_history:Annotated[list[str],reducer_list]# 评审历史(追加)reflection_round:int# 反思轮次计数器final_article:str# 输出:最终文章summary:str# 输出:执行摘要

4.1 为什么有些字段覆盖,有些追加?

更新方式字段原因
覆盖current_draftcritiquescore只关心最新值,当前轮次处理用
追加(reducer)revision_historycritique_history保留完整历史轨迹,可追溯
递增reflection_round控制最大循环次数
只写一次initial_draftfinal_articlesummary写入后不再变

4.2 为什么需要 best_draft / best_score?

因为修订不一定越改越好。可能出现:第1轮7分,第2轮5分(改差了)。没有 best_draft,你只能拿到最后一版(可能最差的那版)。有了它,即使最终版本退化,也能输出历史最高分版本。

4.3 为什么需要 prev_score?

用于退化保护——如果评分从8分骤降到5分,说明修订方向完全错了,应该提前终止而不是继续浪费调用。


五、三个Agent节点:各司其职

5.1 Writer:写作者

最简单的节点,根据主题生成初稿:

defwriter(state: