为什么我觉得 Agent 项目不能只看“能不能调用模型”

现在做一个能聊天的 AI 应用并不难:接入模型接口、拼一个 Prompt、把结果流式输出,几乎就能完成一个 Demo。

但真正开始使用后,问题往往才出现:

  • 模型发现缺少工具时,怎么补?
  • 工具调用失败、超时或服务断开时,怎么恢复?
  • 多步骤任务的计划不合理时,用户能否先修改?
  • 高风险工具能否在执行前审批?
  • 用户中途改变思路,能否介入当前运行?
  • 浏览器刷新、网络抖动后,任务会不会丢?
  • 某一步结果不好时,是否必须从头重跑?
  • RAG、记忆和工具调用的依据能否看见?
  • 模型、工具、步骤的性能和成本如何观测?

这些能力决定了一个项目是“模型调用 Demo”,还是可以持续演进的 Agent 工程。

最近我在整理一个开源 Java Agent 项目:TAgent。它基于 Java 17、Spring Boot 和 Spring AI 构建,重点不是做一个聊天壳,而是尝试把 Agent 的规划、执行、工具治理、记忆、恢复、人工控制和观测做进一条完整运行链路。

项目地址:TAgent GitHub

在这里插入图片描述

1. 从请求进入到最终输出,TAgent 的主链路是什么

一次请求并不是直接交给模型,而是会经过接入、路由、策略选择、运行时装配、模型推理、工具执行和 SSE 输出。

整体可以理解为:

用户请求进入系统后,先建立 SSE 连接;随后由统一路由器选择合适的 Agent,并识别可能缺失的工具能力;系统按需组装模型、Prompt、Advisor、RAG 和 MCP 工具;再根据策略进入 Fixed、Auto 或 Flow 执行;最后把模型输出、工具进度、证据和运行状态通过 SSE 返回前端。

这种拆分的意义是:路由、策略、工具、记忆和模型配置不必全部写死在代码里,而是可以按 Agent 的配置进行组合。

2. 三种执行模式:Fixed、Auto 和 Flow

TAgent 不是把所有任务都强行放进同一种 Agent 循环,而是提供三种执行模式。

Fixed:适合直接问答或固定流程

Fixed 更适合单次问答、明确指令或不需要复杂规划的场景。

它的重点是快速、直接地得到结果,不额外引入多步骤规划成本。

Auto:适合需要分析、执行和质量检查的任务

Auto 模式会把一次运行拆成分析、执行、质量检查和总结等阶段。

它适合需要模型先理解问题、再执行,并在中间进行自检和修正的任务。

Flow:适合可拆解的复杂工作流

Flow 模式会把计划解析为 DAG,也就是带依赖关系的任务图。

当两个步骤没有依赖关系时,可以并行推进;当步骤依赖前置结果时,则按照依赖关系继续执行。

这比“模型想到哪一步就执行哪一步”的方式更适合复杂调研、报告生成、多工具任务和长流程任务。

3. Flow 计划确认:计划不能是黑盒

多步骤任务最常见的问题是:模型生成的计划方向不对,但用户只能等它全部跑完。

TAgent 的 Flow 模式支持计划确认。

模型先生成计划,再将计划解析为 DAG。解析完成后,系统可以暂停执行,让用户查看计划、编辑步骤内容、修改步骤标题,甚至调整步骤依赖关系。

用户确认后,系统才继续执行。

这意味着用户可以在真正消耗模型调用、工具调用和时间之前,纠正方向。

它适合以下场景:

  • 报告生成;
  • 多工具检索;
  • 数据处理;
  • 复杂业务流程;
  • 成本较高或风险较高的任务。

重点不是让用户参与每一个细节,而是在关键节点保留控制权。

4. 动态 MCP 工具:不必一开始把所有工具塞给模型

MCP 工具越来越多后,如果每次请求都把全部工具提供给模型,会带来明显问题:

  • 上下文变大;
  • 模型更容易误选工具;
  • 大量低频工具长期占用资源;
  • 工具权限、故障和更新更难治理。

TAgent 将工具分成常驻工具和动态工具。

当路由阶段识别到当前任务缺少能力,或者模型在执行过程中主动发起工具请求时,系统会根据能力描述到 PgVector 工具目录中进行语义匹配。

之后系统会筛选最相关的工具、去重、复用或创建对应的 MCP 连接,再把工具临时注入本次 Agent 请求。

这个过程可以概括为:

  1. 识别任务缺少的能力。
  2. 根据能力描述检索 MCP 工具目录。
  3. 按照相似度筛选候选工具。
  4. 去重并控制数量。
  5. 复用或创建 MCP 连接。
  6. 将动态工具注入当前请求。

这样做的目标不是让模型拥有更多工具,而是让模型在真正需要时拥有更合适的工具。

5. MCP 自愈与工具治理:工具不是“能调用”就结束了

真实环境中的工具服务会超时、断开、重启或者返回异常。

TAgent 对 MCP 工具调用增加了多层治理:

  • 调用前进行懒探测;
  • 首次失败后进行有限重试;
  • 超时时重新探测连接是否真的失效;
  • 死连接或发送失败时重建 MCP Client;
  • 对每个 MCP 服务设置冷却时间,避免重试风暴;
  • 连续失败后进入熔断状态;
  • 工具名大小写纠正;
  • 未知工具返回可用工具信息,帮助模型自我修正;
  • 非执行阶段隐藏真实工具,避免模型在错误阶段调用;
  • 对工具参数给出约束提示;
  • 对工具调用轮次和结果长度进行治理。

工具调用过程也会产生开始、结束、错误等 SSE 事件,前端可以展示工具执行进度,而不是只在最后看到一个回答。

6. 人工审批:高风险工具不应该由模型直接执行

并不是所有工具都适合由模型自动调用。

例如涉及删除、外部写入、敏感操作或业务风险的工具,应该在执行前让用户审批。

TAgent 支持将高风险工具配置为人工审批模式。

当模型准备调用某个高风险工具时,后端会通过 SSE 告知前端工具名称、参数和审批原因。用户可以明确批准或拒绝。

批准后才执行工具;拒绝或超时后,系统会将结构化结果返回给模型,由模型继续处理当前任务。

这让 Agent 不只是“会调用工具”,而是在工具调用前具备明确的风险边界。

7. Agentic RAG:检索不是每次都查,也不只有一种查法

很多 RAG 实现都会把用户问题直接转成向量,然后检索知识库。

但不同问题适合不同检索方式。

TAgent 会先判断当前问题是否需要检索,再选择不同的查询策略,包括:

  • SIMPLE:重写原始问题后检索;
  • HYDE:先生成假设性答案文档,再用它的语义进行检索;
  • FUSION:生成多个查询变体,再融合结果;
  • DECOMPOSE:将多跳问题拆成多个子问题并行检索。

检索链路同时结合 PgVector 向量检索和 Elasticsearch BM25 关键词检索,再通过 RRF 融合、重排、父文档回填和引用组装形成最终上下文。

当 RAG 真正命中知识时,前端可以收到对应的证据事件,而不是只得到一个无法判断依据的回答。

8. 四层记忆:短期上下文、聊天历史、用户长期偏好和会话经验分开处理

TAgent 将记忆分成四层:

  • 工作记忆:保存在 Redis 中,用于保存 Auto 和 Flow 的中间结果、快照和断线恢复数据;
  • 聊天记忆:保存多轮对话历史,并支持滚动总结;
  • 长期记忆:保存用户画像、技能、偏好、计划和上下文,并支持语义召回;
  • 情景记忆:保存会话阶段总结和近期经验。

长期记忆并不是简单地把历史对话全部塞回 Prompt。

它会处理精确去重、语义去重、单值覆盖、累计合并、冲突检测、访问热度和冷记忆归档等问题。

当系统实际召回了记忆时,前端同样可以看到对应证据,避免“模型为什么知道这件事”变成黑盒。

9. 多模态消息:图片不能只停留在一次请求里

TAgent 支持图片 URL、上传图片和剪贴板图片。

图片会走统一的归一化路径:先保存到对象存储,再以文本和图片组合的形式进入 Chat Memory;只有支持视觉能力的模型才会收到图片内容。

这样可以避免图片只在当前一次请求中可用,而在后续对话、历史回放或模型切换时丢失上下文。

10. 运行中干预:用户可以纠正、收敛或取消任务

Agent 运行不是一次发出请求后就只能等待结果。

TAgent 支持三类运行中干预:

  • 引导:用户在执行过程中补充新想法,系统会把新要求合并到当前任务,并从当前步骤重新推进;
  • 立即回答:用户不想等待完整规划或全部工具执行时,可以要求系统基于当前已有中间结果直接收敛为答案;
  • 取消:用户可以按 Run ID 取消当前运行,避免无意义的后续执行。

这类能力的价值在于:用户不是旁观模型运行,而是可以在任务偏离预期时及时介入。

11. 主动追问:缺少关键信息时,模型可以先问而不是硬猜

当用户请求存在多个合理解释,或者缺少关键输入时,模型可以主动请求补充信息。

TAgent 将这种追问与工具审批分开处理。

追问是为了澄清需求;审批是为了控制高风险工具执行。两者使用不同的事件和标识,避免语义混乱。

系统还会限制单个会话中的追问次数,并支持超时释放,避免 Agent 无限追问。

12. Run Snapshot 与步骤重做:不满意时不必全部从头再来

每次 Agent 运行都会生成一个 Run ID。

Run ID 会关联当前运行的 SSE 事件、聊天记忆、运行日志和 Redis 快照。

如果某一个步骤的结果不满意,用户可以指定某一步进行修正,让系统从目标步骤重新生成。

它不是简单地把原问题全部重跑,而是尽量复用前面仍然有效的上下文,从指定步骤继续执行。

这种能力适合:

  • 某一步工具参数不合理;
  • 中间结论需要纠正;
  • 用户补充了新的关键信息;
  • 长流程中只有局部需要返工。

运行快照会有保存期限。过期后应该启动新运行,而不是错误复用旧数据。

13. 断线续作:浏览器刷新不应该让任务消失

Agent 常通过 SSE 流式输出结果,但网络波动、浏览器刷新和切换页面在真实使用中不可避免。

如果任务和单条 SSE 连接强绑定,连接断开就意味着任务丢失。

TAgent 的设计是:一次运行属于 Session,而不属于某一条浏览器连接。

用户重新进入后,前端会先恢复时间线快照,再读取断线期间的增量事件,最后重新订阅实时 SSE。

因此,即使页面刷新或网络短暂中断,后端任务仍然可以继续。

用户重新进入后,可以恢复查看步骤文本、工具调用、RAG 证据、记忆证据、审批卡片和最终结果。

14. 后台任务中心:Agent 不只能被动等待用户输入

TAgent 还支持将 Agent 能力放进后台任务中。

目前支持三类触发方式:

  • 一次性定时任务;
  • Cron 周期任务;
  • 文件变化后等待稳定窗口再触发的监控任务。

任务不会直接生效,而是先保存为草稿。用户确认后,任务才进入激活状态。

任务中心支持编辑、暂停、恢复、立即执行、取消、查看触发历史和打开目标会话。

文件变化监控不是固定时间提醒,而是文件发生变化后,等待一段静默时间,确认文件不再变化后才触发任务。

这让 Agent 可以从“用户问一次、执行一次”,扩展为具备定时和事件触发能力的后台助手。

15. 可解释 SSE 输出:前端不只显示最后答案

TAgent 通过 SSE 向前端发送的不只是 token。

运行过程中还会发送连接确认、步骤开始、步骤结束、工具调用开始、工具调用结束、工具调用错误、人工审批、用户补充信息、RAG 证据、记忆证据和最终结果等事件。

这样前端可以展示 Agent 当前做到哪一步、是否调用了工具、为什么引用知识库、是否需要用户审批,而不是只显示一个最终回答。

16. 全链路观测:模型、工具和步骤都应该可追踪

当 Agent 进入真实环境后,问题通常不会只发生在模型层。

因此 TAgent 对模型、工具和步骤增加了观测能力:

  • 记录模型调用耗时、Token、缓存 Token 和计费范围;
  • 记录路由、步骤输入输出、工具调用、干预和最终结果;
  • 使用 Prometheus 记录 LLM 与 MCP 指标;
  • 使用 ELK 记录结构化日志和上下文;
  • 使用 Jaeger 跟踪从 Controller、步骤、模型到工具的调用链;
  • 提供系统观测和 MCP 健康页面;
  • 监控 MCP 服务的失败、重试、恢复、冷却和熔断状态。

这对于排查“为什么慢”“为什么失败”“工具到底有没有恢复”“模型成本为什么上涨”等问题非常重要。

17. 适合哪些开发者参考

如果你正在做下面这些方向,TAgent 值得看看:

  • 使用 Java 或 Spring AI 开发 Agent;
  • 接入 MCP 工具,但担心工具数量、权限和故障恢复;
  • 需要多步骤规划、人工审批或运行中干预;
  • 想理解 RAG、记忆、工具调用和 SSE 如何协作;
  • 想实现可恢复、可重做、可观测的长任务;
  • 想找一个不只展示聊天效果的 Agent 工程参考。

项目中已经提供了多个功能录屏,包括三种执行策略、执行期动态补工具、计划确认、人工审批、Run ID 步骤重做、断线续作、多模态图片理解和后台任务等。

Demo 目录:TAgent Demo Videos

结语

我认为 Agent 项目的竞争重点,正在从“能不能调用大模型”转向“能不能稳定运行、被用户控制、在出问题后恢复”。

TAgent 未必试图替代所有 Agent 框架,但它提供了一个比较完整的 Java Agent 工程化参考:从模型调用到工具治理,从计划执行到人工控制,从 RAG 和记忆到恢复和观测,都有对应实现和演示。

如果你也在做 Java Agent、Spring AI、MCP 或企业内部智能体,可以把 TAgent 当作一个工程化实现参考。

如果项目对你有帮助,欢迎 Star,也欢迎交流你最关心的 Agent 工程问题。

Logo

欢迎加入 MCP 技术社区!与志同道合者携手前行,一同解锁 MCP 技术的无限可能!

更多推荐