与LangGraph集成
LangChain代理与LangGraph的关系
LangChain的create_agent函数实际上是基于LangGraph构建的。理解这个关系对于构建复杂应用很重要。
LangChain层(高级抽象)
↑
create_agent()
↓
LangGraph层(低级编排)
↓
执行引擎
何时迁移到LangGraph
迁移条件
场景1:需要复杂的条件逻辑
# ❌ LangChain 难以表达
# 如果用户说"转账",需要进行复杂的条件检查:
# - 检查余额
# - 验证收款人
# - 审查过去的转账历史
# - 根据金额进行不同级别的审批
# ✅ 使用LangGraph更清晰
from langgraph.graph import StateGraph
def should_require_approval(state):
amount = state["transfer_amount"]
return amount > 5000
graph = StateGraph(CommandState)
graph.add_conditional_edges(
"validate_transfer",
should_require_approval,
{
True: "approve",
False: "execute"
}
)
场景2:需要并行处理
# ❌ LangChain 顺序执行
# 代理一次处理一个任务
# ✅ LangGraph 支持并行
from langgraph.graph import StateGraph
# 并行执行多个工具
def parallel_research(state):
# 同时调用多个搜索工具
pass
场景3:需要循环或自定义流程
# ❌ LangChain 固定的代理循环
# ✅ LangGraph 自定义循环
graph.add_edge("step1", "step2")
graph.add_edge("step2", "decision_point")
graph.add_conditional_edges(
"decision_point",
routing_function,
{
"continue": "step3",
"retry": "step1",
"end": END
}
)
从LangChain迁移到LangGraph
1. 简单的代理转换
LangChain版本:
agent = create_agent(
model="anthropic:claude-sonnet-4",
tools=[get_weather, get_forecast],
system_prompt="你是天气助手"
)
result = agent.invoke({
"messages": [{"role": "user", "content": "明天天气?"}]
})
LangGraph等价版本:
from langgraph.graph import StateGraph, MessagesState, START, END
from langchain_anthropic import ChatAnthropic
llm = ChatAnthropic(model="claude-sonnet-4")
llm_with_tools = llm.bind_tools([get_weather, get_forecast])
def model_node(state: MessagesState):
messages = state["messages"]
response = llm_with_tools.invoke(messages)
return {"messages": [response]}
def should_continue(state: MessagesState):
messages = state["messages"]
last_message = messages[-1]
if hasattr(last_message, "tool_calls") and last_message.tool_calls:
return "tools"
return END
def tool_node(state: MessagesState):
messages = state["messages"]
last_message = messages[-1]
tool_results = []
for tool_call in last_message.tool_calls:
tool_name = tool_call["name"]
tool_input = tool_call["args"]
# 执行工具
result = tools_dict[tool_name].invoke(tool_input)
tool_results.append({
"type": "tool",
"content": result,
"tool_call_id": tool_call["id"],
"name": tool_name
})
return {"messages": tool_results}
# 构建图
graph = StateGraph(MessagesState)
graph.add_node("model", model_node)
graph.add_node("tools", tool_node)
graph.add_edge(START, "model")
graph.add_conditional_edges("model", should_continue, {
"tools": "tools",
END: END
})
graph.add_edge("tools", "model")
app = graph.compile()
result = app.invoke({
"messages": [{"role": "user", "content": "明天天气?"}]
})
2. 包装LangChain代理为LangGraph节点
from langgraph.graph import StateGraph, START, END
from typing import TypedDict
class AgentState(TypedDict):
question: str
result: str
# 使用LangChain代理
langchain_agent = create_agent(
model="anthropic:claude-sonnet-4",
tools=[...]
)
def agent_node(state: AgentState):
"""将LangChain代理包装为LangGraph节点"""
result = langchain_agent.invoke({
"messages": [{"role": "user", "content": state["question"]}]
})
return {
"result": result["messages"][-1]["content"]
}
# 在LangGraph中使用
graph = StateGraph(AgentState)
graph.add_node("agent", agent_node)
graph.add_edge(START, "agent")
graph.add_edge("agent", END)
app = graph.compile()