首页
学习
活动
专区
圈层
工具
发布
社区首页 >专栏 >【Multi-agent实战】LangGraph 实现可视化的科研 Multi-Agent实战项目

【Multi-agent实战】LangGraph 实现可视化的科研 Multi-Agent实战项目

原创
作者头像
用户11925555
发布2025-11-22 22:00:38
发布2025-11-22 22:00:38
2160
举报
  • code_snippets, tsne_fig_path, ablation_ideas 等等。

🧪 三、把每个 Agent 包装成 LangGraph 的“节点”

3.1 初始化基础 LLM(沿用你上一篇的习惯)

代码语言:python
复制
# llm_config.py
from config import api_type, api_key, api_base, api_version, model_name
from langchain.chat_models import AzureChatOpenAI

def build_llm():
    return AzureChatOpenAI(
        openai_api_base=api_base,
        openai_api_version=api_version,
        deployment_name=model_name,
        openai_api_key=api_key,
        openai_api_type=api_type,
        temperature=0.2,
    )

3.2 PaperHunter 节点:查文献 → 写回 state

这里不再单独搞一个 AgentExecutor,而是直接在 node 函数里 call LLM + arxiv 工具(你也可以复用上一篇 paper_hunter_agent,我这里写个轻量版示意)。

代码语言:python
复制
# nodes.py
from typing import Dict
from langgraph.graph import END
from langchain.utilities import ArxivAPIWrapper
from langchain.prompts import PromptTemplate
from langchain.chains import LLMChain

from research_state import ResearchState
from llm_config import build_llm

llm = build_llm()
arxiv = ArxivAPIWrapper()

# ===== 1) PaperHunter Node =====
def paper_hunter_node(state: ResearchState) -> ResearchState:
    topic = state["topic"]
    
    query = (
        f"{topic}, focus on works since 2022, "
        "especially those using CLIP or vision-language models."
    )
    result = arxiv.run(query)
    
    state["papers_raw"].append(result)
    state["logs"].append(f"[PaperHunter] searched arxiv with query: {query}")
    return state

3.3 PaperAnalyst 节点:把 raw 文本 → 结构化 JSON

代码语言:python
复制
# nodes.py (继续)
paper_analyze_prompt = PromptTemplate(
    input_variables=["paper_info"],
    template=(
        "你是一名科研助理,下面是若干论文的检索结果:\n{paper_info}\n\n"
        "请将这些论文整理为 JSON 数组,每个元素包含字段:"
        'name, task, method, datasets, metrics, key_ideas, pros, cons。\n'
        "只输出 JSON,不要额外解释。"
    ),
)
paper_analyze_chain = LLMChain(llm=llm, prompt=paper_analyze_prompt)

def paper_analyst_node(state: ResearchState) -> ResearchState:
    # 简单地把 papers_raw 拼起来丢给总结链
    paper_info = "\n\n".join(state["papers_raw"])
    summary_json = paper_analyze_chain.run(paper_info=paper_info)
    
    state["papers_struct"].append(summary_json)
    state["logs"].append("[PaperAnalyst] summarized papers into structured JSON.")
    return state

3.4 ExperimentPlanner 节点:根据 JSON + 资源限制出实验规划

代码语言:python
复制
# nodes.py (继续)
from langchain.prompts import PromptTemplate

experiment_prompt = PromptTemplate(
    input_variables=["paper_summary_json"],
    template=(
        "下面是关于某个研究主题的论文结构化总结(JSON):\n{paper_summary_json}\n\n"
        "我的资源:单卡 RTX 3090(24GB),两周时间,每天训练时间约 6 小时。\n"
        "请设计一个可行的 baseline 实验方案,用 Markdown 输出,包含:\n"
        "1. 推荐复现的论文(1~2 篇)\n"
        "2. 数据集与预处理策略\n"
        "3. 模型与关键超参数\n"
        "4. 预估训练时间(粗略即可)\n"
        "5. TODO checklist(用 [ ] 列出来)\n"
    ),
)
experiment_chain = LLMChain(llm=llm, prompt=experiment_prompt)

def experiment_planner_node(state: ResearchState) -> ResearchState:
    # 简单起见,我们只拿最后一次的结构化结果
    paper_summary_json = state["papers_struct"][-1] if state["papers_struct"] else ""
    plan_md = experiment_chain.run(paper_summary_json=paper_summary_json)
    
    state["plan"] = plan_md
    state["logs"].append("[ExperimentPlanner] generated baseline experiment plan.")
    return state

3.5 HumanReview 节点:插一个“人工确认”点

科研场景经常需要你自己看一眼,这个在 LangGraph 里可以做一个「pause / checkpoint」式节点(这里先写一个简单的占位):

代码语言:python
复制
def human_review_node(state: ResearchState) -> ResearchState:
    # 实战中可以把 state 持久化,等待前端/人工修改后再继续
    state["logs"].append("[HumanReview] checkpoint reached, please review papers_struct.")
    return state

🕸 四、用 LangGraph 把节点串成一张“科研图”

核心步骤:

  1. 创建一个 StateGraph(ResearchState)
  2. 加节点:paper_hunter / paper_analyst / human_review / experiment_planner
  3. 加边: START → paper_hunter → paper_analyst → human_review → experiment_planner → END。
代码语言:python
复制
# graph_build.py
from langgraph.graph import StateGraph, START, END

from research_state import ResearchState
from nodes import (
    paper_hunter_node,
    paper_analyst_node,
    experiment_planner_node,
    human_review_node,
)

def build_research_graph():
    builder = StateGraph(ResearchState)

    # 注册节点
    builder.add_node("paper_hunter", paper_hunter_node)
    builder.add_node("paper_analyst", paper_analyst_node)
    builder.add_node("human_review", human_review_node)
    builder.add_node("experiment_planner", experiment_planner_node)

    # 定义流程:START -> hunter -> analyst -> review -> planner -> END
    builder.add_edge(START, "paper_hunter")
    builder.add_edge("paper_hunter", "paper_analyst")
    builder.add_edge("paper_analyst", "human_review")
    builder.add_edge("human_review", "experiment_planner")
    builder.add_edge("experiment_planner", END)

    graph = builder.compile()
    return graph

调用:

代码语言:python
复制
# main.py
from graph_build import build_research_graph

def main():
    graph = build_research_graph()
    
    init_state = {
        "topic": "CLIP for deepfake detection and multimodal forgery since 2022",
        "papers_raw": [],
        "papers_struct": [],
        "plan": None,
        "logs": [],
    }

    final_state = graph.invoke(init_state)
    
    print("==== Logs ====")
    for log in final_state["logs"]:
        print(log)
    
    print("\n==== Plan ====\n")
    print(final_state["plan"])

if __name__ == "__main__":
    main()

这样你就有了一个完整的:

科研 Multi-Agent × LangGraph State Machine

  • 想加节点:比如再加入一个 CodeGenNode,负责生成训练脚本;
  • 想改流程:比如把 human_review 变成条件分支(需要人工确认时才走这一节点)。

🧩 五、Planning 幻觉 & 粒度问题,在 LangGraph 里怎么回答?

你之前问过两个典型面经问题:

  1. “planning 出现幻觉,你怎么解决?”
  2. “planning 粒度太碎 / 太粗,怎么办?”

用 LangGraph + Multi-Agent 的话,你可以这样回答——

5.1 幻觉问题:把“下一步去哪”从 LLM 里拿出来

  • 在 LangChain 经典 ReAct 里,LLM 每一步自己思考:
    • Thought: 我现在要…
    • Action: 调用 xxx 工具
    • Observation: …
  • 幻觉来源的一部分就是:下一步完全由 LLM 想象

在 LangGraph 方案中:

  • 大部分控制流由图结构决定
    • Papers 还没查完,就不会走 Planner;
    • Planner 只在 papers_struct 存在时才会运行;
  • LLM 只负责 Node 内部「干活」,而不是「决定流程」。

如果要更严一点,可以:

  • 对每个 node 的输入做 schema 校验(例如 papers_struct 必须是合法 JSON);
  • 若校验失败,回到上一个节点重试(LangGraph 支持这种回环边)。

5.2 粒度问题:用节点粒度来“锁”规划粒度

  • 如果你发现某个步骤太大,比如 PaperAnalyst 又总结又打分又排序,还顺带起标题——
    • 可以拆成多个 node:paper_extract_node / paper_rank_node / title_node
  • 如果太碎(每一个小操作都是一个 LLM 调用,效率极差),
    • 就合并一些强相关的逻辑为一个 node,让 LLM 一次做完。

一句话总结:

在 LangGraph 里,planning 粒度是通过“图上节点的拆分粒度”来控制的,而不是完全由 LLM 自由发挥。


🎤 六、面经角度:围绕 LangGraph + Multi-Agent 怎么吹?

给你几段可以直接背的回答。


Q1:你在项目里是怎么管理 Multi-Agent 的流程的?为什么选 LangGraph?

我这边是用 LangGraph 做底层 workflow, 把整个科研 Multi-Agent 抽象成一张 StateGraph:

每个 Agent(比如文献检索、论文分析、实验规划)都是一个 Graph Node; 所有中间结果都挂在一个共享 State 上,比如 topic、papers_raw、papers_struct、plan 等; 控制流由 Graph 显式定义,比如 START → PaperHunter → PaperAnalyst → ExperimentPlanner → END;

这样相比纯 prompt-based 的 ReAct,有几个优点:

控制流是可视化、可追踪的,很容易 debug; 可以插入人工审阅节点,实现「AI + Human in the loop」; 一旦要改流程,比如加一个 CodeGen 节点,只要改图结构,不用推倒所有 prompt。


Q2:LangGraph 和 LangChain 的 AgentExecutor 相比,有什么优势?

LangChain 的 AgentExecutor 更像是「单 Agent 带工具」, 流程主要靠 LLM 的 Thought/Action 循环,核心是一条“对话录”。

LangGraph 则更偏向「流程编排」:

提供 StateGraph,支持有向图、分支、循环、条件边; 状态是一个 TypedDict,显式管理,而不是塞到 prompt 里; 更适合复杂的 Multi-Agent 系统,比如科研流水线、商用流程自动化;

我这个科研项目里,两者是配合使用的:

某些 Node 内部仍然用 LangChain Agent(比如 PaperHunter 里用带工具的 Agent); LangGraph 则在更高一层做“节点级调度”。


Q3:如果后续要在这个科研 Multi-Agent 里加入“在线强化学习 / 评分器调整策略”,LangGraph 还能 hold 住吗?

可以的,LangGraph 的思想跟 RL 里的 policy graph、option framework 其实挺像:

每个 Node 类似一个 option 或 sub-policy; State 里可以加入 reward、history 等信息; 甚至可以在图上加一个「策略更新节点」,定期根据失败的轨迹更新 prompt 或 routing 策略。

真要搞 Agentic RL 的话,LangGraph 可以作为环境里的「流程引擎」, 上面再跑一层 RL 来调整路径或参数,这也正好和我在做的 Agentic RL 专题呼应。


✅ 七、小结

这一篇,我们做了几件事:

  1. 把「科研 Multi-Agent」升级成了一个 LangGraph StateGraph
  2. 定义了一个 ResearchState,让所有节点共享一个“科研黑板”;
  3. 节点粒度显式图结构 来解决:
    • planning 幻觉;
    • 粒度太碎 / 太粗;
  4. 顺手准备了几个关于 LangGraph + Multi-Agent 的面经回答

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 用 【Multi-agent实战】LangGraph 实现可视化的科研 Multi-Agent实战项目
    • ✍ 前言
    • 🧠 一、为什么要用 LangGraph 来做 Multi-Agent?
    • 🧩 二、先定义一个科研 State:所有 Agent 共用
    • 🧪 三、把每个 Agent 包装成 LangGraph 的“节点”
      • 3.1 初始化基础 LLM(沿用你上一篇的习惯)
      • 3.2 PaperHunter 节点:查文献 → 写回 state
      • 3.3 PaperAnalyst 节点:把 raw 文本 → 结构化 JSON
      • 3.4 ExperimentPlanner 节点:根据 JSON + 资源限制出实验规划
      • 3.5 HumanReview 节点:插一个“人工确认”点
    • 🕸 四、用 LangGraph 把节点串成一张“科研图”
    • 🧩 五、Planning 幻觉 & 粒度问题,在 LangGraph 里怎么回答?
      • 5.1 幻觉问题:把“下一步去哪”从 LLM 里拿出来
      • 5.2 粒度问题:用节点粒度来“锁”规划粒度
    • 🎤 六、面经角度:围绕 LangGraph + Multi-Agent 怎么吹?
    • ✅ 七、小结
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档