04. AI Agent 开发入门¶
一句话说明:AI Agent(智能体)是能"自己思考、自己决定用什么工具、自己执行多步任务"的 AI 程序——不再只是一问一答,而是像一个能干活的实习生。
目录¶
- 为什么要学
- 核心概念(白话版)
- 主流 Agent 框架对比
- 实操教程:用 LangGraph 搭建 Agent
- 给 Agent 添加工具
- 多 Agent 协作入门
- 生信场景的 Agent 应用
- 常见报错与解决方案
- 速查表
- 延伸学习资源
1. 为什么要学¶
Agent 能做什么¶
| 普通 LLM 对话 | Agent |
|---|---|
| 你问一句,它答一句 | 你给一个目标,它自己拆分步骤、调用工具、迭代完成 |
| 不能联网、不能操作文件 | 能搜索、能读写文件、能执行代码 |
| 一次性回答,没有"记忆" | 有记忆,能记住对话上下文和历史结果 |
| 遇到不会的就瞎编 | 遇到不会的会去查资料、调用工具获取真实信息 |
白话比方: - 普通 LLM = 只会聊天的客服(你问什么它答什么,但它不能帮你真正干活) - Agent = 能干活的实习生(你说"帮我分析这批测序数据",它会自己找数据、跑命令、整理结果)
面试为什么加分¶
- 2025-2026 年 AI 领域最热方向,几乎所有 AI 岗位都在问
- 生信 + AI 岗位越来越看重"能不能用 AI 自动化分析流程"
- 体现你不只是"会用 ChatGPT",而是"能开发 AI 应用"
2. 核心概念(白话版)¶
2.1 Agent 是什么¶
正式定义:Agent 是一个以 LLM 为"大脑",能自主规划任务、调用外部工具、根据反馈调整行为的智能程序。
白话:Agent 就是"会自己想办法完成任务的 AI"。你给它一个目标,它自己想该怎么做、用什么工具、做完一步再想下一步。
普通 LLM:你 → 问题 → AI → 答案(一来一回就结束)
Agent:你 → 目标 → AI 思考 → 调用工具 → 看结果 → 再思考 → 再调用 → ... → 最终答案
2.2 Tool(工具调用)¶
白话:Tool 就是 Agent 的"手脚"。LLM 本身只会"想"(生成文字),Tool 让它能"做"(搜索、计算、读文件、调 API)。
常见工具举例:
| 工具 | 作用 | 生信举例 |
|---|---|---|
| 搜索工具 | 联网搜索信息 | 搜索最新的 MetaPhlAn 版本号 |
| 代码执行 | 运行 Python/Shell | 跑 FastQC 质控命令 |
| 文件读写 | 读取/保存文件 | 读取质控报告、保存分析结果 |
| 数据库查询 | 查 SQL/API | 查 NCBI 数据库获取基因注释 |
| 计算器 | 数学计算 | 计算 Shannon 多样性指数 |
2.3 ReAct 模式(思考-行动-观察循环)¶
ReAct = Reasoning + Acting,是目前最主流的 Agent 工作模式。
白话:Agent 工作时像人一样"想一想 → 做一做 → 看看结果 → 再想想",不断循环直到完成任务。
循环过程:
┌─────────────────────────────────────────────┐
│ Thought(思考): 我需要先查看文件内容 │
│ ↓ │
│ Action(行动): 调用文件读取工具 │
│ ↓ │
│ Observation(观察): 文件内容是 xxx │
│ ↓ │
│ Thought(思考): 根据内容,下一步应该... │
│ ↓ │
│ Action(行动): 调用计算工具 │
│ ↓ │
│ Observation(观察): 计算结果是 yyy │
│ ↓ │
│ Final Answer(最终答案): 分析完成,结论是...│
└─────────────────────────────────────────────┘
白话比方:就像做实验——先想实验方案,然后做实验,看结果,再调整方案,再做……直到得到满意的结果。
2.4 Memory(记忆)¶
Agent 的记忆分两种:
| 类型 | 白话 | 举例 |
|---|---|---|
| 短期记忆 | 当前对话中的上下文 | 记住用户 5 分钟前说的"分析 T2D 数据" |
| 长期记忆 | 跨对话的持久存储 | 记住用户偏好"喜欢用 conda 环境" |
白话比方:短期记忆 = 你正在讨论的话题(聊完就忘),长期记忆 = 你的笔记本(随时翻看)。
2.5 Planning(规划)¶
白话:给 Agent 一个复杂任务时,它会先"列计划"再执行——像写论文前先列大纲。
规划能力让 Agent 能处理复杂任务:
用户: "帮我分析这批宏基因组数据的物种多样性"
Agent 的内部规划:
1. 先检查数据格式(fastq? fasta?)
2. 做质控(fastp 过滤低质量序列)
3. 物种注释(MetaPhlAn 或 Kraken2)
4. 计算多样性指数(Shannon、Simpson)
5. 可视化(画柱状图和热图)
6. 生成报告
3. 主流 Agent 框架对比¶
框架概览(2026年5月数据)¶
| 框架 | GitHub Stars | 定位 | 难度 | 适合场景 |
|---|---|---|---|---|
| LangGraph | 31,000+ | 底层图编排框架 | ⭐⭐⭐ 中 | 需要精细控制流程的复杂 Agent |
| CrewAI | 50,000+ | 多 Agent 协作框架 | ⭐⭐ 低 | 多角色协作、快速搭建 |
| AutoGen | 57,000+ | 微软出品,多 Agent 对话 | ⭐⭐⭐ 中 | 研究场景、多 Agent 讨论 |
| 直接用 API | - | 手写所有逻辑 | ⭐⭐⭐⭐ 高 | 极简场景、学习原理 |
详细对比¶
LangGraph(推荐入门)¶
优点:
- LangChain 官方出品,你已经学过 LangChain,上手最快
- 用"图"来定义 Agent 流程,可视化强
- 支持持久化、人工介入、复杂流程控制
- 文档丰富,社区活跃
缺点:
- 概念多(State、Node、Edge、Conditional Edge...)
- 对简单场景可能"杀鸡用牛刀"
CrewAI¶
优点:
- 用"角色扮演"方式定义 Agent,直觉上最好理解
- 多 Agent 协作开箱即用
- 代码量少,5 分钟就能跑起来
- 完全独立于 LangChain,轻量
缺点:
- 底层控制力不如 LangGraph
- 复杂流程定制性有限
- 企业特性需要付费
AutoGen(微软)¶
优点:
- 微软背书,研究导向
- 多 Agent 对话模式独特
- 支持代码执行和人工参与
缺点:
- 2025年经历了 v0.4 大重构,API 变化大
- 文档更新慢,网上教程版本混乱
- 不推荐新手第一个学
直接用 API¶
# 最原始的方式:自己写循环调用 OpenAI API
# 优点:完全理解原理
# 缺点:要自己处理所有细节(记忆、工具解析、错误处理...)
选择建议¶
你的情况(已学 LangChain,想快速入门):
推荐路线:LangGraph → CrewAI → 了解 AutoGen
理由:
1. LangGraph 和 LangChain 一脉相承,知识复用最多
2. CrewAI 适合快速搭建多 Agent 原型
3. AutoGen 了解概念即可,面试能说出来就行
4. 实操教程:用 LangGraph 搭建 Agent¶
4.1 环境准备¶
# 激活 conda 环境(用你已有的 t2d_ml 环境,或新建一个)
conda activate t2d_ml
# 安装 LangGraph(会自动安装 langchain-core 依赖)
pip install langgraph langchain-openai langchain-community
# 如果用本地 Ollama 模型(省钱方案)
pip install langchain-ollama
4.2 最简 Agent:一个能搜索的助手¶
"""
文件: simple_agent.py
功能: 用 LangGraph 搭建一个最简单的 Agent(带搜索工具)
前置: 需要 OPENAI_API_KEY 或本地 Ollama 模型
"""
# ============ 1. 导入必要的库 ============
from typing import Annotated # 类型标注,Python 内置
from typing_extensions import TypedDict # 类型字典
from langgraph.graph import StateGraph, START, END # LangGraph 核心:图、开始节点、结束节点
from langgraph.graph.message import add_messages # 消息累加器(把新消息追加到列表)
from langchain_openai import ChatOpenAI # OpenAI 模型接口
from langchain_core.messages import HumanMessage, AIMessage # 消息类型
# ============ 2. 定义 State(状态)============
# 白话:State 就是 Agent 的"工作记录本",存储所有中间信息
class State(TypedDict):
# messages 存储对话历史
# Annotated[list, add_messages] 意思是:每次更新时,把新消息追加到列表尾部
messages: Annotated[list, add_messages]
# ============ 3. 初始化 LLM ============
# 方案 A:用 OpenAI API(需要 key,效果好)
llm = ChatOpenAI(
model="gpt-4o-mini", # 便宜又好用的模型
temperature=0, # 0 表示确定性回答,不随机
)
# 方案 B:用本地 Ollama(免费,隐私好)
# from langchain_ollama import ChatOllama
# llm = ChatOllama(model="qwen2.5:7b", temperature=0)
# ============ 4. 定义节点函数 ============
# 白话:节点 = Agent 流程中的"一站"
def chatbot(state: State):
"""聊天节点:把当前消息历史发给 LLM,获取回复"""
response = llm.invoke(state["messages"]) # 调用 LLM
return {"messages": [response]} # 返回新消息(会自动追加到 state 里)
# ============ 5. 构建图(Graph)============
# 白话:图 = Agent 的"流程图",定义节点和节点之间的连线
graph_builder = StateGraph(State) # 创建图,指定状态结构
# 添加节点
graph_builder.add_node("chatbot", chatbot) # 添加聊天节点
# 添加边(连线)
graph_builder.add_edge(START, "chatbot") # 开始 → 聊天
graph_builder.add_edge("chatbot", END) # 聊天 → 结束
# 编译图(类似于"保存并运行")
graph = graph_builder.compile()
# ============ 6. 运行 Agent ============
if __name__ == "__main__":
# 用户输入
user_input = "什么是宏基因组?用一句话解释"
# 调用 Agent
result = graph.invoke({
"messages": [HumanMessage(content=user_input)]
})
# 打印最后一条消息(即 AI 的回复)
print(result["messages"][-1].content)
4.3 运行结果¶
python simple_agent.py
# 输出类似:宏基因组是直接从环境样本中提取所有微生物的DNA进行测序分析的技术,
# 不需要逐个培养微生物。
4.4 理解 LangGraph 核心概念¶
LangGraph 三要素:
1. State(状态)= 工作记录本
- 存储 Agent 运行过程中的所有信息
- 每个节点都能读写 State
2. Node(节点)= 流程中的"一站"
- 每个节点是一个函数,接收 State,返回更新
- 比如:chatbot 节点、tool 节点、判断节点
3. Edge(边)= 节点之间的连线
- 普通边:A → B(固定走向)
- 条件边:根据条件决定走哪条路(比如:需要工具?→ 走工具节点;不需要?→ 结束)
5. 给 Agent 添加工具¶
5.1 定义工具¶
"""
文件: agent_with_tools.py
功能: 给 Agent 添加搜索、计算、文件读取三个工具
"""
from typing import Annotated
from typing_extensions import TypedDict
from langgraph.graph import StateGraph, START, END
from langgraph.graph.message import add_messages
from langgraph.prebuilt import ToolNode, tools_condition # 预置的工具节点和条件判断
from langchain_openai import ChatOpenAI
from langchain_core.tools import tool # 工具装饰器
from langchain_core.messages import HumanMessage
import math
# ============ 1. 定义工具 ============
@tool
def search_pubmed(query: str) -> str:
"""搜索 PubMed 数据库查找相关论文。
(白话:让 Agent 能搜论文)
Args:
query: 搜索关键词,如 'gut microbiome T2D'
"""
# 实际项目中这里会调用 PubMed API
# 这里用模拟数据演示
return f"搜索到关于 '{query}' 的 3 篇论文:\n1. Gut microbiome and T2D (Nature, 2024)\n2. Metagenomic analysis of diabetic patients (Cell, 2023)\n3. Probiotics intervention in T2D (Lancet, 2024)"
@tool
def calculator(expression: str) -> str:
"""计算数学表达式。
(白话:让 Agent 能做数学计算)
Args:
expression: 数学表达式,如 '2+3' 或 'math.log2(8)'
"""
try:
result = eval(expression, {"math": math, "__builtins__": {}}) # 安全地执行数学计算
return f"计算结果: {result}"
except Exception as e:
return f"计算错误: {e}"
@tool
def read_file(filepath: str) -> str:
"""读取本地文件内容。
(白话:让 Agent 能看文件)
Args:
filepath: 文件路径
"""
try:
with open(filepath, 'r', encoding='utf-8') as f:
content = f.read()[:2000] # 只读前 2000 字符,防止太长
return f"文件内容:\n{content}"
except FileNotFoundError:
return f"文件不存在: {filepath}"
except Exception as e:
return f"读取错误: {e}"
# ============ 2. 把工具绑定到 LLM ============
tools = [search_pubmed, calculator, read_file] # 工具列表
llm = ChatOpenAI(model="gpt-4o-mini", temperature=0)
llm_with_tools = llm.bind_tools(tools) # 关键!告诉 LLM 它可以用这些工具
# ============ 3. 定义 State 和节点 ============
class State(TypedDict):
messages: Annotated[list, add_messages]
def chatbot(state: State):
"""聊天节点:LLM 决定是回答还是调用工具"""
response = llm_with_tools.invoke(state["messages"])
return {"messages": [response]}
# ============ 4. 构建带工具的图 ============
graph_builder = StateGraph(State)
# 添加节点
graph_builder.add_node("chatbot", chatbot) # 聊天/决策节点
graph_builder.add_node("tools", ToolNode(tools)) # 工具执行节点(预置的,自动处理工具调用)
# 添加边
graph_builder.add_edge(START, "chatbot") # 开始 → 聊天
# 关键:条件边!chatbot 之后,根据是否需要工具决定走向
# tools_condition 会检查 LLM 的回复中是否包含工具调用请求
graph_builder.add_conditional_edges(
"chatbot", # 从哪个节点出发
tools_condition, # 条件函数(LangGraph 预置的)
# 如果需要工具 → 走 "tools" 节点
# 如果不需要 → 走 END(结束)
)
graph_builder.add_edge("tools", "chatbot") # 工具执行完 → 回到聊天(让 LLM 看结果,决定下一步)
# 编译
graph = graph_builder.compile()
# ============ 5. 运行 ============
if __name__ == "__main__":
# 测试 1:需要搜索的问题
print("=" * 50)
print("测试: 搜索论文")
result = graph.invoke({
"messages": [HumanMessage(content="帮我搜一下关于肠道菌群和2型糖尿病的最新论文")]
})
print(result["messages"][-1].content)
# 测试 2:需要计算的问题
print("\n" + "=" * 50)
print("测试: 计算 Shannon 指数")
result = graph.invoke({
"messages": [HumanMessage(content="帮我算一下 Shannon 多样性指数,三个物种的相对丰度分别是 0.5, 0.3, 0.2")]
})
print(result["messages"][-1].content)
5.2 工作流程图解¶
用户提问
↓
┌─────────┐ 需要工具 ┌──────────┐
│ chatbot │ ───────────────→ │ tools │
│(LLM) │ ←─────────────── │(执行) │
└─────────┘ 返回结果 └──────────┘
↓ 不需要工具
┌─────────┐
│ END │
└─────────┘
ReAct 循环体现在:
chatbot → tools → chatbot → tools → ... → chatbot → END
(思考) (行动) (观察+再思考)(再行动) (最终回答)
6. 多 Agent 协作入门¶
6.1 为什么需要多 Agent¶
单个 Agent 处理复杂任务时容易"跑偏"。多 Agent 的思路是:让不同 Agent 各司其职。
白话比方:一个人写论文容易出错,但如果有"文献搜索员 + 数据分析员 + 写作员"三人合作,效率更高、质量更好。
6.2 用 CrewAI 实现多 Agent(最简方案)¶
"""
文件: multi_agent_crew.py
功能: 用 CrewAI 搭建一个"生信论文分析小组"
安装: pip install crewai crewai-tools
"""
from crewai import Agent, Task, Crew, Process
# ============ 1. 定义 Agent(角色)============
# Agent 1:文献搜索专家
searcher = Agent(
role="文献搜索专家", # 角色名称
goal="搜索并总结与用户问题相关的最新论文", # 目标
backstory="你是一位经验丰富的生物信息学研究员,擅长在 PubMed 和 Google Scholar 上快速定位高质量论文。", # 背景故事(帮助 LLM 进入角色)
verbose=True, # 打印详细过程
allow_delegation=False, # 不允许把任务转给别人
)
# Agent 2:数据分析专家
analyst = Agent(
role="生信数据分析专家",
goal="分析实验数据并给出统计学结论",
backstory="你是一位资深生信分析师,精通 Python、R、统计学和各种组学分析流程。",
verbose=True,
allow_delegation=False,
)
# Agent 3:报告撰写专家
writer = Agent(
role="科研报告撰写专家",
goal="将分析结果整理成清晰的中文报告",
backstory="你擅长将复杂的科研结果用简洁准确的语言表达,让非专业人士也能理解。",
verbose=True,
allow_delegation=False,
)
# ============ 2. 定义任务 ============
# 任务 1:搜索文献
search_task = Task(
description="搜索关于'肠道菌群与2型糖尿病关系'的最新研究进展,重点关注 2023-2024 年的 meta-analysis 和队列研究。总结 3-5 篇核心论文的关键发现。",
expected_output="一份包含 3-5 篇核心论文摘要和关键发现的列表",
agent=searcher, # 分配给搜索专家
)
# 任务 2:分析数据
analysis_task = Task(
description="基于搜索到的文献,分析目前该领域的共识和争议点。识别哪些菌属被多次报道为 T2D 相关,哪些结论还有争议。",
expected_output="一份分析报告,列出共识菌属、争议点和潜在的研究方向",
agent=analyst,
)
# 任务 3:写报告
report_task = Task(
description="综合文献搜索和数据分析的结果,撰写一份 500 字左右的中文综述报告,适合在面试中用 2 分钟口头介绍。",
expected_output="一份结构清晰的中文报告(背景→方法→发现→结论→展望)",
agent=writer,
)
# ============ 3. 组建 Crew 并执行 ============
crew = Crew(
agents=[searcher, analyst, writer], # 团队成员
tasks=[search_task, analysis_task, report_task], # 任务列表(按顺序执行)
process=Process.sequential, # 顺序执行(一个接一个)
verbose=True, # 打印过程
)
# 运行
if __name__ == "__main__":
result = crew.kickoff() # 启动!
print("\n" + "=" * 60)
print("最终报告:")
print("=" * 60)
print(result)
6.3 用 LangGraph 实现多 Agent(进阶)¶
"""
文件: multi_agent_langgraph.py
功能: 用 LangGraph 实现两个 Agent 协作(Supervisor 模式)
说明: Supervisor(管理者)负责调度,Worker(工人)负责执行
"""
from typing import Annotated, Literal
from typing_extensions import TypedDict
from langgraph.graph import StateGraph, START, END
from langgraph.graph.message import add_messages
from langchain_openai import ChatOpenAI
from langchain_core.messages import HumanMessage, SystemMessage
# ============ State ============
class State(TypedDict):
messages: Annotated[list, add_messages]
next_agent: str # 下一个该谁干活
# ============ LLM ============
llm = ChatOpenAI(model="gpt-4o-mini", temperature=0)
# ============ Supervisor 节点 ============
def supervisor(state: State):
"""管理者:决定下一步让谁干活"""
system_prompt = """你是一个任务管理者。根据对话内容,决定下一步应该交给谁:
- "researcher": 需要搜索信息或查阅文献
- "coder": 需要写代码或分析数据
- "FINISH": 任务已完成,可以输出最终结果
只回复一个词:researcher、coder 或 FINISH"""
response = llm.invoke([
SystemMessage(content=system_prompt),
*state["messages"]
])
next_step = response.content.strip().lower()
# 确保返回有效值
if "researcher" in next_step:
next_step = "researcher"
elif "coder" in next_step:
next_step = "coder"
else:
next_step = "FINISH"
return {"next_agent": next_step, "messages": [response]}
# ============ Worker 节点 ============
def researcher(state: State):
"""研究者 Agent:负责搜索和文献调研"""
system_prompt = "你是一个生信领域的文献研究专家。根据用户需求搜索和总结相关信息。"
response = llm.invoke([
SystemMessage(content=system_prompt),
*state["messages"]
])
return {"messages": [response]}
def coder(state: State):
"""编程者 Agent:负责写代码和数据分析"""
system_prompt = "你是一个生信编程专家,擅长 Python 和 R。根据需求编写分析代码。"
response = llm.invoke([
SystemMessage(content=system_prompt),
*state["messages"]
])
return {"messages": [response]}
# ============ 构建图 ============
def route_next(state: State) -> Literal["researcher", "coder", "__end__"]:
"""条件路由:根据 supervisor 的决定走不同路径"""
if state["next_agent"] == "researcher":
return "researcher"
elif state["next_agent"] == "coder":
return "coder"
else:
return "__end__" # LangGraph 内置的结束标记
graph_builder = StateGraph(State)
# 添加节点
graph_builder.add_node("supervisor", supervisor)
graph_builder.add_node("researcher", researcher)
graph_builder.add_node("coder", coder)
# 添加边
graph_builder.add_edge(START, "supervisor")
graph_builder.add_conditional_edges("supervisor", route_next)
graph_builder.add_edge("researcher", "supervisor") # 研究完回到 supervisor
graph_builder.add_edge("coder", "supervisor") # 编程完回到 supervisor
graph = graph_builder.compile()
7. 生信场景的 Agent 应用¶
7.1 自动化分析 Pipeline Agent¶
"""
场景:用 Agent 自动执行宏基因组分析流程
思路:Agent 根据数据状态,自动决定下一步该跑什么
"""
@tool
def run_fastp(input_file: str) -> str:
"""运行 fastp 质控。Agent 判断数据需要质控时会调用此工具。"""
import subprocess
cmd = f"fastp -i {input_file} -o clean_{input_file} --html report.html"
# result = subprocess.run(cmd, shell=True, capture_output=True)
return f"质控完成:clean_{input_file},报告:report.html"
@tool
def run_metaphlan(input_file: str) -> str:
"""运行 MetaPhlAn 物种注释。"""
cmd = f"metaphlan {input_file} --input_type fastq -o profile.txt"
return f"物种注释完成:profile.txt"
@tool
def run_humann(input_file: str) -> str:
"""运行 HUMAnN 功能注释。"""
cmd = f"humann --input {input_file} --output humann_results/"
return f"功能注释完成:humann_results/"
@tool
def generate_report(result_dir: str) -> str:
"""生成分析报告。"""
return f"分析报告已生成:{result_dir}/final_report.html"
# 使用方式(伪代码):
# 用户说:"帮我分析 sample1.fastq.gz 的宏基因组数据"
# Agent 会自动规划:质控 → 物种注释 → 功能注释 → 生成报告
7.2 论文检索 Agent¶
"""
场景:一个能自动搜索、筛选、总结论文的 Agent
实际很有用:面试前快速了解某个领域的最新进展
"""
@tool
def search_papers(query: str, year_from: int = 2023) -> str:
"""在 PubMed 搜索论文,返回标题和摘要"""
# 实际实现:用 Biopython 的 Entrez 模块
from Bio import Entrez
Entrez.email = "your@email.com"
handle = Entrez.esearch(db="pubmed", term=query, retmax=5, mindate=str(year_from))
# ... 解析结果
return "搜索结果..."
@tool
def summarize_paper(pmid: str) -> str:
"""获取论文全文摘要并生成中文总结"""
# 获取摘要 → LLM 总结
return "论文总结..."
@tool
def compare_methods(papers: str) -> str:
"""对比多篇论文的方法和结论"""
return "对比分析..."
# Agent 使用场景:
# "帮我查一下 2024 年关于肠道菌群-脑轴的最新 meta-analysis,
# 对比它们的样本量和主要结论"
7.3 面试中怎么说¶
"我用 LangGraph 搭建了一个生信分析 Agent,它能根据输入数据的格式和质量,自动决定执行质控、物种注释还是功能注释,相当于把传统的 Snakemake 流程变成了一个能自主决策的智能流水线。"
8. 常见报错与解决方案¶
报错 1:openai.AuthenticationError: Incorrect API key¶
原因:API Key 没设置或者过期了
解决:
export OPENAI_API_KEY="sk-your-key-here" # Linux/Mac
# 或者在代码里直接传
llm = ChatOpenAI(api_key="sk-xxx", model="gpt-4o-mini")
# 省钱方案:改用本地 Ollama,完全免费
报错 2:RecursionError: maximum recursion depth exceeded¶
原因:Agent 陷入了死循环(工具调用后又调工具,无限循环)
解决:给图设置 recursion_limit(最大循环次数)
graph = graph_builder.compile()
result = graph.invoke(inputs, config={"recursion_limit": 25})
报错 3:ToolException: Tool 'xxx' not found¶
原因:LLM 试图调用一个你没定义的工具
解决:
1. 检查 bind_tools() 是否包含了所有工具
2. 检查工具名称是否有 typo
3. 在 system prompt 里明确告诉 LLM 可用的工具列表
报错 4:InvalidRequestError: max tokens exceeded¶
原因:对话历史太长,超出了模型上下文窗口
解决:
1. 添加消息裁剪(只保留最近 N 条)
from langchain_core.messages import trim_messages
trimmer = trim_messages(max_tokens=4000, strategy="last")
2. 或者用 summarize 策略(把旧消息总结成一段话)
报错 5:GraphRecursionError: Recursion limit of 25 reached¶
原因:Agent 的 ReAct 循环超过了最大次数还没结束
解决:
1. 提高 recursion_limit(但要小心,可能是 prompt 有问题)
2. 改进 system prompt,让 LLM 更果断地给出最终答案
3. 添加一个"兜底节点":循环 N 次后强制结束
报错 6:ImportError: cannot import name 'ToolNode' from 'langgraph.prebuilt'¶
原因:langgraph 版本太低
解决:
pip install --upgrade langgraph
# 确保版本 >= 0.2.0(2026年最新是 0.4.x)
pip show langgraph # 查看当前版本
报错 7:pydantic.ValidationError: 1 validation error for Tool¶
原因:@tool 装饰器的函数缺少 docstring 或参数类型标注
解决:每个 @tool 函数必须有:
1. 类型标注(def func(query: str) -> str:)
2. docstring("""功能说明""")
3. Args 说明(在 docstring 中用 Args: 格式)
9. 速查表¶
LangGraph 核心 API¶
| 代码 | 作用 | 白话 |
|---|---|---|
StateGraph(State) |
创建状态图 | 创建一个空流程图 |
.add_node("name", func) |
添加节点 | 在流程图上画一个站 |
.add_edge(A, B) |
添加普通边 | 画一条 A→B 的线 |
.add_conditional_edges(A, func) |
添加条件边 | A 之后根据条件走不同路 |
.compile() |
编译图 | 保存流程图,准备运行 |
graph.invoke(input) |
运行图 | 启动 Agent |
ToolNode(tools) |
工具执行节点 | 一个能自动运行工具的节点 |
tools_condition |
工具条件判断 | 判断 LLM 是否想调用工具 |
@tool |
工具装饰器 | 把函数变成 Agent 能用的工具 |
llm.bind_tools(tools) |
绑定工具 | 告诉 LLM 它有哪些工具可用 |
Agent 设计模式¶
| 模式 | 适用场景 | 复杂度 |
|---|---|---|
| 单 Agent + 工具 | 简单任务,一个角色能搞定 | 低 |
| Supervisor 模式 | 多角色协作,需要统一调度 | 中 |
| 对等协作 | Agent 之间平等讨论 | 中 |
| 层级模式 | 大型复杂任务,多层管理 | 高 |
框架选择速查¶
| 需求 | 推荐框架 |
|---|---|
| 精细控制流程 | LangGraph |
| 快速搭建多 Agent | CrewAI |
| 研究 / 论文复现 | AutoGen |
| 学习原理 | 直接用 API |
| 生产部署 | LangGraph + LangSmith |
常用命令¶
# 安装
pip install langgraph langchain-openai langchain-community
pip install crewai crewai-tools
pip install pyautogen
# 环境变量
export OPENAI_API_KEY="sk-xxx"
export TAVILY_API_KEY="tvly-xxx" # 搜索工具需要
# 检查版本
pip show langgraph # 当前推荐 >= 0.4.0
pip show crewai # 当前推荐 >= 0.100.0
10. 延伸学习资源¶
官方文档(首选)¶
| 资源 | 链接 | 说明 |
|---|---|---|
| LangGraph 官方文档 | docs.langchain.com | 最权威,有中文社区翻译 |
| LangChain Academy | academy.langchain.com | 免费课程,LangGraph 入门最佳 |
| CrewAI 文档 | docs.crewai.com | 多 Agent 入门 |
| AutoGen 文档 | microsoft.github.io/autogen | 了解微软方案 |
GitHub 仓库¶
| 仓库 | Stars | 说明 |
|---|---|---|
| langchain-ai/langgraph | 31K+ | LangGraph 源码和示例 |
| crewAIInc/crewAI | 50K+ | CrewAI 框架 |
| microsoft/autogen | 57K+ | 微软 AutoGen |
| langchain-ai/deepagents | 新! | 能规划、能用子 Agent 的深度 Agent |
推荐学习路线¶
第 1 周:理解概念 + 跑通 LangGraph 基础示例
↓
第 2 周:给 Agent 加工具 + 实现 ReAct 循环
↓
第 3 周:多 Agent 协作(CrewAI 快速搭建)
↓
第 4 周:结合生信场景,搭建自己的分析 Agent
面试高频问题预备¶
- "什么是 AI Agent?" → 以 LLM 为大脑、能自主规划和使用工具完成任务的程序
- "Agent 和 RAG 的区别?" → RAG 只是"查了再答",Agent 能"想-做-看-再想"循环完成复杂任务
- "ReAct 是什么?" → Reasoning + Acting,让 LLM 在思考和行动之间交替的框架
- "你用 Agent 做过什么?" → 用 LangGraph 搭建了宏基因组自动分析 Agent,能自动质控→注释→报告
- "多 Agent 有什么好处?" → 各司其职,降低单个 Agent 的复杂度,提高结果质量
总结:Agent 是 2025-2026 年 AI 最火的方向。你已经学了 LangChain,再学 LangGraph 搭 Agent 是自然的下一步。核心就是:让 AI 不只是"聊天",而是能"干活"。