#AI#AI Agent

实战:用 LangGraph 做一个多步研究 Agent

深度研究(一个问题 → 多轮检索 + 综合成报告)是 Agent 最有含金量的场景,也是单轮 RAG 解不了的。本文用 LangGraph 做一个研究 Agent:拆问题 → 并行检索 → 读全文 → 查漏补缺 → 综合成报告,讲清状态图设计、工具调用、循环控制——把"研究"这件开放的事工程化。

本文要点

  • 主题聚焦:AI、AI Agent
  • 适合人群:独立开发者、全栈工程师、AI 应用开发者
  • 核心价值:快速理解背景、实践路径、常见误区和工程建议
作者 @admin·发布于 2026年1月9日·更新于 2026年7月23日

"帮我研究一下 X,给一份报告"——这种任务,单轮 RAG 解不了(知识库未必有),需要 Agent 自主多步检索外部信息、综合判断。这是 Agent 最有含金量、也最能体现"自主"的场景。

这篇用 LangGraph 做一个研究 Agent,把"开放性研究"这件事工程化。

一、研究 Agent 和普通 RAG 的区别

普通 RAG:一次检索 + 一次生成,适合"知识库里能查到的具体问题"。

研究 Agent:多轮、自主——它要自己决定查什么、查够了没、要不要换关键词、最后综合多源信息成报告。比如"对比 A 和 B 两款框架的优劣",它要分别查 A、查 B、查对比,最后综合。

核心能力链:

text
问题 → 拆子问题 → 并行检索(搜索+读全文) → 评估(够不够) →
       (不够)再检索 → (够了)综合成报告

二、用 LangGraph 画状态图

LangGraph 的"状态图"模型特别适合这种多步流程。先定义状态:

ts
import { StateGraph, Annotation } from "@langchain/langgraph";

const ResearchState = Annotation.Root({
  question: Annotation<string>,            // 原始问题
  subQuestions: Annotation<string[]>,       // 拆出的子问题
  findings: Annotation<Doc[]>(              // 已收集的资料
    { reducer: (a, b) => dedup([...a, ...b]), default: () => [] }
  ),
  drafts: Annotation<string[]>,             // 各子问题的阶段性答案
  report: Annotation<string>,               // 最终报告
  steps: Annotation<number>({ default: () => 0 }),  // 步数(防失控)
});

findings 用 reducer 做去重合并(多个检索节点并行往里加,自动合并去重)。

然后画图:

text
plan → search(parallel) → reflect → (不够)search / (够)write → END
ts
const graph = new StateGraph(ResearchState)
  .addNode("plan", planNode)          // 拆子问题
  .addNode("search", searchNode)      // 检索(可并行 fan-out)
  .addNode("reflect", reflectNode)    // 评估:够不够、缺什么
  .addNode("write", writeNode)        // 综合成报告
  .addEdge(START, "plan")
  .addEdge("plan", "search")
  .addEdge("search", "reflect")
  .addConditionalEdges("reflect", (s) =>
    s.steps >= 5 || enough(s) ? "write" : "search"  // 够了或到上限 → 写报告
  )
  .addEdge("write", END);

三、各节点的设计

plan(拆问题):一个 LLM 调用,把大问题拆成 3–5 个可独立检索的子问题。

text
输入: "对比 Qwen 和 Llama 在中文场景的优劣"
输出: ["Qwen 中文能力 benchmark", "Llama 中文能力", "Qwen vs Llama 对比", "..."]

search(检索):对每个子问题,调搜索工具(web search API),取 top 结果的摘要 + URL。关键:每个子问题独立检索,别用一个模糊 query 搜所有。

read(读全文,可选):对高相关的搜索结果,fetch 全文、切块、抽要点。这是质量分水岭——只看搜索摘要的研究很浅,读全文才能拿到细节。

reflect(评估):这是研究 Agent 的"大脑"。一个 LLM 调用,看当前 findings,判断:

  • 信息够不够回答原问题?
  • 有没有明显缺口(某子问题没查到)?
  • 要不要再查(给新关键词)?

reflect 的输出决定"继续 search 还是去 write"。这个节点决定研究质量——做得好,Agent 会自主补漏;做得差,要么过早写报告(浅)、要么死循环(搜不完)。

write(综合):把 findings 按原问题综合成结构化报告,带引用(每条结论标注来源 URL)。研究 Agent 不带引用 = 不可信。

四、控制:别让它失控

研究 Agent 最容易出的问题:循环搜不完(reflect 一直觉得"不够")。控制手段:

  1. 硬上限:steps >= 5 强制结束去 write。没有上限的研究 Agent 会无限搜。
  2. reflect 给明确判据:"如果每个子问题都有 ≥2 条可信来源,就 enough"——别让它凭感觉。
  3. 预算约束:总检索次数/总 token 上限,撞到就收尾。

研究 Agent 的"够"是主观的,你需要用明确的判据 + 硬上限把它约束住。

五、质量的关键:reflect 和引用

研究 Agent 的好坏,70% 在 reflect 节点。一个差的 reflect:

  • 过早收:报告浅、缺关键面。
  • 不收:死循环烧钱。

调 reflect 的 prompt:给清晰的"够了"判据、让它说出"还缺什么"、给它最大步数意识。

另一个质量关键:引用。write 节点必须让每条结论带来源。研究 Agent 的产出是给人决策用的,没引用的结论没法采信。带引用的研究报告,价值是"综述"的十倍。

六、工程化补充

  • 搜索工具的选择:用能返回正文/摘要的 API(如 Tavily、Brave Search API),别用只给链接的。Agent 要读内容,不只是 URL。
  • 缓存:同一子问题的检索结果缓存(研究里会重复搜相似 query)。
  • 流式:最终 write 流式输出,用户能边看边等(研究 Agent 跑一轮几十秒,全程黑盒很煎熬)。
  • trace:每个节点(plan/search/reflect/write)的输入输出落 trace,研究质量出问题靠它定位("是 plan 拆错了,还是 reflect 过早收了")。

小结

研究 Agent 是 Agent 自主性的集中体现:拆问题 → 多步检索 → 自评 → 补漏 → 综合报告。LangGraph 的状态图把它讲透了——节点是各环节、边是控制流、reflect 是大脑。

记住四条:

  1. plan 拆好子问题,并行检索各管一段。
  2. reflect 是质量关键,给明确"够了"判据。
  3. 硬上限 + 预算,防死循环。
  4. 带引用,研究产出没引用就没价值。

把这套搭起来,你的 Agent 就能做"开放式研究"这种单轮 RAG 做不了的高价值任务——这才是 Agent 相比传统检索最不可替代的能力。

Related

相关推荐