Skip to content

框架选型边界:什么时候用 Spring AI,什么时候上 AgentScope ​

1. 本节产出 ​

一张清晰的选型边界表:什么场景用 Spring AI 自带的编排就够,什么场景需要 AgentScope 或自研编排;以及一个**「先轻后重」的演进路径**,避免一开始就上重型框架。

2. 前置依赖 ​

3. 为什么选型会出问题 ​

两种典型失败:

失败一:一上来就上重型框架。 团队用 AgentScope 做了一个只需要「查天气 + 查订单」的单 Agent,结果:

  • 学习成本:团队两周才搞清楚消息机制;
  • 调试困难:出问题时不知道是框架行为还是自己代码;
  • 部署复杂:多了一套运行时依赖。

而这两件事用手写循环 60 行就能做完。

失败二:什么都自己写。 另一个团队拒绝任何框架,自己实现了消息总线、状态机、工具注册。半年后发现:

  • 代码 8000 行,只有最初写的人能改;
  • 缺少的功能(并发、重试、追踪)不断补,越补越乱;
  • 换模型厂商要改三处。

判断标准:框架的价值不在「让你能写 Agent」,而在「替你处理你不擅长的基础设施」。

4. 核心原理 ​

4.1 能力对照 ​

能力Spring AI 2.0AgentScope Java自研
模型调用与多厂商✅ 原生✅自己适配
Tool 注册与调用✅ @Tool✅ Toolkit自己写
ReAct 单 Agent⚠️ 需自己写循环✅ 原生60 行
Advisor / 拦截器链✅ 成熟⚠️ 较弱自己写
多 Agent 协作(Supervisor/Handoff)❌ 无✅ 原生大量工作
分布式 Agent / 跨进程❌✅ 设计目标不现实
状态持久化⚠️ 自己做✅ 有抽象自己写
与 Spring 生态集成✅ 天然⚠️ 需桥接—
学习曲线低中高—
版本稳定性中(迭代快)低(演进中)—

4.2 决策规则 ​

需求判断:

Q1:是否需要多个 Agent 协作(分工、辩论、流水线)?
    是 → 考虑 AgentScope
    否 → 继续

Q2:是否需要 Agent 跨进程 / 分布式运行?
    是 → AgentScope
    否 → 继续

Q3:是否需要复杂的消息机制(多轮对话、中断恢复、消息持久化)?
    是 → 考虑 AgentScope
    否 → Spring AI + 自研循环(推荐)

默认答案是「Spring AI + 自研循环」。因为:

理由说明
单 Agent 场景占绝大多数企业里 80% 的需求是单 Agent + 几个工具
可靠性才是难点无论用哪个框架,超时/熔断/审计都要自己写
与 Spring 生态一致依赖注入、配置、监控、事务全部复用现有能力
依赖更少Spring AI 是 Spring 官方项目,稳定性更有保障

4.3 推荐的演进路径 ​

阶段一(0-3 个月):Spring AI + 手写 ReAct 循环
    └─ 验证业务价值,跑通 1-2 个场景

阶段二(3-6 个月):抽取自研 Harness
    └─ 把超时/熔断/审计/状态沉淀成可复用组件(03B)

阶段三(6 个月+):按需引入 AgentScope
    └─ 只在真正需要多 Agent 协作的模块引入,与 Spring AI 共存

阶段二的自研 Harness 是本课程的核心交付(03B-13)。它的定位是:框架不管的可靠性,我来管。

4.4 混合架构:两者共存 ​

┌─────────────────────────────────────────┐
│  Web 层 / API 网关(Spring Boot)        │
├─────────────────────────────────────────┤
│  编排层                                  │
│  ├─ 单 Agent:Spring AI + 自研 Harness   │
│  └─ 复杂子图:AgentScope Bridge          │
├─────────────────────────────────────────┤
│  共享基础设施                            │
│  审计 / 配额 / 追踪 / 工具权限(Spring)  │
└─────────────────────────────────────────┘

关键:无论用哪个引擎,共享同一套基础设施(审计、权限、配额)。这样切换引擎不会丢失治理能力。

5. 代码走查 ​

5.1 统一抽象:让两者可切换 ​

java
// ch03-agent/src/main/java/com/aitech/agent/agent/AgentRunner.java
public interface AgentRunner {

    /** 统一的运行入口:输入目标,输出结果与轨迹 */
    AgentResult run(AgentRequest request);
}

public record AgentRequest(String runId, String goal, String tenantId,
                           String userId, List<String> allowedTools,
                           Duration timeout) {}

public record AgentResult(String answer, List<Step> trace,
                          int iterations, int totalTokens, Status status) {
    public enum Status { DONE, MAX_ITERATIONS, TIMEOUT, NEED_APPROVAL, FAILED }
}

定义自己的 AgentRunner 接口是关键一步。这样:

  • 初期用一个 SpringAiAgentRunner 实现;
  • 需要时再加一个 AgentScopeRunner;
  • 上层编排代码完全不动。

5.2 Spring AI 实现 ​

java
// ch03-agent/src/main/java/com/aitech/agent/agent/SpringAiAgentRunner.java
@Component
@ConditionalOnProperty(name = "agent.engine", havingValue = "spring-ai", matchIfMissing = true)
public class SpringAiAgentRunner implements AgentRunner {

    private final ReactLoop loop;
    private final AuditLogger audit;

    @Override
    public AgentResult run(AgentRequest req) {
        audit.logStart(req);
        try {
            String answer = loop.run(req.goal(), req.allowedTools());
            return AgentResult.done(answer, loop.lastTrace());
        } finally {
            audit.logEnd(req);
        }
    }
}

5.3 AgentScope 桥接(示意) ​

java
// ch03-agent/src/main/java/com/aitech/agent/agent/AgentScopeRunner.java
@Component
@ConditionalOnProperty(name = "agent.engine", havingValue = "agentscope")
public class AgentScopeRunner implements AgentRunner {

    @Override
    public AgentResult run(AgentRequest req) {
        // 把 AgentRequest 映射到 AgentScope 的消息与 Agent 配置
        // 运行子图,把结果映射回 AgentResult
        // 注意:审计/权限仍在 Harness 层,不依赖 AgentScope
        ...
    }
}

5.4 通过配置切换 ​

yaml
agent:
  engine: spring-ai      # 或 agentscope
  max-iterations: 10
  timeout: 60s

6. 跑起来 ​

bash
git checkout ch03-02-framework-choice
mvn -q test -Dtest=AgentRunnerSwitchTest
bash
# 1. 用默认引擎跑
curl -X POST http://localhost:8080/api/agent/run \
  -d '{"goal":"查一下北京今天天气,适合户外运动吗"}'
# 期望:返回结果 + trace,engine=spring-ai

# 2. 切换引擎(若已配置 AgentScope)
# 改 application.yml: agent.engine=agentscope,重启
# 期望:同样的请求返回同样的结构(trace 格式一致)
检查项通过标准
接口统一两个引擎返回同一个 AgentResult 结构
切换不改业务上层编排代码零改动
审计不丢切换引擎后审计日志仍然完整
默认可用不配 AgentScope 时系统正常工作

7. 生产避坑 ​

  1. 不要为了「以后可能需要多 Agent」而提前上重型框架。先用手写循环验证业务价值,等真的需要协作模式时再引入。提前引入的成本是确定的,收益是不确定的。
  2. 定义自己的 AgentRunner 抽象,不要直接在业务代码里用框架类型。这是唯一能让你后期切换引擎而不改业务的做法。成本极低(一个接口),收益很大。
  3. 无论用哪个引擎,审计与权限必须放在自己的 Harness 层。依赖框架提供的审计能力,意味着换框架时治理能力跟着丢——而治理能力恰恰是你最不能丢的东西。

8. 延伸与锚点 ​