github.com/ludayuan/Lu... 鲁大猿的视频知识库
AI Agent 框架怎么选:从一次制度查询拆出技术边界
适用范围:应用侧模型调用、工具执行、状态编排与检索组件的选型方法。框架关系按当前 Python LangChain Agent、LangGraph、LlamaIndex 及 Spring AI 的能力边界解释,不表示所有历史版本均相同。例子是教学模型,不是框架性能测试。
核心问题:LangChain、LangGraph、LlamaIndex 都能参与完成一个 AI 助手,为什么不能只比较"谁能回答问题"?
一句话答案:最终回答只是终点。先拆清模型如何调用工具、任务如何保存和推进、资料如何变成可用上下文,再选择能补齐实际缺口、且维护成本可接受的组件。
阅读准备:函数接收输入并返回结果;模型输出不等于程序已执行;一次请求可能失败或超时。掌握这三点即可进入下面的案例。
1. 固定一个任务,避免空谈框架
假设需要一个公司制度助手。用户问:"这笔出差交通费能不能报销?"助手查询制度,返回相关条款及文档出处。
初始范围只包含查询,不提交报销申请。成功标准不是"生成了一段文字",而是找到了适用条款,回答没有曲解条款,出处能够对应原文。
已有系统可以直接按固定顺序做:检索制度 → 把条款交给模型 → 生成带来源的回答。只要它满足要求,就没有理由为了使用 Agent 名称而让模型重新决定每一步。
后续需求可能分别增加:自己选择查制度还是查额度;资料不足时限次重查;提交前等待人工确认;进程重启后继续等待;处理大量难以解析的制度文件。这些不是同一个技术缺口。
2. 从基本事实推导三类职责
模型输出一份"调用查询工具"的描述,不等于查询已经发生。应用必须校验并执行函数,将结果交回模型。这产生第一类职责:调用组织。
工具结果可能为空。下一步是重查、回答资料不足,还是继续提交,取决于当前状态和业务规则。单靠最终回答文本无法可靠记录"已重查几次""有没有批准"。这产生第二类职责:状态与执行控制。
即使函数调用正常完成,也可能取回无关条款。文档解析、切分、保存来源、检索与可选重排决定送给模型的资料。这产生第三类职责:数据处理与检索。
| 层次 | 要解决的问题 | 不能顺便保证的事 |
|---|---|---|
| 调用组织 | 模型、工具、消息怎样接起来 | 查询结果必然正确、工具天然有权限 |
| 状态与执行 | 现在到哪一步、下一步能不能执行 | 业务副作用只发生一次 |
| 数据与检索 | 哪些资料进入上下文 | 模型解释一定准确 |
框架是复用这些工作的实现集合。三个层次是分析维度,不是三个产品互斥的功能清单。
3. 用一条请求推演完整往返
教学输入:问题为"出差交通费能报销吗?",资料中有"制度 A 的 §4:差旅交通"片段。具体条款内容省略,不能仅凭章节名称得出真实报销结论。
| 步骤 | 输入 | 动作 | 可检查结果 |
|---|---|---|---|
| 1 | 用户问题和可用工具描述 | 模型提出查询工具及问题参数 | 调用描述,不是已查询的证据 |
| 2 | 调用描述与当前身份 | 应用检查参数、权限和执行限制 | 合法调用才进入函数 |
| 3 | 查询问题 | 函数寻找相关片段 | 条款文本、来源、相关性等信息 |
| 4 | 工具执行结果 | 应用把结果交回模型 | 模型上下文出现真实工具结果 |
| 5 | 问题和相关条款 | 模型组织回答 | 答案可与原条款核对 |
只改一个条件:第3步没有找到足够依据。可靠系统不应编造出处,而应进入"重查或停止"的规则分支。能否将结果不足表达为可检查状态,比工具接口名字更重要。
4. 看清框架的关系与组合边界
图4-1|制度助手的职责边界。箭头说明输入输出或控制关系,不代表已经授予权限。固定流程也可以用程序实现这些职责,不必三套框架一起引入。
当前 LangChain Agent 建立在 LangGraph 运行基础上:前者提供已组织的模型和工具交互方式,后者提供状态和执行调度。不能据此说"LangChain 不能做暂停恢复",也不能泛化为"所有 LangChain 组件都等同于一个 Agent"。
先检查现成 Agent 的扩展点能否表达需求。确实需要更细的节点、状态和路由控制时,再考虑直接定制 LangGraph;直接定制也意味着自己维护更多流程代码。LangGraph 可独立使用,不要求同时采用 LangChain。
LlamaIndex 提供资料处理、索引、查询等组件,也具有 Agent 和工作流能力。LangChain 同样能组织检索。选择依据应是具体资料上的效果、开发与排查收益,而不是给它们贴"只能做某事"的标签。
5. 从只查询,扩展到需要确认的提交
下面增加一个独立需求:助手可以代提交申请,但必须先获批准。教学规则规定:首次检索之外,最多再查两次。
图5-1|有限重查与确认是两项独立约束。"等待"不代表持续忙循环;实际实现可暂停执行并等待外部事件。拒绝与尚未响应也必须区分。
节点读取当前状态,完成工作后更新相关字段,路由再根据新状态判断下一步。只在提示词里写"不要超过次数"并不能替代程序条件;模型建议提交,也不能替代批准结果。
这套规则是案例假设,不是 LangGraph 默认就具有的报销逻辑。是否保存在内存、是否持久化、更新如何合并,都要由具体应用配置。
6. 数据接口与状态应该表达什么
一个教学检索函数可以约定为 query_policy(question)。输入是待查询的问题;正常输出是若干条款及其出处;不足或失败需要显式结果,不能用一个看似成功的空字符串混过去。
| 对象 | 教学表示 | 谁负责 |
|---|---|---|
| question | 一段查询文本 | 调用层提供,执行层校验 |
| passages | 条款文本、文档标识、章节位置 | 检索函数产生,应用核验 |
| sufficient | 依据是否满足本任务要求 | 应用定义判断标准 |
| retries | 已完成的额外重查次数 | 执行层记录,不由模型自行承诺 |
| approval | pending / approved / rejected | 可信确认事件驱动 |
| next | 当前可继续执行的节点 | 运行时结合状态和路由确定 |
这些是示意字段,不冒充某个框架的固定 API。
检索函数负责怎样找资料;外部 Agent 或固定流程负责什么时候调用。组合多个框架时,还要写清谁处理超时、谁负责重试、总尝试预算是多少。
如果外层最多尝试2次,内层每次最多尝试2次,在所有尝试都触发的假设下,底层调用最多变为 2 × 2 = 4 次,而不是2次。这里的"尝试"包含首次调用;不能把"两次重试"与"两次尝试"混用。
7. 用最小状态实验检查你的理解
先不接模型、不安装框架,验证最容易讲错的控制规则。附件 check_selection.py 仅用 Python 标准库,运行:
bash
python3 examples/check_selection.py
它验证三个有限的命题:
- 依据不足且额外次数未满时重查,到达上限后停止。
- 依据充分但尚未批准时等待,拒绝时终止,批准后才可提交。
- 单进程顺序教学模型中,同一操作号重复提交只生成一次结果;改用新操作号会生成另一条结果。
第三项不是生产级幂等实现。真实系统必须把去重判断、业务变更与结果记录放进可靠的一致性设计,处理并发、宕机、超时和记录保留周期等问题。内存字典既不能跨进程持久保存,也不能证明并发原子性。
真正比较框架还需要固定模型、资料、工具和任务,分别检查答案、引用、失败定位、等待确认时重启后的状态,以及延迟、调用量和维护成本。附件不测这些,也不能给任何框架打性能分。
8. 恢复、幂等与选型代价
8.1 为什么保存聊天记录还不够
聊天内容可能写着"准备提交",但程序可能尚未提交,也可能已经提交却没收到响应。文字不能可靠替代执行状态。
检查点记录任务状态和后续执行信息。跨进程恢复需要持久化存储,并能定位对应的任务或线程;内存保存不能自动变成跨重启恢复。检查点通常在特定运行边界保存,也不意味着任意一行代码都可精确续跑。
8.2 提交成功,但响应超时
另取一个已获批准的申请:业务服务创建成功,响应在返回途中丢失。调用方知道的是"超时、结果未知",不是"业务肯定失败"。
重试若生成新的业务操作号,服务端可能将其当成第二笔申请。复用同一操作号,并由接收方可靠地识别同一操作、返回原结果,才能避免重复产生业务结果。仅仅在请求里加一个 UUID 不构成完整保障。
人工中断恢复与网络超时重试是不同场景,但都提醒我们:节点再次执行不等于业务可以再次生效。检查点与业务幂等分别保护执行进度和业务结果。
8.3 怎样判断值得引入
| 实际缺口 | 优先检查 | 增加的代价 |
|---|---|---|
| 只是固定检索再生成 | 现有函数和组件是否已满足 | 最小,不额外引入模型决策循环 |
| 要在多种工具间选择 | 现成 Agent 循环、工具限制与停止条件 | 模型选择的不确定性、额外调用 |
| 需要细粒度分支、暂停、恢复 | 现成扩展点,再评估直接定制图 | 状态、持久化与流程维护 |
| 主要难在资料处理 | 同批资料比较检索组件 | 接入、索引、更新及排查成本 |
| Java / Spring 原系统已管理流程 | Spring AI 是否补齐模型、工具和上下文接入 | 仍需单独验证控制与恢复要求 |
不是功能越多越好,而是满足必要约束后,总体实现和运维成本是否合理。
9. 换条件再做一次判断
问题一: 助手只按固定顺序查制度并给出处,是否必须让模型决定下一步?
参考判断:不必须。程序固定检索、生成就能满足时,Agent 循环没有解决新的缺口,反而引入额外决策与调用成本。
问题二: 系统已经恢复到等待确认,但用户从未批准,能不能为了避免卡住自动提交?
参考判断:不能。恢复不改变批准事实。应继续等待或按超时策略终止,不能凭恢复成功推导提交授权。
问题三: 换用 LlamaIndex 后仍引用错条款,应该马上换模型吗?
参考判断:先看中间结果。解析文本已错就修解析;相关片段未入候选就查切分和检索;正确条款已交给模型而解释错误,才进一步检查生成环节。一次换多个环节无法定位收益来源。
10. 技术速查
具体任务 → 拆调用、控制、数据职责 → 检查现有能力缺口 → 选择最小增量 → 用同样输入验证结果和异常 → 计入维护与运行成本。
- LangChain Agent 与 LangGraph 不是简单的同层二选一;先分清现成组织方式与底层控制。
- LlamaIndex 与 LangChain 的能力有重叠;以具体资料和排查收益作比较,而非背互斥标签。
- 工具可调用不等于有权限,保存检查点不等于恰好执行一次,能组合也不等于值得组合。