news 2026/9/7 13:53:12

企业级AI Agent开发:LangChain与LangGraph核心实战与架构详解

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
企业级AI Agent开发:LangChain与LangGraph核心实战与架构详解

企业级 AI Agent 开发绕不开两个名字:LangChain 和 LangGraph。到了 2026 年前后,学习资料越来越多,但很多人的状态是概念零散:今天学一下 Prompt 模板,明天看一段工具调用,后天又听人讲多智能体,等真正要写一个能跑的 Agent 项目时,才发现代码不知道往哪放、状态从哪里来、工具调用失败该看哪一层日志。这篇文章以 LangChain 1.x 与 LangGraph 1.x 的稳定接口为主线,先讲清楚两个框架的分工,再从核心组件拆解到单 Agent 实战,再到多智能体架构中最常用的 Supervisor 模式,最后落到生产环境必须补的配置、安全、监控和排查方法。读完以后,可以把一条完整的学习路线和一个可运行的最小项目结构同时带走。

1. 先分清 LangChain 与 LangGraph:一个管零件,一个管流程

1.1 LangChain 的定位:把模型、提示词、工具串成组件

LangChain 最初解决的核心问题是:LLM 应用不能只靠一次模型调用完成。一个真实功能,往往需要把用户输入转换成 Prompt,把 Prompt 发给模型,把模型输出解析成结构化数据,再决定是否调用外部工具或检索文档。LangChain 把这条链路中的每个环节都抽象成独立组件:ChatModel 负责模型调用,PromptTemplate 负责文本拼接,OutputParser 负责输出解析,Retriever 负责检索,Tool 负责把外部能力封装给模型。这些组件可以自由组合,构成一条固定流程的 Chain。

典型例子是 RAG。用户提出一个问题,系统先去向量库检索相关片段,再把片段与问题拼成一个带上下文的 Prompt,最后让模型生成回答。这个流程基本是线性的,用 LangChain 的组件就能串起来。但问题随之出现:一旦流程需要根据中间结果决定走哪条分支,或者需要循环调用同一个步骤多次,或者需要在某个环节停下来等人工确认,早期的 Chain 模型就显得很笨重。真正适合企业级 Agent 的流程控制,需要由 LangGraph 来承担。

1.2 LangGraph 的定位:用有状态的图表达 Agent 执行流程

LangGraph 把 Agent 运行过程建模成一张有向图。图中每个 Node 是一个处理函数,比如“调用大模型”“调用工具”“判断是否要继续”;Edge 连接节点,表达执行顺序;Conditional Edge 则根据状态自动决定下一步走向。执行期间,所有数据保存在一个全局 State 对象里,每个节点从 State 取输入,向 State 写输出。

理解 LangGraph 要抓住三个核心设计。第一是 State 统一管理:无论是模型消息、工具结果还是自定义字段,都放在同一个状态对象里,用 reducer 函数控制合并方式。第二是 Checkpointer:把每一步状态持久化,程序中断后可以从某个快照恢复,也可以基于历史状态实现多轮记忆。第三是条件分支:让“模型自己决定调用哪个工具、是否需要结束”成为可控的图逻辑,而不是写死的 if else。这些能力正是多智能体协作需要的底座。

1.3 两者的边界与 1.x 版本后的变化

从 LangChain 1.x 开始,生态里的分工越来越明确:LangChain 负责组件和集成,LangGraph 负责 Agent 的执行控制。过去 LangChain 里承载 Agent 逻辑的 AgentExecutor 类正在被 LangGraph 的图执行方式取代。新项目如果直接使用 LangGraph 的 StateGraph、ToolNode 和条件边来编写 Agent 流程,后面维护状态、加记忆、做人工确认都会更顺。

维度LangChainLangGraph
定位组件库与编排工具有状态、可控制的 Agent 执行框架
核心抽象ChatModel、Prompt、OutputParser、Retriever、ToolState、Node、Edge、Conditional Edge、Checkpointer
适合场景固定流程、RAG、一次性生成循环、分支、多步、多智能体、人机协作
状态管理弱,主要靠外部传参强,State 加 reducer 统一管理
持久化需要自己实现Checkpointer 提供快照与恢复
作为多智能体底座可以辅助推荐

注意:标题里的 LangChain V1.3 属于目标版本号。实际开发前先运行pip show查看安装版本,接口如果与示例不一致,优先看目标版本的官方迁移文档,不要照抄旧教程。

2. 环境准备与最小项目骨架

2.1 Python 虚拟环境与依赖安装

学习阶段建议使用 Python 3.10 或 3.11 的独立虚拟环境,避免和系统 Python 或其它项目互相影响。

python -m venv .venv source .venv/bin/activate python -m pip install -U pip

然后安装核心依赖:

pip install -U langchain langchain-openai langgraph python-dotenv

其中:

  • langchain:核心组件库,提供消息、工具、提示词和输出解析等抽象。
  • langchain-openai:OpenAI 模型适配包,负责把 LangChain 的消息对象转换成模型接口请求。
  • langgraph:图执行框架,负责状态、节点、条件和持久化。
  • python-dotenv:本地加载.env文件,方便管理密钥。

安装完成后,用下面命令确认版本。生产项目一定要锁定版本号,不能每次安装都更新到最新。

pip show langchain langgraph langchain-openai

2.2 模型密钥与本地配置

以 OpenAI 兼容接口为例,先在命令行导出密钥:

export OPENAI_API_KEY="your-api-key"

本地开发更推荐使用.env文件,并在入口处调用load_dotenv()

from dotenv import load_dotenv load_dotenv()

如果企业自建了兼容接口网关,可以在创建模型时传入base_url

from langchain_openai import ChatOpenAI model = ChatOpenAI( model="gpt-4o-mini", temperature=0, base_url="https://your-endpoint.example.com/v1", api_key="your-api-key", )

两个注意点:第一,.env和密钥文件绝对不能提交到代码仓库;第二,base_url指向的是企业自己的模型网关或云厂商兼容端点,实际地址以公司内部平台为准。

2.3 项目目录设计

学习环境可以先用单个文件跑通,生产项目建议按模块拆分。

agent_project/ ├── .env ├── requirements.txt ├── app/ │ ├── __init__.py │ ├── main.py │ ├── state.py │ ├── agents/ │ │ ├── supervisor.py │ │ ├── researcher.py │ │ └── writer.py │ └── tools/ │ └── device_tools.py └── tests/ └── test_agent.py

这样拆的好处是:Agent 只负责流程和提示词,工具层单独维护,State 独立定义,后续加监控、加测试、换模型都不会牵一发动全身。

2.4 最小模型调用验证

环境配置完成后,先做一个最小编译验证:

from langchain_openai import ChatOpenAI from langchain_core.messages import SystemMessage, HumanMessage model = ChatOpenAI(model="gpt-4o-mini", temperature=0) resp = model.invoke([ SystemMessage(content="你是设备运维助手。"), HumanMessage(content="设备 M-001 现在是什么状态?"), ]) print(resp.content)

能输出一句合理的自然语言回复,说明模型链路、密钥和依赖都通了。这一步失败时不要急着往下写,先确认网络、密钥、模型名和依赖版本。

3. 核心组件拆解:消息、工具、结构与状态

3.1 ChatModel 与消息对象

LangChain 与模型交互时统一使用消息对象,而不是直接传字符串。最常用的三类消息:

  • SystemMessage:系统设定,定义助手身份和行为边界。
  • HumanMessage:用户输入。
  • AIMessage:模型输出;当模型决定调用工具时,它还会携带tool_calls字段。

这个设计的意义在于:多轮对话必须区分“谁说的”,工具调用必须记录“模型想调哪个工具、参数是什么”。把这些信息统一成消息列表,LangGraph 才能用同一个messages字段管理全部上下文。

3.2 bind_tools 与工具定义

让模型具备调用工具的能力,核心是bind_tools

from langchain_core.tools import tool @tool def query_device_status(device_id: str) -> str: """查询指定设备的最新运行状态。 Args: device_id: 设备编号,例如 M-001。 """ status_map = {"M-001": "运行中", "M-002": "待机", "M-003": "故障"} return status_map.get(device_id, "未找到该设备") tools = [query_device_status] model_with_tools = model.bind_tools(tools)

工具定义的三个关键点:

要点说明错误示范
docstring描述工具功能和适用场景,模型据此判断何时调用不写 docstring
参数类型标注生成 JSON Schema 时依赖类型信息不写类型或者用*args
返回值尽量返回结构化文本,方便下游解析和排查返回None或只打日志

工具定义完成后,可以把生成的 schema 打印出来检查:

print(model_with_tools.bind_tools(tools).model_dump())

3.3 结构化输出

很多下游系统需要 JSON,而不是一段自由文本。可以用with_structured_output把输出约束成 Pydantic 模型:

from pydantic import BaseModel, Field class DeviceQueryResult(BaseModel): device_id: str = Field(description="设备编号,例如 M-001") status: str = Field(description="设备最新运行状态") suggestion: str = Field(description="针对该状态的处理建议") structured_model = model.with_structured_output(DeviceQueryResult) result = structured_model.invoke("请查询设备 M-003 的状态并给出建议") print(result.device_id, result.status, result.suggestion)

注意,不同 LangChain 版本对 Pydantic 版本的兼容有差异。落地前先确认当前环境支持的模型基类,不要假设所有版本的导入路径都一致。

3.4 State 与 reducer

LangGraph 中的 State 是节点之间传递数据的唯一通道。最常见的定义方式:

from typing import Annotated, TypedDict from langgraph.graph.message import add_messages class AgentState(TypedDict): messages: Annotated[list, add_messages]

Annotated[list, add_messages]表示:当多个节点都向messages写数据时,用add_messages这个 reducer 决定如何合并。add_messages会把新消息追加到列表尾部,而不是直接覆盖。这个细节是让多轮对话和多次工具调用能够累积上下文的关键。

4. 用 LangGraph 实现一个会调用工具的单 Agent

4.1 目标与运行流程

现在实现一个最小但完整的单 Agent:用户提出设备状态查询,Agent 调用工具查询,把结果告诉用户。图中只有两个节点:

  • agent:调用绑定了工具的模型,模型可能返回普通回复,也可能返回tool_calls
  • tools:执行模型指定的工具,把结果写回 messages。

条件边判断:最后一条消息有tool_calls就进入tools,没有就直接结束。

from typing import Annotated, TypedDict from langchain_openai import ChatOpenAI from langchain_core.messages import SystemMessage, HumanMessage from langchain_core.tools import tool from langgraph.graph import StateGraph, START, END from langgraph.graph.message import add_messages from langgraph.prebuilt import ToolNode, tools_condition class AgentState(TypedDict): messages: Annotated[list, add_messages] @tool def query_device_status(device_id: str) -> str: """查询指定设备的最新运行状态。""" status_map = {"M-001": "运行中", "M-002": "待机", "M-003": "故障"} return status_map.get(device_id, "未找到该设备") tools = [query_device_status] model = ChatOpenAI(model="gpt-4o-mini", temperature=0).bind_tools(tools) def agent_node(state: AgentState): messages = [SystemMessage(content="你是设备运维助手,可以调用工具查询设备状态。")] + state["messages"] return {"messages": [model.invoke(messages)]} tool_node = ToolNode(tools) graph = StateGraph(AgentState) graph.add_node("agent", agent_node) graph.add_node("tools", tool_node) graph.add_edge(START, "agent") graph.add_conditional_edges( "agent", tools_condition, { "tools": "tools", END: END, }, ) graph.add_edge("tools", "agent") app = graph.compile() result = app.invoke({"messages": [HumanMessage(content="请查询设备 M-001 的状态")]}) print(result["messages"][-1].content)

4.2 这段代码的四个关键点

第一,agent_node返回的是{"messages": [...]},LangGraph 会根据add_messages自动把新消息追加到状态里,不需要手动维护列表。第二,ToolNode(tools)会执行tools中所有工具,并把执行结果包装成ToolMessage写回状态。第三,tools_condition会检查最后一条消息是否包含tool_calls,有则返回"tools",没有则返回END。第四,graph.add_edge("tools", "agent")让工具执行完再回到模型节点,形成“思考-调用-再看结果-再思考”的循环。

4.3 运行结果与预期输出

正常运行时会看到类似输出:“设备 M-001 当前状态为:运行中。” 由于模型生成内容有随机性,措辞可能不同,但核心信息应包含设备编号和状态。如果只输出了“抱歉,我无法查询”之类的回答,而日志里没有任何工具调用,说明模型没有正确触发工具,优先检查bind_tools是否生效,以及模型本身是否支持 function calling。

4.4 用 Checkpointer 实现多轮记忆

单 Agent 默认是无状态的。要让多轮对话记住上下文,需要给图编译时挂上 Checkpointer,并在调用时传入固定的thread_id

from langgraph.checkpoint.memory import InMemorySaver app = graph.compile(checkpointer=InMemorySaver()) session_id = "thread-001" app.invoke( {"messages": [HumanMessage(content="帮我记录一下,设备 M-002 需要加润滑油。")]}, config={"configurable": {"thread_id": session_id}}, ) result = app.invoke( {"messages": [HumanMessage(content="我之前提醒过哪台设备需要维护?")]}, config={"configurable": {"thread_id": session_id}}, ) print(result["messages"][-1].content)

InMemorySaver只适合本地演示和测试,进程重启后数据就没了。生产环境要使用支持持久化的检查点实现,例如 PostgreSQL 或 Redis 版本,具体接入方式以实际环境为准。

5. 多智能体架构:先用 Supervisor 模式跑通协作

5.1 为什么需要多智能体

单 Agent 在场景变大后会遇到三个问题。第一,提示词越来越长:既要会检索,又要会写作,还要会审核,System Prompt 膨胀后模型更容易忽略关键指令。第二,工具集冲突:检索工具和写数据库工具放在同一个 Agent 里,模型可能因为上下位语义混淆而选错工具。第三,职责无法审计:所有业务逻辑混在一个节点里,出了问题很难定位是哪一步答错。

多智能体的思路是拆分:每个 Agent 只负责一个专业领域,由总控 Agent 负责调度。这样每个 Prompt 更短、工具集更小、可解释性更强。

5.2 常见多智能体协作模式

模式特点适用场景
Supervisor 模式一个总控 Agent 决定下一步交给谁任务边界清晰、专家 Agent 工具集差异大
Handoff 模式当前 Agent 直接把会话移交给另一个 Agent客服场景,需要按用户意图转接
分层模式上级拆解任务,下级执行并汇总复杂企业流程,有明确组织层级

这篇文章重点实现 Supervisor 模式,因为它最容易理解,也是大多数企业项目的第一步。

5.3 实现一个最小 Supervisor 多智能体

下面示例包含三个节点:supervisor负责路由,researcher负责检索,writer负责写作。worker 执行完必须回到 supervisor,由 supervisor 判断是继续还是结束。

from typing import Annotated, TypedDict from langchain_openai import ChatOpenAI from langchain_core.messages import SystemMessage, HumanMessage, AIMessage from langgraph.graph import StateGraph, START, END from langgraph.graph.message import add_messages from langgraph.checkpoint.memory import InMemorySaver class MultiAgentState(TypedDict): messages: Annotated[list, add_messages] next: str llm = ChatOpenAI(model="gpt-4o-mini", temperature=0) SUPERVISOR_PROMPT = ( "你是多 Agent 协作的总控。可选专家:\n" "researcher:负责检索资料、查证事实。\n" "writer:负责整理内容并输出最终文本。\n" "请根据用户的请求选择下一个专家,只输出一个词:researcher、writer 或 FINISH。" ) def supervisor_node(state: MultiAgentState): messages = [SystemMessage(content=SUPERVISOR_PROMPT)] + state["messages"] resp = llm.invoke(messages) text = resp.content.strip().upper() if "WRITER" in text: next_agent = "writer" elif "FINISH" in text: next_agent = "FINISH" else: next_agent = "researcher" return {"next": next_agent} def researcher_node(state: MultiAgentState): # 真实项目在这里调用检索工具、RAG 服务或知识库 API return {"messages": [AIMessage(content="研究员已完成资料检索,收集到 3 条关键信息。")]} def writer_node(state: MultiAgentState): # 真实项目在这里读取上下文,重新整理成最终交付文本 return {"messages": [AIMessage(content="写作专家已完成最终内容输出。")]} def route_after_supervisor(state: MultiAgentState): return state.get("next", "researcher") graph = StateGraph(MultiAgentState) graph.add_node("supervisor", supervisor_node) graph.add_node("researcher", researcher_node) graph.add_node("writer", writer_node) graph.add_edge(START, "supervisor") graph.add_conditional_edges( "supervisor", route_after_supervisor, { "researcher": "researcher", "writer": "writer", "FINISH": END, }, ) graph.add_edge("researcher", "supervisor") graph.add_edge("writer", "supervisor") app = graph.compile(checkpointer=InMemorySaver()) result = app.invoke( { "messages": [HumanMessage(content="请先查一下 M-001 最近一周的告警,再帮我写一段运维周报。")], "next": "researcher", }, config={"configurable": {"thread_id": "multi-agent-demo"}}, ) print(result["messages"][-1].content)

5.4 消息流转顺序

一次典型执行顺序如下:

HumanMessage -> supervisor -> researcher -> supervisor -> writer -> supervisor -> FINISH

每轮 worker 执行完都把结果追加到messages,supervisor 下一次决策时能读到全部上下文。需要注意的是,next字段没有 reducer 时默认是覆盖更新,所以初始状态里必须显式传入"next": "researcher",否则路由函数会在第一次读取时拿不到字段。这是多智能体代码最常见的初始化错误。

5.5 防止多智能体死循环

supervisor 如果反复把任务分给同一个 worker,图会一直跑下去。LangGraph 提供了递归上限:

result = app.invoke( {...}, config={ "configurable": {"thread_id": "multi-agent-demo"}, "recursion_limit": 25, }, )

当执行步数超过recursion_limit时,LangGraph 会抛出异常。生产环境除了提高上限,还要在 supervisor 提示词里明确“任务完成就输出 FINISH”,并在代码层加入最大轮次判断,双保险防止失控。

6. 运行验证、调试与链路追踪

6.1 查看图结构

写完图之后,可以用命令直接查看图的拓扑结构,确认边和节点关系是否符合预期:

app.get_graph().print_ascii()

输出里会显示节点连接顺序。如果发现某个节点没有按预期连接到 supervisor,或者条件边缺失,返回结果会与设计不符。建议在编写复杂多智能体时先打印图结构,再写业务逻辑。

6.2 节点内部日志

在节点函数里打印关键信息是最直接的调试方式:

def supervisor_node(state: MultiAgentState): resp = llm.invoke(messages) print(f"[supervisor] route text: {resp.content}") return {"next": next_agent}

生产环境不要用print,应改为结构化日志,带上thread_id和节点名。但本地调试阶段,print比任何工具都直观。

6.3 用 LangSmith 做链路追踪

如果项目开启了 LangSmith,可以在环境变量里配置:

export LANGCHAIN_TRACING_V2="true" export LANGCHAIN_API_KEY="lsv2-..." export LANGCHAIN_PROJECT="agent-demo"

之后每次调用都会生成一条 trace,可以看到模型输入输出、工具调用参数、各节点耗时和 token 消耗。排查“模型为什么没有调用工具”“某个节点为什么超时”“工具返回值是什么”这类问题,直接看 trace 比翻代码快得多。企业没有使用 LangSmith 时,也可以用 OpenTelemetry 或公司自建的链路追踪体系,核心思想相同:把每次 Agent 执行的完整路径记录下来。

6.4 检查点状态查看

使用 Checkpointer 后,可以在运行被中断后查看当前状态快照:

state = app.get_state(config) print(state.values)

通过app.get_state能确认消息累积到了哪一步、next字段当前是什么值。这是排查多智能体路由问题的重要工具。

7. 企业级落地:生产环境要补的六件事

7.1 配置外置与密钥管理

学习环境可以把密钥写在.env里,生产环境必须做到配置外置:环境变量、配置中心或密钥管理服务统一管理。模型名称、温度、超时时间、API 地址都不要硬编码在代码里。发布时通过 CI/CD 注入,而不是由开发手工拷贝服务器配置文件。

7.2 可观测性

生产 Agent 至少要记录三类数据:

  • 日志:每次用户请求的入参、模型选择、工具调用、错误信息和耗时。
  • 指标:请求量、成功率、平均延迟、token 消耗、工具调用失败率。
  • 链路:一次 Agent 执行经过了哪些节点,每一步输入输出是什么。

缺少链路追踪时,多智能体一旦路由错误,排查成本是指数级上升的。

7.3 安全与权限

Agent 会调用真实系统时,需要提前建立工具白名单:模型只能调用事先登记的工具,不能动态执行任意代码。工具参数要做类型和取值范围校验,防止模型生成异常参数打坏下游系统。涉及用户敏感数据时,输入和输出都要做脱敏处理,并记录完整审计日志。工具层的权限应遵循最小化原则:Agent 只拿到完成任务所需的最小权限。

7.4 工具层稳定性

工具是 Agent 最容易出错的环节。生产环境里,每个工具应该具备超时控制、失败重试和限流能力。工具内部要捕获异常,把错误转换成结构化的错误消息返回给模型,而不是让异常直接抛出导致整个图中断。比如查询接口超时,工具应该返回{"error": "timeout", "message": "设备服务不可用"},让模型基于这个信息决定下一步。

7.5 成本与模型治理

不要所有任务都使用同一个大模型。路由、摘要、工具调用选择不同规格的模型,可以显著降低成本。同时为每个请求设置 token 上限,对高频问题使用缓存,把相似请求在模型调用前直接命中。模型名称和参数变更要走版本管理,每次升级后都要用评测样本回归验证。

7.6 发布、灰度与回滚

Agent 项目发布前需要做三件事:锁定依赖版本、准备一套评测集、明确回滚方案。评测集至少覆盖正常问题、边界问题和必须拒绝的问题。发布采用灰度策略:先让少量真实流量进入新版本,对比成功率、延迟和用户反馈后再全量。一旦发现问题,能够快速切换回上一个模型版本或上一版图配置。

7.7 发布前检查清单

  • [ ] 密钥和配置是否已外置,仓库里是否有硬编码。
  • [ ] 依赖版本是否在 requirements.txt 或 lock 文件中固定。
  • [ ] 每个工具是否都有超时、重试和异常处理。
  • [ ] 工具白名单是否确认,模型可调用的工具是否是最小集合。
  • [ ] 是否接入链路追踪,能否查看单次执行的完整节点路径。
  • [ ] 是否设置recursion_limit或轮次上限,防止死循环。
  • [ ] 是否有多轮对话的thread_id会话管理设计。
  • [ ] 是否准备评测集,并在发布前完成回归。
  • [ ] 是否有回滚方案,包括模型版本和代码版本。

8. 常见问题与排查路径

8.1 模型没有调用工具

现象:用户问题明显需要查询设备,但模型直接给出“无法查询”的回答。原因可能是模型不支持 function calling、工具没有正确 bind、或者提示词没有引导模型使用工具。检查顺序:

  1. 确认model.bind_tools(tools)是否生效,打印 schema。
  2. 确认模型型号是否支持工具调用能力。
  3. 确认 System Prompt 是否明确说明“可以调用工具,不要凭空编造”。

8.2 条件边返回的 key 与节点名不一致

现象:运行时报错,提示路由映射里找不到某个 key,或图执行走向完全不对。原因通常是自定义路由函数返回了映射表中不存在的值。检查方式:在路由函数里打印返回值,并逐一核对add_conditional_edges的映射表。不要让路由函数返回None,要给状态字段设置默认值或使用state.get("next", "默认节点")

8.3 多轮对话没有记忆

现象:第二次提问时,模型完全不记得第一次对话内容。原因是没有配置 Checkpointer,或者调用了不同的thread_id。检查方式:确认graph.compile(checkpointer=...)是否传参,确认每次invoke的 config 里thread_id是否固定。InMemorySaver重启后数据会丢失,这在生产环境不是 bug,而是架构限制。

8.4 工具报错导致整个流程失败

现象:一个下游接口超时,整个 Agent 请求失败。原因是工具函数内部没有捕获异常,异常直接抛出 Graph。推荐做法是在工具函数内部捕获异常并返回结构化错误信息:

from langchain_core.tools import tool @tool def call_device_api(device_id: str) -> str: """调用设备接口查询状态。""" try: raw = request_device_status(device_id) return raw except TimeoutError: return "{\"error\": \"timeout\", \"message\": \"设备服务响应超时\"}" except Exception as exc: return f"{{\"error\": \"unknown\", \"message\": \"{exc}\"}}"

这样模型可以在下一轮根据错误信息决定重试策略,而不是让整个链路直接失败。

8.5 常见问题速查表

问题现象常见原因检查方式处理建议
模型没有调用工具工具未 bind、模型不支持 tool calling打印 bind_tools 结果换支持 function calling 的模型并确认绑定
工具参数解析失败工具缺少类型标注或 docstring查看工具生成的 schema补全函数签名和描述
条件边找不到节点路由 key 与映射表不一致打印路由返回值给 next 设置默认值,核对映射表
多轮对话无记忆未配置 checkpointer 或 thread_id 变化检查 compile 和 config使用持久化 Checkpointer 并固定会话 ID
工具异常导致全链路失败工具内未捕获异常查看 trace 和日志工具内 try/except 返回结构化错误
多智能体死循环supervisor 一直分发给同一 worker查看 trace 节点数设置 recursion_limit 并在提示词中要求 FINISH
成本过高全部任务使用大模型统计 token 消耗分层模型、设置预算、加缓存

9. 最佳实践与后续学习路径

9.1 写 Agent 代码时坚持的几条原则

第一,节点函数保持简单和可重放。每个节点只做一件事:调用模型、调用工具、或做路由判断。第二,工具永远返回结构化数据,不要返回“成功”这样没有信息量的文本。第三,自定义状态字段都要考虑默认值,避免路由函数在最开始就报错。第四,提示词与代码分离,System Prompt 不要散落在业务代码深处。第五,不要让单个 Agent 承担所有职责,先把职责边界划清楚,再决定是否需要多智能体。

9.2 学习顺序建议

如果从零开始,可以按照下面顺序推进:

  1. 掌握 LangChain 的核心组件:ChatModel、消息对象、工具定义、结构化输出。
  2. 跟着 LangGraph 官方教程跑通 StateGraph、条件边、Checkpointer 三个基础概念。
  3. 做一个 RAG Agent:加载文档、切分、向量化、检索、生成,把组件串成完整流程。
  4. 做一个会调用外部工具的单 Agent,把工具调用循环跑顺。
  5. 用 Supervisor 模式改造项目,从单 Agent 演进到多智能体。
  6. 最后补生产能力:评测集、链路追踪、安全白名单、成本控制。

学习资源方面,LangGraph 官方文档是最值得优先阅读的,因为它的 API 更新较快,第三方教程很可能滞后。遇到接口不一致时,以官方文档和当前安装版本的源码为准。

9.3 一个更务实的起点

很多人一开始就想做完整的企业级多智能体平台,这是弯路。更务实的起点是:用一两天时间把这个最小例子跑通,然后替换成自己领域的问题和工具。把“状态如何累积,条件边如何路由,Checkpointer 如何保存会话”这三个问题真正理解透,后面加多少 Agent 都只是重复同样一套模式。所谓少走弯路,核心不是囤积教程,而是把状态、工具、控制流三件事一次想清楚,再用代码验证一次。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/7 13:53:03

AI钱币鉴定实战:Claude Agent与智谱GLM-5.1多模态协作

这次我们来看一个很有意思的组合项目:AI 钱币鉴定。它的核心不是某个单独的模型,而是把 Claude Agent 的任务编排能力,和智谱 GLM-5.1 大模型的视觉理解能力接在一起,组成一条“钱币图片 → 特征识别 → 知识比对 → 结构化鉴定报…

作者头像 李华
网站建设 2026/9/7 13:52:30

嵌入式Linux驱动:Platform设备与驱动匹配机制全解析

搞嵌入式Linux驱动,只要你在设备树和驱动模型之间打过交道,就一定绕不开Platform机制。很多刚入手i.MX6ULL的朋友,第一步往往是照着手册写字符设备驱动,insmod之后看到日志打印就以为完事了,但等真正要把驱动挂到实际硬…

作者头像 李华
网站建设 2026/9/7 13:50:09

MySQL高性能企业级实战:索引设计、SQL优化与故障排查指南

企业级应用里,MySQL 高性能从来不是一个抽象目标,而是一连串需要被具体解决的现象:报表查询为什么跑十几秒,下单高峰期写入为什么频繁超时,锁等待和死锁日志为什么刷屏,磁盘 I/O 并不高但数据库就是慢。这些…

作者头像 李华
网站建设 2026/9/7 13:49:10

神经网络代码实战:BP、CNN、RNN与PyTorch实现指南

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/9/7 13:46:33

CMSIS-DSP源码审计与工业落地:嵌入式信号处理实战详解

最近在调一套振动监测和电机控制类的固件,几十兆主频的 Cortex-M4 上要同时跑 FIR 滤波、256 点 FFT 和最小二乘矩阵运算。最开始我打算全部手写,写了两天发现精度、溢出和边界条件全都得自己验证,掉头把 Arm-CMSIS-DSP 拉进来,花…

作者头像 李华
网站建设 2026/9/7 13:46:18

构建推荐系统的相似检索技术:从距离度量到深度学习的快速了解

目录 一、相似检索方法总体分析 二、基于距离度量的方法 (一)余弦相似度 (二)欧氏距离 (三)曼哈顿距离 (四)汉明距离 三、基于集合的方法 (一)Jaccard相似度 (二)杰卡德距离 四、基于内容的方法 五、协同过滤方法 (一)基于用户的协同过滤 基本原理 …

作者头像 李华