第六章:加上"循环"和"记忆"
6.1 为什么需要循环?
线性流程只能走一遍就结束。但真实 Agent 需要"思考 → 行动 → 观察 → 再思考"的循环。比如模型先决定搜索,搜索完再看结果决定是否再搜。
6.2 条件边:控制"下一步去哪"
python
python
from typing import TypedDict
from langgraph.graph import StateGraph, START, END
class State(TypedDict):
count: int
def increment(state: State):
return {"count": state["count"] + 1}
def should_continue(state: State):
if state["count"] < 3:
return "keep_going"
return "stop"
builder = StateGraph(State)
builder.add_node("increment", increment)
builder.add_edge(START, "increment")
# 条件边:根据 should_continue 的返回值决定去向
builder.add_conditional_edges(
"increment",
should_continue,
{
"keep_going": "increment", # 回到自己,形成循环
"stop": END
}
)
graph = builder.compile()
result = graph.invoke({"count": 0})
print(result) # 输出 {'count': 3}
add_conditional_edges 的第三个参数是一个映射字典 :should_continue 返回 "keep_going" 就跳回 "increment",返回 "stop" 就结束。这样 count 从 0 累加到 3 才停。
6.3 记忆:让 Agent 记住上下文
默认情况下,每次 invoke() 都是全新的开始。加上 Checkpointer 后,Agent 就能记住之前的对话。
python
python
from langgraph.checkpoint.memory import MemorySaver
checkpointer = MemorySaver()
graph = builder.compile(checkpointer=checkpointer)
# 用 thread_id 区分不同用户的对话
config = {"configurable": {"thread_id": "user_001"}}
# 第一轮
graph.invoke({"question": "我叫小明"}, config)
# 第二轮
result = graph.invoke({"question": "我叫什么?"}, config)
# Agent 能记住"小明"
thread_id 就像会话 ID,同一个 ID 的多次调用会共享状态。