langgraph
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseLangGraph
LangGraph
Role: LangGraph Agent Architect
You are an expert in building production-grade AI agents with LangGraph. You
understand that agents need explicit structure - graphs make the flow visible
and debuggable. You design state carefully, use reducers appropriately, and
always consider persistence for production. You know when cycles are needed
and how to prevent infinite loops.
角色:LangGraph Agent架构师
您是使用LangGraph构建生产级AI Agent的专家。您明白Agent需要明确的结构——图可以让流程可视化且易于调试。您会谨慎设计状态,合理使用reducer,并始终考虑生产环境下的持久化。您清楚何时需要循环以及如何防止无限循环。
Capabilities
能力
- Graph construction (StateGraph)
- State management and reducers
- Node and edge definitions
- Conditional routing
- Checkpointers and persistence
- Human-in-the-loop patterns
- Tool integration
- Streaming and async execution
- 图构建(StateGraph)
- 状态管理与reducer
- 节点与边定义
- 条件路由
- 检查点与持久化
- 人机协作模式
- 工具集成
- 流式与异步执行
Requirements
要求
- Python 3.9+
- langgraph package
- LLM API access (OpenAI, Anthropic, etc.)
- Understanding of graph concepts
- Python 3.9+
- langgraph包
- LLM API访问权限(OpenAI、Anthropic等)
- 具备图概念相关知识
Patterns
模式
Basic Agent Graph
基础Agent图
Simple ReAct-style agent with tools
When to use: Single agent with tool calling
python
from typing import Annotated, TypedDict
from langgraph.graph import StateGraph, START, END
from langgraph.graph.message import add_messages
from langgraph.prebuilt import ToolNode
from langchain_openai import ChatOpenAI
from langchain_core.tools import tool带工具的简单ReAct风格Agent
适用场景:带工具调用的单Agent
python
from typing import Annotated, TypedDict
from langgraph.graph import StateGraph, START, END
from langgraph.graph.message import add_messages
from langgraph.prebuilt import ToolNode
from langchain_openai import ChatOpenAI
from langchain_core.tools import tool1. Define State
1. Define State
class AgentState(TypedDict):
messages: Annotated[list, add_messages]
# add_messages reducer appends, doesn't overwrite
class AgentState(TypedDict):
messages: Annotated[list, add_messages]
# add_messages reducer appends, doesn't overwrite
2. Define Tools
2. Define Tools
@tool
def search(query: str) -> str:
"""Search the web for information."""
# Implementation here
return f"Results for: {query}"
@tool
def calculator(expression: str) -> str:
"""Evaluate a math expression."""
return str(eval(expression))
tools = [search, calculator]
@tool
def search(query: str) -> str:
"""Search the web for information."""
# Implementation here
return f"Results for: {query}"
@tool
def calculator(expression: str) -> str:
"""Evaluate a math expression."""
return str(eval(expression))
tools = [search, calculator]
3. Create LLM with tools
3. Create LLM with tools
llm = ChatOpenAI(model="gpt-4o").bind_tools(tools)
llm = ChatOpenAI(model="gpt-4o").bind_tools(tools)
4. Define Nodes
4. Define Nodes
def agent(state: AgentState) -> dict:
"""The agent node - calls LLM."""
response = llm.invoke(state["messages"])
return {"messages": [response]}
def agent(state: AgentState) -> dict:
"""The agent node - calls LLM."""
response = llm.invoke(state["messages"])
return {"messages": [response]}
Tool node handles tool execution
Tool node handles tool execution
tool_node = ToolNode(tools)
tool_node = ToolNode(tools)
5. Define Routing
5. Define Routing
def should_continue(state: AgentState) -> str:
"""Route based on whether tools were called."""
last_message = state["messages"][-1]
if last_message.tool_calls:
return "tools"
return END
def should_continue(state: AgentState) -> str:
"""Route based on whether tools were called."""
last_message = state["messages"][-1]
if last_message.tool_calls:
return "tools"
return END
6. Build Graph
6. Build Graph
graph = StateGraph(AgentState)
graph = StateGraph(AgentState)
Add nodes
Add nodes
graph.add_node("agent", agent)
graph.add_node("tools", tool_node)
graph.add_node("agent", agent)
graph.add_node("tools", tool_node)
Add edges
Add edges
graph.add_edge(START, "agent")
graph.add_conditional_edges("agent", should_continue, ["tools", END])
graph.add_edge("tools", "agent") # Loop back
graph.add_edge(START, "agent")
graph.add_conditional_edges("agent", should_continue, ["tools", END])
graph.add_edge("tools", "agent") # Loop back
Compile
Compile
app = graph.compile()
app = graph.compile()
7. Run
7. Run
result = app.invoke({
"messages": [("user", "What is 25 * 4?")]
})
undefinedresult = app.invoke({
"messages": [("user", "What is 25 * 4?")]
})
undefinedState with Reducers
带Reducer的状态管理
Complex state management with custom reducers
When to use: Multiple agents updating shared state
python
from typing import Annotated, TypedDict
from operator import add
from langgraph.graph import StateGraph使用自定义reducer的复杂状态管理
适用场景:多个Agent更新共享状态
python
from typing import Annotated, TypedDict
from operator import add
from langgraph.graph import StateGraphCustom reducer for merging dictionaries
Custom reducer for merging dictionaries
def merge_dicts(left: dict, right: dict) -> dict:
return {**left, **right}
def merge_dicts(left: dict, right: dict) -> dict:
return {**left, **right}
State with multiple reducers
State with multiple reducers
class ResearchState(TypedDict):
# Messages append (don't overwrite)
messages: Annotated[list, add_messages]
# Research findings merge
findings: Annotated[dict, merge_dicts]
# Sources accumulate
sources: Annotated[list[str], add]
# Current step (overwrites - no reducer)
current_step: str
# Error count (custom reducer)
errors: Annotated[int, lambda a, b: a + b]class ResearchState(TypedDict):
# Messages append (don't overwrite)
messages: Annotated[list, add_messages]
# Research findings merge
findings: Annotated[dict, merge_dicts]
# Sources accumulate
sources: Annotated[list[str], add]
# Current step (overwrites - no reducer)
current_step: str
# Error count (custom reducer)
errors: Annotated[int, lambda a, b: a + b]Nodes return partial state updates
Nodes return partial state updates
def researcher(state: ResearchState) -> dict:
# Only return fields being updated
return {
"findings": {"topic_a": "New finding"},
"sources": ["source1.com"],
"current_step": "researching"
}
def writer(state: ResearchState) -> dict:
# Access accumulated state
all_findings = state["findings"]
all_sources = state["sources"]
return {
"messages": [("assistant", f"Report based on {len(all_sources)} sources")],
"current_step": "writing"
}def researcher(state: ResearchState) -> dict:
# Only return fields being updated
return {
"findings": {"topic_a": "New finding"},
"sources": ["source1.com"],
"current_step": "researching"
}
def writer(state: ResearchState) -> dict:
# Access accumulated state
all_findings = state["findings"]
all_sources = state["sources"]
return {
"messages": [("assistant", f"Report based on {len(all_sources)} sources")],
"current_step": "writing"
}Build graph
Build graph
graph = StateGraph(ResearchState)
graph.add_node("researcher", researcher)
graph.add_node("writer", writer)
graph = StateGraph(ResearchState)
graph.add_node("researcher", researcher)
graph.add_node("writer", writer)
... add edges
... add edges
undefinedundefinedConditional Branching
条件分支
Route to different paths based on state
When to use: Multiple possible workflows
python
from langgraph.graph import StateGraph, START, END
class RouterState(TypedDict):
query: str
query_type: str
result: str
def classifier(state: RouterState) -> dict:
"""Classify the query type."""
query = state["query"].lower()
if "code" in query or "program" in query:
return {"query_type": "coding"}
elif "search" in query or "find" in query:
return {"query_type": "search"}
else:
return {"query_type": "chat"}
def coding_agent(state: RouterState) -> dict:
return {"result": "Here's your code..."}
def search_agent(state: RouterState) -> dict:
return {"result": "Search results..."}
def chat_agent(state: RouterState) -> dict:
return {"result": "Let me help..."}基于状态路由到不同路径
适用场景:存在多种可能的工作流
python
from langgraph.graph import StateGraph, START, END
class RouterState(TypedDict):
query: str
query_type: str
result: str
def classifier(state: RouterState) -> dict:
"""Classify the query type."""
query = state["query"].lower()
if "code" in query or "program" in query:
return {"query_type": "coding"}
elif "search" in query or "find" in query:
return {"query_type": "search"}
else:
return {"query_type": "chat"}
def coding_agent(state: RouterState) -> dict:
return {"result": "Here's your code..."}
def search_agent(state: RouterState) -> dict:
return {"result": "Search results..."}
def chat_agent(state: RouterState) -> dict:
return {"result": "Let me help..."}Routing function
Routing function
def route_query(state: RouterState) -> str:
"""Route to appropriate agent."""
query_type = state["query_type"]
return query_type # Returns node name
def route_query(state: RouterState) -> str:
"""Route to appropriate agent."""
query_type = state["query_type"]
return query_type # Returns node name
Build graph
Build graph
graph = StateGraph(RouterState)
graph.add_node("classifier", classifier)
graph.add_node("coding", coding_agent)
graph.add_node("search", search_agent)
graph.add_node("chat", chat_agent)
graph.add_edge(START, "classifier")
graph = StateGraph(RouterState)
graph.add_node("classifier", classifier)
graph.add_node("coding", coding_agent)
graph.add_node("search", search_agent)
graph.add_node("chat", chat_agent)
graph.add_edge(START, "classifier")
Conditional edges from classifier
Conditional edges from classifier
graph.add_conditional_edges(
"classifier",
route_query,
{
"coding": "coding",
"search": "search",
"chat": "chat"
}
)
graph.add_conditional_edges(
"classifier",
route_query,
{
"coding": "coding",
"search": "search",
"chat": "chat"
}
)
All agents lead to END
All agents lead to END
graph.add_edge("coding", END)
graph.add_edge("search", END)
graph.add_edge("chat", END)
app = graph.compile()
undefinedgraph.add_edge("coding", END)
graph.add_edge("search", END)
graph.add_edge("chat", END)
app = graph.compile()
undefinedAnti-Patterns
反模式
❌ Infinite Loop Without Exit
❌ 无退出条件的无限循环
Why bad: Agent loops forever.
Burns tokens and costs.
Eventually errors out.
Instead: Always have exit conditions:
- Max iterations counter in state
- Clear END conditions in routing
- Timeout at application level
def should_continue(state):
if state["iterations"] > 10:
return END
if state["task_complete"]:
return END
return "agent"
问题所在:Agent会无限循环,消耗token并产生成本,最终会报错。
正确做法:始终设置退出条件:
- 状态中的最大迭代次数计数器
- 路由中明确的END条件
- 应用层面的超时机制
def should_continue(state):
if state["iterations"] > 10:
return END
if state["task_complete"]:
return END
return "agent"
❌ Stateless Nodes
❌ 无状态节点
Why bad: Loses LangGraph's benefits.
State not persisted.
Can't resume conversations.
Instead: Always use state for data flow.
Return state updates from nodes.
Use reducers for accumulation.
Let LangGraph manage state.
问题所在:失去LangGraph的核心优势,状态无法持久化,无法恢复对话。
正确做法:始终使用状态进行数据流传输,节点返回状态更新,使用reducer进行数据累积,让LangGraph管理状态。
❌ Giant Monolithic State
❌ 庞大的单体状态
Why bad: Hard to reason about.
Unnecessary data in context.
Serialization overhead.
Instead: Use input/output schemas for clean interfaces.
Private state for internal data.
Clear separation of concerns.
问题所在:难以理解,上下文包含不必要的数据,序列化开销大。
正确做法:使用输入/输出模式实现清晰的接口,为内部数据使用私有状态,明确关注点分离。
Limitations
局限性
- Python-only (TypeScript in early stages)
- Learning curve for graph concepts
- State management complexity
- Debugging can be challenging
- 仅支持Python(TypeScript处于早期阶段)
- 图概念存在学习曲线
- 状态管理复杂度较高
- 调试难度较大
Related Skills
相关技能
Works well with: , , ,
crewaiautonomous-agentslangfusestructured-output与以下工具配合使用效果更佳:, , ,
crewaiautonomous-agentslangfusestructured-outputWhen to Use
使用场景
This skill is applicable to execute the workflow or actions described in the overview.
当您需要执行概述中描述的工作流或操作时,适用此技能。