四驱兄弟传说游戏
97.20 MB · 2026-02-05
在前面几讲里,我们已经让智能体“能记住”“会用工具”“会路由”“会和人协作”。 但一旦进入真实项目,你一定会遇到两个非常现实的问题:
这就需要“可观测性(Observability)”:
本讲,我们就来解决:如何让你的 LangGraph 智能体“可视、可查、好调试”。
传统后端服务:你写完业务逻辑、单测通过、日志简单看看就够了。 但 LLM + LangGraph 有几个特点:
如果没有良好的观测能力,你只会听到用户抱怨:
而你自己完全复现不了那次执行路径,只能瞎猜。
可以简单理解为三层:
LangGraph 的流式 API + 事件流 + LangSmith,就分别对应了这几个层次。
假设你已经有一个最简单的图:
from langgraph.graph import StateGraph, START, MessagesState
from langchain.chat_models import init_chat_model
model = init_chat_model(model="deepseek-chat", model_provider="deepseek")
def call_model(state: MessagesState) -> MessagesState:
response = model.invoke(state["messages"])
return {"messages": state["messages"] + [response]}
builder = StateGraph(MessagesState)
builder.add_node("call_model", call_model)
builder.add_edge(START, "call_model")
graph = builder.compile()
如果希望在控制台里看到模型一点点输出,可以使用graph.stream:
config = {"configurable": {"thread_id": "stream-demo"}}
for chunk in graph.stream({"messages": "请用中文解释一下 LangGraph 是什么?"}, config):
# 每个 chunk 代表一次状态增量更新
print(chunk)
这已经是最朴素的“流式可见”,但可读性还不太好。 真实项目中更常见的做法是:
仅仅看到“文本流”还是不够,调试时我们更关心:
LangGraph 提供了事件流(Events Stream),帮助我们查看整条执行的“时间轴”。
下面是一个典型用法(伪代码示意):
from langgraph.graph import StateGraph, START, MessagesState
# 假设你已经有一个复杂一点的 graph
graph = builder.compile()
config = {"configurable": {"thread_id": "debug-1"}}
events = graph.stream_events(
{"messages": "帮我查一下订单状态,然后发一封邮件给客户"},
config,
version="v1", # 可选:标记当前版本
)
for event in events:
# event 里包含:
# - event["event"]:事件类型(node_started / node_finished / tool_started / tool_finished 等)
# - event["name"]:节点或工具名称
# - event["data"]:输入输出、错误信息等
print(event)
你可以按需筛选:
node_started/node_finished,看整体路径tool_started/tool_finished,排查某个工具慢的问题error类型事件)打印堆栈和状态快照很多人会在本地做一个小工具:
stream_events把事件推到 WebSocket这其实就是一个“简单版 LangSmith UI”,但完全在你本地环境里实现。
如果你不想自己造可视化工具,LangSmith是一个很现实的选择。
它可以帮你:
大致步骤(略化):
export LANGCHAIN_TRACING_V2=true
export LANGCHAIN_ENDPOINT="https://api.smith.langchain.com"
export LANGCHAIN_API_KEY="your_api_key"
export LANGCHAIN_PROJECT="your_project_name"
result = graph.invoke({"messages": "帮我规划一个周末北京两日游行程"}, config)
常见优化方式:
在更复杂的系统里,你可能想看到的是:
plan/tools_used/errors)是如何变化的典型做法是:
stream_events订阅事件流node_finished事件里,拿到当前的state或state_diff伪代码示意:
for event in graph.stream_events(input, config):
if event["event"] == "node_finished":
node_name = event["name"]
state_diff = event["data"].get("state_diff", {})
logger.info("node=%s diff=%s", node_name, state_diff)
这样你可以回答类似问题:
不需要一上来就做得很复杂,推荐你按以下节奏演进:
本讲我们围绕“让智能体可观测”展开,重点讲了: