跳到主要内容

Agent 框架

Agent 框架封装模型调用、工具执行和状态管理等通用能力。本文先说明框架替开发者完成哪些工作,再比较 LangChain 与 LangGraph。随后讲解状态合并、常见框架的定位,以及选型时需要权衡的成本。

面试中需要说清框架承担的工作,并结合项目需求解释选用或自研的原因。

1. 面试核心​

先记住这几条,再读正文
  • LangChain 与 LangGraph。 LangChain v1 的 create_agent 基于 LangGraph 运行,通过中间件定制模型和工具调用。卡 · LangChain 与 LangGraph
  • 图的执行模型。 LangGraph 用 State 保存流程数据,节点执行工作,边决定后续节点。卡 · LangChain 与 LangGraph
  • 并行状态合并。 State 字段的 reducer 决定更新如何合并,未声明 reducer 的字段采用覆盖更新。卡 · State 归并与并行更新
  • 框架与自研。 标准能力满足需求时可复用框架,特殊控制需求则需要扩展框架或自研。卡 · 选型依据
  • 能力侧重点。 Agent 框架的侧重点包括流程编排、多 Agent 协作、数据检索和开发生态集成。卡 · 常见框架的定位

2. 框架能力​

手写 Agent 的核心是调用模型、执行工具,再把结果放回上下文。要让它持续运行,还需要处理下表中的运行与集成能力。

能力需要解决的问题
模型适配消息、工具格式和流式事件的转换
工具管理Schema、执行和错误回传
循环与编排节点调度、分支和停止条件
持久化保存检查点并恢复
人工介入暂停、接收输入、恢复
追踪输入输出、耗时、用量和错误
集成检索器、向量库、MCP 等组件接入

比如,工具管理要定义参数 Schema,也就是字段与类型的规则。收到调用请求后,程序解析参数、执行函数,再把结果或错误交回模型。预置 Agent 循环可以封装这些操作,同时设置最大步数和停止条件。

流式输出也是一项独立能力。应用需要在任务执行期间转发模型生成的文本片段,以及工具执行的进度事件。框架提供流式接口后,前端就能持续显示进展。

模型接口和工具节点承接调用,检查点组件保存可恢复的状态。文档加载器、检索器和向量库集成则负责接入外部数据。跨会话记忆还需要选定存储方式,明确何时读取和更新。

各框架的覆盖范围不同,所以要用项目要求逐项验证。业务授权、验收条件和部署配置仍由应用负责。回答选型问题时,也应说明复用了哪些组件、还需补哪些能力。

3. LangChain 与 LangGraph​

两者的主要区别是开发者直接控制哪一层。LangChain 提供高层 Agent 接口,LangGraph 则让开发者直接定义图中的状态和执行路径。

LangChain 最初以“链”组织组件:前一个组件的输出成为下一个组件的输入。比如,提示模板生成输入,模型生成回答,输出解析器再提取字段。检索器也可以参与这条链路。预置链把多个步骤封装在一起,调试时就需要继续追踪内部调用。

LangChain v1 以 create_agent 为高层入口,底层运行在 LangGraph 上。中间件是在调用前后插入自定义逻辑的扩展方式,可以处理摘要、审批或重试。旧版链等接口迁入 langchain-classic,LangChain Core 仍保留可组合的基础抽象。

LangGraph 用有向图描述流程,需要理解以下三个组成部分:

  • State 是节点之间传递的状态,包含消息、计划和中间结果等字段。
  • **节点(Node)**是执行工作的函数,读取当前状态,再返回需要更新的字段。
  • **边(Edge)**决定下一步执行哪个节点。固定边直接连接节点,条件边则调用路由函数,根据状态选择后继节点。

图可以包含循环和并行分支。比如,模型节点与工具节点之间的环可以表达 Agent 循环。发生可处理的错误时,节点把错误写入 State,路由函数再选择错误处理分支。

执行模型借鉴 Pregel,按“超步”推进。一个超步就是一轮节点执行,同一轮中就绪的节点可以并行运行。等这一轮完成、更新合并后,下一轮节点才读取新状态。因此,并行节点之间需要明确字段的合并规则。

维度LangChain v1LangGraph
层次高层 Agent 接口图编排与运行时
定制方式中间件与组件配置节点、边和状态模式
适用情况标准 Agent 与生态集成需要精确控制的有状态流程

LangGraph 可以单独使用,也可以在节点中调用 LangChain 组件。子图还能作为父图的节点,两者通过共享字段或输入输出转换传递数据。

检查点按线程保存状态,供恢复、回放和查看历史使用,生产环境需要持久存储。具体机制见检查点与恢复。

人工介入通过中断等待审批或补充信息,再用同一线程标识恢复。节点重跑的边界见 LangGraph 中断节点重跑。

3.1 State 归并与并行更新​

多个节点都会返回更新时,需要先确定新值怎样进入 State。归并函数(reducer)接收字段的旧值和新更新,返回合并后的值。

State 只保存节点之间需要传递的数据,比如消息、当前计划和中间结果。错误信息与重试次数也应在需要跨节点使用时保存。大对象放到外部存储,State 中只保留引用,避免每次保存状态都复制大对象。

未指定 reducer 的字段采用覆盖更新。同一超步中,多个节点写入此类字段会产生冲突。需要汇总多个结果时,可以定义合并规则,也可以让节点分别写入不同字段。

下面让多个审查节点把发现的问题写入同一个列表:

from typing import Annotated, TypedDict
import operator

class ReviewState(TypedDict):
findings: Annotated[list[str], operator.add]

operator.add 在这里负责拼接列表。两个节点分别返回 {"findings": ["A"]} 和 {"findings": ["B"]} 后,合并结果包含两个发现。并行执行时若需要稳定的展示顺序,可以给结果附上任务 ID,再按 ID 排序。

消息字段可以使用 add_messages:新消息追加到列表,已有消息 ID 对应的条目则被更新。这样,修订同一条消息时就能替换旧内容。简单列表拼接只会追加;如果业务还要求去重,归并规则也要明确去重依据。

4. 常见框架的定位​

框架的能力有重叠,选型时先看它主要简化哪类工作。下表按主要定位区分常见选择。

框架主要定位
LangGraph图编排、状态与检查点
AutoGen通过消息组织多 Agent 协作
CrewAI按角色、任务和团队组织协作
LlamaIndex数据接入、索引与检索
OpenAI Agents SDKAgent 循环、工具、转交和追踪
Claude Agent SDK复用 Claude Code 的工具与执行能力
Spring AISpring 生态的模型、工具、RAG 与 MCP
Dify、Coze可视化编排与应用集成

把定位对应到项目,可以考虑以下使用场景:

  • LangGraph 适合有分支、循环和人工介入的长任务。
  • AutoGen 的消息协作适合多角色讨论和研究原型。CrewAI 的角色与任务组织方式适合分工明确的内容生成或业务流程。
  • LlamaIndex 适合围绕知识库构建检索增强生成(RAG)应用,也就是先检索文档再让模型回答。
  • OpenAI Agents SDK 与 Claude Agent SDK 适合复用各自提供的 Agent 运行能力。两者的模型支持、工具集成和部署方式需要分别核对。
  • Spring AI 适合希望复用 Spring 体系的 Java 后端团队。
  • Dify、Coze 适合通过可视化流程快速验证应用,也便于业务人员参与搭建。

官方 SDK 也能执行应用提供的工具。需要统一模型接口和请求路由时,还可以评估 LiteLLM 这类网关组件。

Claude Code、Codex 等编码产品的运行时设计也可供自研参考,具体分工见 Agent Harness。

5. 选型依据​

选型要从项目需要出发,比较框架节省的工作与引入的成本。可以沿以下五个维度判断:

  • 流程复杂度:一次调用或固定几步可以直接调用 API,减少依赖。需要循环、并行或长时间运行时,再验证图编排与持久化能力。
  • 控制需求:检查框架能否表达上下文组装、压缩、工具授权和停止条件。扩展点不足时,可以自研循环,或只使用框架的底层组件。
  • 团队与语言:Java 团队可以评估 Spring AI,Python 团队则有多种框架可选。团队熟悉框架内部调用,出现问题时才更容易定位。
  • 追踪与运维:确认每一步的输入输出、Token 用量和耗时都可查询。还要确认检查点存储适合部署环境,并明确存储与运维责任。
  • 升级与迁移:固定依赖版本,升级时回归工具调用、状态更新和失败路径。工具实现、提示和评测集保持独立,便于更换编排方式。

自研可以用官方 SDK 调模型,自己管理循环和状态,再复用存储、向量库与追踪组件。这样能精确控制每次调用,也需要自行集成恢复、流式事件等能力。框架节省通用开发工作,同时带来学习、抽象调试和依赖升级成本。

比较方案时使用同一任务集和运行预算。只有现有缺口带来的代价超过迁移成本,更换框架才有实际收益。

6 · 面试题卡片​

本页题目与参考回答

6.1 LangChain、LangGraph 和原生手写 Agent 有什么区别?各自的优劣是什么?​

考察重点

  • 解释链式组合与图编排的区别,以及 LangChain 1.0 前后的接口变化。
  • 说明手写实现需要补齐哪些能力,并比较框架带来的开发收益和维护成本。

相关内容:LangChain 与 LangGraph、框架能力。

参考回答

LangChain v1 提供高层 Agent 接口,LangGraph 提供图编排,手写方案则直接管理执行循环。

早期 LangChain 用链把组件串起来,前一步的输出作为后一步的输入。v1 的 create_agent 基于 LangGraph,通过中间件定制调用前后的逻辑。旧版链等接口移到 langchain-classic。直接使用 LangGraph 时,开发者自己定义 State、节点和边,因此能精确控制分支、循环和并行。

手写循环可以直接控制每次调用,减少框架依赖。代价是要自行集成持久化、恢复、流式事件、追踪和模型适配。框架减少了这部分开发工作,但调试需要理解内部抽象,上下文与权限策略也要适配扩展点。因此,简单流程可直接调用 API,标准 Agent 可用 LangChain,复杂有状态流程可评估 LangGraph。

6.2 为什么自研 Agent 而不用成熟的开源框架?反过来,为什么用框架而不直接调模型接口?​

考察重点

  • 根据项目的流程、上下文和权限要求,解释复用或自研的原因。
  • 说明框架已经覆盖的能力、需要补齐的能力,以及替换框架的成本。

相关内容:选型依据、框架能力、Agent Harness。

参考回答

标准能力覆盖需求时,框架能减少开发工作;核心流程简单或控制要求特殊时,自研更容易直接表达需求。

比如,每次工具执行前都要检查权限、等待审批并记录审计结果。这时需要确认框架是否提供对应扩展点。扩展点不足时,可以自己驱动循环,接入已有的工具执行组件。上下文压缩策略和部署限制也会影响这个选择。

如果项目需要完整的恢复、流式事件和追踪能力,框架已经提供这些组件,复用就能节省集成成本。团队对框架的熟悉程度也会影响交付速度。工具实现、提示和评测集保持独立,可以降低升级与迁移成本。替换现有框架时,还要比较当前能力缺口与迁移后的收益。

6.3 讲一下 LangGraph 的原理。State 怎样设计,节点返回后是覆盖还是合并?条件边、断点续跑和人工介入怎样实现?​

考察重点

  • 解释 State、节点和边怎样配合,以及超步怎样组织并行执行。
  • 说明字段如何覆盖或合并,并解释检查点保存与中断恢复的边界。

相关内容:LangChain 与 LangGraph、检查点与恢复。

参考回答

LangGraph 用 State 保存数据,用节点执行工作,再通过边决定下一步的执行路径。

节点读取当前状态并返回部分更新,条件边根据路由函数选择后继。可处理的错误写入状态后,也能路由到错误处理节点。同一超步内的节点可以并行执行,更新合并后再进入下一超步。

State 保存消息、计划、中间结果等需要跨节点使用的数据,错误和重试次数也按需要保存。大对象放外部存储,状态里保留引用。字段未指定 reducer 时采用覆盖更新,并行写同一字段则需要合并规则或拆分字段。消息字段可用 add_messages 追加新消息,并按已有 ID 更新旧消息。

Checkpointer 按 thread_id 保存检查点,恢复时使用同一线程标识和存储。interrupt() 暂停节点等待外部输入,Command(resume=...) 再传入审批或补充信息。恢复会重跑中断节点,因此发送邮件等副作用需要防止重复执行。父子图通过共享字段或转换函数交换数据。

6.4 你了解哪些 Agent 框架?框架里有哪些组件?不同框架适合什么场景?​

考察重点

  • 说明模型接入、工具执行、状态和追踪等组件各自承担什么工作。
  • 按框架定位匹配项目场景,并解释选择的依据。

相关内容:常见框架的定位、框架能力。

参考回答

Agent 框架分别侧重高层集成、流程编排、多 Agent 协作或数据检索,需要按项目场景选择。

通用组件负责模型接入、提示组织、工具执行和流程调度。状态与持久化组件保存进度,记忆与检索组件提供可复用的信息,流式输出和追踪组件展示执行过程。

选择时,可以按以下几类需求匹配:

  • 标准 Agent 可评估 LangChain,复杂分支和长任务可评估 LangGraph。
  • 多角色讨论可评估 AutoGen,分工明确的任务流程可评估 CrewAI。
  • 知识库应用可评估 LlamaIndex,复用官方 Agent 运行能力可评估 OpenAI Agents SDK 或 Claude Agent SDK。
  • Java 后端集成可评估 Spring AI,可视化验证应用可评估 Dify 或 Coze。

长任务还需核对检查点、中断恢复和授权能力。最终用项目中的具体任务比较候选方案,说明取舍依据。

6.5 LangGraph 并行节点同时更新 State 时,怎样避免覆盖或冲突?​

考察重点:解释并行更新为何需要归并规则,以及消息 ID 怎样决定追加或替换。

相关内容:State 归并与并行更新。

参考回答

多个节点共同更新的字段应声明归并规则,也可以拆成各节点独立写入的字段。

无 reducer 的字段在同一超步收到多次更新会冲突。列表结果可以拼接,展示时再按任务 ID 排序。消息使用 add_messages 时,新 ID 会追加,相同 ID 则更新原消息。因此,普通结果列表和消息列表需要按各自的业务含义选择归并规则,去重要求也要明确。

7. 参考资料​