使用 Java、Spring Boot 和 Spring AI 开发符合 A2A 标准的 AI 智能体

AI 智能体指的是一种软件实体,它能够利用自然语言处理、机器学习或推理系统等人工智能技术,自主感知、推理和行动,以实现特定目标。

我为 Telex 开发了一个 AI 智能体,该智能体接收一个正则表达式模式,并就该模式所匹配的字符串类型提供易于理解的解释。开发此智能体的灵感源于我在此之前开发的一个 API(您可以在此处查看该项目),在该 API 中我必须使用正则表达式进行一些自然语言处理。尽管我之前学习过正则表达式,但感觉像是第一次见到它。正则表达式就是这样。因此,当 Telex 为其平台寻求更多 AI 智能体时,我决定开发这个智能体。

以下是我使用 Java、Spring AI 和 Spring Boot 实现它的过程。

初始设置

1. Spring Boot 项目初始化

我使用 Spring 提供的初始化工具来初始化项目。请注意,我在依赖项中包含了 Spring Web 和 Open AI。

初始化 Spring 项目

2. 设置 API 凭证

在我的 application.properties 文件中,我设置了 Spring AI 以使用我的 API 凭证(我的 API 密钥)。我通过 Google AI Studio 获得了一个免费的 Google Gemini API 密钥。我的 application.properties 文件设置如下:

    spring.config.import=classpath:AI.properties

    spring.application.name=regexplain

    spring.ai.openai.api-key = ${GEMINI_API_KEY}
    spring.ai.openai.base-url = https://generativelanguage.googleapis.com/v1beta/openai
    spring.ai.openai.chat.completions-path = /chat/completions
    spring.ai.openai.chat.options.model = gemini-2.5-pro

第一行导入了包含我 API 密钥的文件。重要的是不要将您的 API 密钥暴露给公众。该文件与 application.properties 位于同一文件夹中。

3. 首次项目运行

使用我的包管理器(Maven),我安装了所需的依赖项。然后我运行了我的主类,以确保一切正常。如果您到目前为止一切都做对了,您的项目应该可以无错误运行。如果遇到任何错误,请在 Google 上查找解决方法。

A2A 请求和响应模型

在深入实现之前,让我们先谈谈符合 A2A 标准的请求和响应的结构。A2A 协议遵循标准的 JSON-RPC 2.0 结构来处理请求和响应。

所有方法调用都封装在一个请求对象中,其结构如下:

{
  "jsonrpc": "2.0",
  "method": "String",
  "id": "String | Integer",
  "params": "Message"
}

响应对象有些类似:

{
  "jsonrpc": "2.0",
  "id": "String | Integer | null",
  "result?": "Task | Message | null",
  "error?": "JSONRPCError"
}

响应中的 ID 必须与请求中的 ID 相同。

有关 A2A 协议的更多信息,请查阅 A2A 协议文档

以上就是请求和响应的通用结构。我开发这个智能体是为了在 Telex 平台上使用,因此我的部分实现可能特定于 Telex。

现在进入实现部分。我创建了一个名为 model 的文件夹,用于存储我的模型。请求模型类 A2ARequest 如下所示:

public class A2ARequest {
    private String id;
    private RequestParamsProperty params;

    public A2ARequest(String id, RequestParamsProperty params) {
        this.id = id;
        this.params = params;
    }

    // getters and setters
}

RequestParamsProperty 类代表了 params 中包含信息的结构。它如下所示:

public class RequestParamsProperty {
    private HistoryMessage message;
    private String messageId;

    public RequestParamsProperty(HistoryMessage message, String messageId) {
        this.message = message;
        this.messageId = messageId;
    }

    // getters and setter
}

HistoryMessage 类如下所示:

@JsonIgnoreProperties(ignoreUnknown = true)
@JsonInclude(JsonInclude.Include.NON_NULL)
public class HistoryMessage {
    private String kind;
    private String role;
    private List<MessagePart> parts;
    private String messageId;
    private String taskId;

    public HistoryMessage() {}

    public HistoryMessage(String role, List<MessagePart> parts, String messageId, String taskId) {
        this.kind = "message";
        this.role = role;
        this.parts = parts;
        this.messageId = messageId;
        this.taskId = taskId;
    }

    // getters and setters
}

注解的作用是让 Spring 知道在请求和响应的 JSON 表示中包含什么。如果请求中不存在某个属性,它应该忽略它并在类中将其设置为 null。如果某个属性设置为 null,则不应将其包含在响应中。

MessagePart 类如下所示:

@JsonIgnoreProperties(ignoreUnknown = true)
@JsonInclude(JsonInclude.Include.NON_NULL)
public class MessagePart {
    private String kind;
    private String text;
    private List<MessagePart> data;

    public MessagePart(String kind, String text, List<MessagePart> data) {
        this.kind = kind;
        this.text = text;
        this.data = data;
    }

    // getters and setters
}

以上就是表示从 Telex 接收的请求结构所需的所有类。现在需要为我的响应创建一个模型,以及表示响应所需的所有支持类。

A2AResponse 类:

@JsonInclude(JsonInclude.Include.NON_NULL)
public class A2AResponse {
    private final String jsonrpc;
    @JsonInclude(JsonInclude.Include.ALWAYS)
    private String id;
    private Result result;
    private CustomError error;

    public A2AResponse() {
        this.jsonrpc = "2.0";
    }

    public A2AResponse(String id, Result result, CustomError error) {
        this.jsonrpc = "2.0";
        this.id = id;
        this.result = result;
        this.error = error;
    }

    //getters and setters
}

Result 类:

public class Result {
    private String id;
    private String contextId;
    private TaskStatus status;
    private List<Artifact> artifacts;
    private List<HistoryMessage> history;
    private String kind;

    public Result() {}

    public Result(String id, String contextId, TaskStatus status, List<Artifact> artifacts, List<HistoryMessage> history, String task) {
        this.id = id;
        this.contextId = contextId;
        this.status = status;
        this.artifacts = artifacts;
        this.history = history;
        this.kind = task;
    }

    // getters and setters
}

CustomError 类:

public class CustomError {
    private int code;
    private String message;
    private Map<String, String> data;

    public CustomError(int code, String message, Map<String, String> data) {
        this.code = code;
        this.message = message;
        this.data = data;
    }

    // getters and setters
}

TaskStatus 类:

@JsonInclude(JsonInclude.Include.NON_NULL)
public class TaskStatus {
    private String state;
    private Instant timestamp;
    private HistoryMessage message;

    public TaskStatus() {}

    public TaskStatus(String state, Instant timestamp, HistoryMessage message) {
        this.state = state;
        this.timestamp = timestamp;
        this.message = message;
    }

    // getters and setters
}

Artifact 类:

public class Artifact {
    private String artifactId;
    private String name;
    private List<MessagePart> parts; // 稍后复查此类型

    public Artifact() {}

    public Artifact(String artifactId, String name, List<MessagePart> parts) {
        this.artifactId = artifactId;
        this.name = name;
        this.parts = parts;
    }

    // getters and setters
}

A2A 协议还包含一个称为"智能体卡片"的东西。我也为它创建了一个模型。

public class AgentCard {
    private String name;
    private String description;
    private String url;
    private Map<String, String> provider;
    private String version;
    private Map<String, Boolean> capabilities;
    private List<String> defaultInputModes;
    private List<String> defaultOutputModes;
    private List<Map<String, Object>> skills;

    public AgentCard() {
        this.provider = new HashMap<>();
        this.capabilities = new HashMap<>();
        this.skills = new ArrayList<>();
    }

    // getters and setters
}

模型部分就这些了。继续…

服务类

我的智能体的作用是获取一个正则表达式字符串,然后使用预定义的提示词将其发送到 OpenAI 的 API。服务类负责与 OpenAI 通信,发送提示词并接收响应。我创建了另一个名为 service 的文件夹,我的服务类就放在这里。我是这样编写我的服务类的:

@Service
public class RegExPlainService {
    private ChatClient chatClient;

    RegExPlainService(ChatClient.Builder chatClientBuilder) {
        this.chatClient = chatClientBuilder.build();
    }

    @Tool(name = "regexplain", description = "An agent that explains what type of string a regex pattern matches")
    public String generateResponse(String regex) {
        return chatClient
                .prompt("Give me a simple explanation of the type of string matched by this regex pattern: %s. No validating statements from you. Just straight to the point".formatted(regex))
                .call()
                .content();
    }
}

@Service 注解允许 Spring Boot 将服务注入到您的控制器中。@Tool 注解将该方法标记为一个智能体工具,如果将来要扩展该智能体以包含该功能,它可以被自主调用。不过目前并不需要它。

控制器

控制器通过 REST API 暴露该智能体。在这个案例中,我有两个端点,一个 GET 端点和一个 POST 端点。我在一个名为 controller 的文件夹中创建了我的控制器。实现如下:

@RestController
public class RegExPlainController {
    private final RegExPlainService regexplainService;

    @Autowired
    RegExPlainController (RegExPlainService regexplainService) {
        this.regexplainService = regexplainService;
    }

    @GetMapping("/a2a/agent/regexplain/.well-known/agent.json")
    public ResponseEntity<AgentCard> getAgentCard () {
        AgentCard agentCard = new AgentCard();
        agentCard.setName("regexplain");
        agentCard.setDescription("An agent that provides a simple explanation of the type of string a regex pattern matches");
        agentCard.setUrl("regexplain-production.up.railway.app/api");
        agentCard.setProvider("Bituan", null); // 假设 setProvider 处理 Map 的填充
        agentCard.setVersion("1.0");
        agentCard.setCapabilities(false, false, false); // 假设 setCapabilities 处理 Map 的填充
        agentCard.setDefaultInputModes(List.of("text/plain"));
        agentCard.setDefaultOutputModes(List.of("application/json", "text/plain"));
        agentCard.setSkill("skill-001", "Explain Regex", "Provides a simple explanation of the type of string a regex pattern matches",
                List.of("text/plain"), List.of("text/plain"), List.of());

        return ResponseEntity.ok(agentCard);
    }

    @PostMapping("/a2a/agent/regexplain")
    public ResponseEntity<A2AResponse> explainRegex (@RequestBody A2ARequest request) {
        String regexRequest;
        String responseText;

        // 如果参数无效,返回 403
        try {
            regexRequest = request.getParams().getMessage().getParts().get(0).getText();
        } catch (Exception e) {
            CustomError error = new CustomError(-32603, "Invalid Parameter", Map.of("details", e.getMessage()));
            A2AResponse errorResponse = new A2AResponse(null, null,  error);
            return ResponseEntity.status(HttpStatusCode.valueOf(403)).body(errorResponse);
        }

        // 如果调用服务失败,返回错误 500
        try {
            responseText = regexplainService.generateResponse(regexRequest);
        } catch (Exception e) {
            CustomError error = new CustomError(-32603, "Internal Error", Map.of("details", e.getMessage()));
            A2AResponse errorResponse = new A2AResponse(null, null,  error);
            return ResponseEntity.internalServerError().body(errorResponse);
        }

        // 构建响应
        A2AResponse response = new A2AResponse();
        response.setId(request.getId());

        // 构建响应 -> 构建结果
        Result result = new Result();
        result.setId(UUID.randomUUID().toString());
        result.setContextId(UUID.randomUUID().toString());
        result.setKind("task");

        // 构建响应 -> 构建结果 -> 构建状态
        TaskStatus status = new TaskStatus();
        status.setState("completed");
        status.setTimestamp(Instant.now());

        // 构建响应 -> 构建结果 -> 构建状态 -> 构建消息
        HistoryMessage message = new HistoryMessage();
        message.setRole("agent");
        message.setParts(List.of(new MessagePart("text", responseText, null)));
        message.setKind("message");
        message.setMessageId(UUID.randomUUID().toString());

        // 构建响应 -> 构建结果 -> 构建状态 (续)
        status.setMessage(message);

        // 构建响应 -> 构建结果 -> 构建工件
        List<Artifact> artifacts = new ArrayList<>();
        Artifact artifact = new Artifact();
        artifact.setArtifactId(UUID.randomUUID().toString());
        artifact.setName("regexplainerResponse");
        artifact.setParts(List.of(new MessagePart("text", responseText, null)));
        artifacts.add(artifact);

        // 构建响应 -> 构建结果 -> 构建历史记录
        List<HistoryMessage> history = new ArrayList<>();

        // 构建响应 -> 构建结果 (续)
        result.setStatus(status);
        result.setArtifacts(artifacts);
        result.setHistory(history);

        // 构建响应 (续)
        response.setResult(result);

        return ResponseEntity.ok(response);
    }
}
  • GET 端点使用的路由路径是 A2A 协议标准中用于获取智能体卡片的部分。智能体卡片是对智能体及其功能的描述。
  • POST 端点接收一个符合 A2A 标准的请求,执行智能体,然后返回适当的响应。

结论

就是这样。这就是我编写 Regexplain 的过程。

通过这个示例,您可以从头开始构建您的 AI 智能体并使其符合 A2A 标准。或者,至少我希望这能让您对如何使用 Java 开发符合 A2A 标准的 AI 智能体有所了解。


【注】本文译自:Developing an A2A-compliant AI Agent with Java, Spring Boot and Spring AI – DEV Community

构建可用于生产环境的AI智能体

围绕AI智能体的炒作确实存在,但让我们拨开迷雾,直面实质。在过去六个月中,我致力于构建并部署用于生产环境的AI智能体,并深刻认识到演示系统与可用于生产环境的系统之间存在着巨大差距。本指南将引导您构建真正能在现实世界中工作的AI智能体,而不仅仅是在您的本地环境中运行。

作为一位深耕AI微调大语言模型部署领域的人,我可以告诉您,构建智能体所需的心态与传统软件开发截然不同。

AI智能体究竟是什么?

在深入技术细节之前,我们先明确讨论的对象。AI智能体是一种自主系统,它能够感知环境、做出决策并采取行动以实现特定目标。与仅响应查询的传统聊天机器人不同,AI智能体能够:

  • 将复杂任务分解为子任务
  • 自主使用工具和API
  • 在多次交互中保持上下文
  • 从反馈中学习并随时间改进

可以将它们视为能够处理整个工作流程的智能工作者,而不仅仅是单个任务。这与我们一直在大语言模型中使用的传统提示工程方法有着根本的不同。

AI智能体的商业价值

根据麦肯锡2025年报告,部署AI智能体的公司实现了:

  • 运营成本降低40%
  • 任务完成速度提升3倍
  • 客户满意度得分提高60%

但问题是:只有15%的AI智能体项目能够成功进入生产环境。为什么?因为大多数团队低估了构建可靠、可扩展的智能体系统的复杂性。正如我在关于AI对劳动力动态影响的文章中所讨论的,这项技术具有变革性,但需要谨慎实施。

实践证明有效的架构

在尝试了各种方法之后,以下是经过生产环境验证最为可靠的架构:

核心组件

组件 用途 关键考量因素
编排层 管理智能体生命周期、处理重试、记录交互 必须容错、支持异步操作
规划模块 将复杂任务分解为可执行步骤 需要处理模糊性、验证可行性
执行引擎 运行单个动作、管理状态 错误处理至关重要、需实现超时机制
记忆系统 存储上下文、过往交互、学习到的模式 考虑使用向量数据库进行语义搜索
工具层 与外部API、数据库、服务交互 实施适当的身份验证、速率限制

为何选择此架构?

这种模块化方法使您能够:

  1. 独立扩展 – 每个组件可根据负载独立扩展
  2. 优雅降级 – 局部故障不会导致整个系统瘫痪
  3. 快速迭代 – 更新组件而无需重建所有内容
  4. 有效监控 – 清晰的边界使调试更容易

这类似于我在关于模型上下文协议 的指南中概述的原则,其中结构化的上下文管理是可扩展AI系统的关键。

构建您的第一个生产级智能体

让我们一步步构建一个真实的智能体,它能够分析GitHub仓库并生成技术文档。这不是一个玩具示例——它基于一个当前在生产环境中运行、每日处理超过1000个仓库的系统。

步骤1:明确界定能力范围

团队最常犯的错误是试图构建无所不能的智能体。请从聚焦开始:

class AgentCapabilities:
    """定义您的智能体能做什么"""
    name: str = "github_analyzer"
    description: str = "分析GitHub仓库并生成文档"
    tools: List[str] = [
        "fetch_repo_structure",
        "analyze_code_quality", 
        "generate_documentation"
    ]
    max_iterations: int = 10  # 防止无限循环
    memory_window: int = 2000  # 要记住的令牌数

步骤2:实施健壮的错误处理

这是大多数教程未能覆盖的地方。在生产环境中,任何可能出错的地方都终将出错。以下是您需要处理的情况:

错误类型 发生频率 影响程度 解决方案
API速率限制 每日 实现指数退避、队列管理
网络超时 每小时 设置积极的超时时间,使用断路器进行重试
无效响应 常见 验证所有响应,制定回退策略
上下文溢出 每周 实施上下文修剪、摘要
无限循环 罕见 严重 循环检测、最大迭代次数限制

步骤3:记忆与上下文管理

没有记忆的智能体只不过是花哨的API包装器。一个生产级的记忆系统需要:

  1. 短期记忆 – 当前任务上下文(Redis,内存缓存)
  2. 长期记忆 – 学习到的模式和成功策略(PostgreSQL,向量数据库)
  3. 情景记忆 – 过去的交互及其结果(时间序列数据库)

这种方法建立在我MCP架构指南中详细介绍的上下文管理策略之上。

规划模块:智能所在之处

规划模块是真正智能体与简单自动化之间的区别所在。一个好的规划器:

  • 将任务分解为具体、可实现的步骤
  • 识别步骤间的依赖关系
  • 在步骤失败时提供回退选项
  • 估算资源需求(时间、API调用、成本)

有效的规划策略

策略 适用场景 优点 缺点
线性规划 简单、顺序性任务 易于调试、可预测 无法处理复杂依赖关系
分层规划 复杂、多层次任务 能很好地处理复杂性 实现难度较大
自适应规划 不确定环境 能从经验中学习 需要更多数据
混合规划 大多数生产场景 平衡各种方法 架构更复杂

工具集成:智能体的双手

工具是智能体与世界交互的方式。常见的工具类别包括:

  • 数据检索 – API、数据库、网络爬虫
  • 数据处理 – 分析、转换、验证
  • 外部操作 – 发送邮件、创建工单、更新系统
  • 监控 – 检查状态、验证结果

工具设计最佳实践

  • 保持工具原子性 – 每个工具应专注于做好一件事
  • 优雅地处理错误 – 返回结构化的错误信息
  • 实现超时机制 – 任何操作都不应无限期运行
  • 记录一切 – 调试时将需要这些日志
  • 对工具进行版本控制 – API会变化,您的工具也应如此

部署策略

将智能体投入生产环境需要仔细考量。根据我大规模部署LLM的经验,基础设施的选择至关重要。

部署方案比较

方法 适用场景 可扩展性 成本 复杂度
无服务器 偶发性工作负载 自动扩展 按使用付费
容器 稳定工作负载 手动/自动 可预测
托管服务 快速部署 有限 较高
混合 复杂需求 灵活 可变 非常高

关键的部署考量因素

  • API密钥管理 – 使用密钥管理服务(AWS Secrets Manager, HashiCorp Vault)
  • 速率限制 – 在多个层级实施(API、用户、全局)
  • 监控 – 实时仪表板是必不可少的
  • 回滚策略 – 您将需要进行回滚,请提前规划
  • 成本控制 – 设定API支出的硬性限制

监控与可观测性

无法衡量,就无法改进。必要的指标包括:

关键绩效指标

指标 说明 告警阈值
任务成功率 整体可靠性 < 95%
平均执行时间 性能退化 > 2倍基线值
单任务成本 经济可行性 > $0.50
按工具分类的错误率 问题组件 > 5%
内存使用率 资源效率 > 80%
队列深度 容量问题 > 1000个任务

可观测性技术栈

一个生产级的智能体系统需要:

  • 指标 – Prometheus + Grafana 用于实时监控
  • 日志 – 带有关联ID的结构化日志
  • 追踪 – OpenTelemetry 用于分布式追踪
  • 告警 – PagerDuty 用于关键问题

现实世界的陷阱与解决方案

1. 上下文窗口问题

  • 挑战:随着对话增长,您会触及LLM的上下文限制。
  • 解决方案:实施智能上下文修剪:
    • 总结较早的交互
    • 仅保留相关信息
    • 对长期记忆使用高级检索模式

2. 成本爆炸

  • 挑战:一个失控的智能体在3小时内消耗了10,000美元的API积分。
  • 解决方案:实施多重保障措施:
    • 每小时/每日的硬性成本限制
    • 昂贵操作的审批流程
    • 带有自动关闭功能的实时成本监控
      这一点在我分析算法交易系统时探讨的AI经济学中尤为重要。

3. 幻觉问题

  • 挑战:智能体基于幻觉信息自信地执行错误操作。
  • 解决方案
    • 执行前验证所有智能体输出
    • 实施置信度评分
    • 关键操作需要人工批准

4. 规模化性能

  • 挑战:能为10个用户工作的系统在1000个用户时失败。
  • 解决方案
    • 实施适当的队列机制(RabbitMQ, AWS SQS)
    • 对数据库使用连接池
    • 积极但智能地进行缓存

投资回报率与业务影响

让我们谈谈数字。以下是我们跨部署观察到的情况:

典型的投资回报时间线

月份 投资 回报 累计投资回报率
1-2 $50,000 $0 -100%
3-4 $30,000 $40,000 -50%
5-6 $20,000 $80,000 +20%
7-12 $60,000 $360,000 +180%

AI智能体表现出色的领域

  • 客户支持 – 响应时间减少70%
  • 数据分析 – 洞察生成速度提升10倍
  • 内容生成 – 输出量增加5倍
  • 流程自动化 – 手动任务减少90%

这些影响与我在分析AI经济影响时所讨论的内容一致,即自动化能带来显著的生产力提升。

安全考量

安全常被事后考虑,但不该如此。正如我在黑帽SEO分析中所述,了解攻击向量对于防御至关重要。

基本安全措施

层级 威胁 缓解措施
输入 提示注入 输入验证、沙箱
处理 数据泄露 加密、访问控制
输出 有害操作 操作审批、速率限制
存储 数据泄露 静态加密、审计日志
网络 中间人攻击 全程TLS、证书固定

入门:您的30天路线图

第1周:基础

  • 精确界定您的用例
  • 设置开发环境
  • 构建一个简单的原型

第2周:核心开发

  • 实现具有2-3个工具的基本智能体
  • 添加错误处理和日志记录
  • 创建初始测试套件

第3周:生产就绪

  • 添加监控和可观测性
  • 实施安全措施
  • 对系统进行压力测试

第4周:部署

  • 部署到预生产环境
  • 与有限用户进行试点运行
  • 收集反馈并迭代

选择正确的工具

AI智能体生态系统正在蓬勃发展。以下是选择方法:

框架比较

框架 最适合 学习曲线 生产就绪 成本
LangChain 快速原型开发 免费
CrewAI 多智能体系统 新兴 免费
AutoGPT 自主智能体 免费
自定义 特定需求 非常高 视情况而定 开发成本

LLM提供商比较

提供商 优势 劣势 成本(每百万令牌)
OpenAI GPT-4 整体质量最佳 昂贵、速率限制 $30-60
Anthropic Claude 非常适合分析 可用性有限 $25-50
Google Gemini 多模态能力 较新、验证较少 $20-40
开源模型 完全控制、无限制 需要基础设施 仅基础设施成本

有关详细实施指南,请查阅我关于微调LLM使用Hugging Face托管模型的文章。

面向未来的智能体系统

AI领域每周都在变化。请以应对变化为目标进行构建:

  • 抽象化LLM提供商 – 不要硬编码到某一个提供商
  • 对提示进行版本控制 – 它们也是代码,请同样对待
  • 为多模态做准备 – 未来的智能体将能看、听、说
  • 内置学习循环 – 智能体应能随时间改进
  • 为监管做准备 – AI治理即将到来

这与我LLM引导指南中概述的策略一致,其中适应性是长期成功的关键。

结论

构建可用于生产环境的AI智能体充满挑战,但也回报丰厚。关键在于从简单开始,快速失败,并根据现实世界的反馈进行迭代。请记住:

  • 完美是优秀的敌人 – 先交付一个可用的东西,然后再改进
  • 监控一切 – 您无法修复看不见的问题
  • 为失败做好计划 – 失败终会发生,请做好准备
  • 聚焦价值 – 技术是手段,而非目的

在未来12-18个月内掌握AI智能体的公司将会获得显著的竞争优势。问题不在于是否要构建AI智能体,而在于您能以多快的速度将它们投入生产环境。


【注】本文译自:How to Build AI Agents (Complete 2025 Guide) – Superprompt.com

如何构建 AI 智能体(2025 完全指南)

🎯内容提要

AI 智能体是能够自主决策并采取行动以完成任务的系统。与聊天机器人不同,它们不遵循预定义的工作流程——它们会进行推理、规划、使用工具并动态适应。本指南将通过真实示例和代码,向你具体展示如何使用如 LangChain 和 AutoGen 等现代框架来构建可工作的智能体。


2025 年正被誉为"AI 智能体之年",其在企业中的应用正在加速。微软 CEO 萨提亚·纳德拉称其为一根本性转变:"请将智能体视为 AI 时代的应用。"但问题在于——大多数教程向你展示的都是伪装成智能体的聊天机器人,或者更糟的是,那些在演示中有效但在生产环境中失败的复杂系统。
在构建了多个生产级智能体并分析了最新框架之后,我将确切地向你展示如何创建真正有效的 AI 智能体。不掺水分,不搞噱头——只有由真实代码和经过验证的架构支持的实践实现细节。

AI 智能体与聊天机器人有何不同?

让我们立刻澄清这一点。智能体没有预定义的工作流程——它不仅仅是遵循第一步、第二步、第三步。相反,它会在不确定的步骤数量中动态做出决策,并根据需要进行调整。

特性 传统聊天机器人 AI 智能体
决策能力 遵循预定义规则 自主决策
工作流程 固定的、线性的步骤 动态的、自适应的规划
记忆 仅限于会话 跨任务持久化
工具使用 无或硬编码 动态选择和使用工具
错误处理 失败或请求帮助 尝试替代方法

真实示例: 要求一个聊天机器人"预订下周二飞往纽约的航班",它要么会失败,要么会向你询问更多信息。而一个智能体会检查你的日历、搜索航班、比较价格,甚至处理预订——根据发现的情况调整其方法。

每个 AI 智能体所需的 5 个核心组件

基于广泛的研究和生产部署,每个可工作的 AI 智能体都需要以下五个组件:

1. 大语言模型 – 大脑

LLM 充当推理引擎。在 2025 年,你有多种优秀选择(参见我们的详细比较):

  •   Claude 4 Opus: 最适合复杂推理和扩展思考
  •   GPT-4.1: 在编码和工具使用方面表现出色,拥有 100 万令牌上下文
  •   Gemini 2.5 Pro: 强大的多模态能力

💡 专业提示: 不要默认使用最昂贵的模型。对于智能体任务,每百万令牌 2 美元的 GPT-4.1-mini 通常表现不俗,尤其是在结合良好提示的情况下。

2. 记忆系统 – 上下文

由于 LLM 默认是无状态的,你需要管理它们的历史和上下文。现代框架提供几种记忆类型:

# 示例:LangChain 记忆实现
from langchain.memory import ConversationSummaryBufferMemory
memory = ConversationSummaryBufferMemory(
    llm=llm,
    max_token_limit=2000,
    return_messages=True
)
# 智能体现在可以跨多次交互进行记忆

记忆类型:

  •   缓冲区记忆: 存储原始对话历史
  •   摘要记忆: 压缩长对话
  •   实体记忆: 跟踪特定实体及其属性
  •   知识图谱记忆: 构建概念间的关系

3. 工具 – 双手

工具允许你的智能体与外部世界交互。正确的工具配置与提示工程同等重要。

# 示例:定义一个用于网络搜索的工具
from langchain.tools import Tool
def search_web(query: str) -> str:
    """搜索网络以获取最新信息。"""
    # 此处为实现代码
    return search_results
web_search_tool = Tool(
    name="WebSearch",
    func=search_web,
    description="搜索网络以获取最新信息。当你需要最新数据时使用。"
)

⚠️ 关键点: 你的工具描述直接影响智能体性能。要具体说明何时以及如何使用每个工具。模糊的描述会导致工具选择不当。

4. 规划系统 – 策略

智能体必须能够提前规划和思考。2025 年最成功的方法是 ReAct 范式(推理 + 行动)

# ReAct 风格智能体循环
while not task_complete:
    # 1. 观察当前状态
    observation = get_current_state()
   
    # 2. 思考下一步行动
    thought = llm.think(f"给定 {observation},我下一步该做什么?")
   
    # 3. 决定行动
    action = llm.decide_action(thought, available_tools)
   
    # 4. 执行行动
    result = execute_action(action)
   
    # 5. 反思结果
    reflection = llm.reflect(result)
   
    # 更新状态并继续

5. 执行循环 – 引擎

执行循环负责协调一切。现代框架以不同方式处理此问题:

  •   LangChain/LangGraph: 使用基于图的执行模型
  •   AutoGen: 实现事件驱动的参与者模型
  •   CrewAI: 专注于基于角色的智能体协作

逐步指南:构建你的第一个可工作智能体

让我们构建一个能够研究主题并撰写报告的实用智能体。此示例展示了所有五个核心组件的实际运作。

步骤 1:设置环境

# 安装所需的包
pip install langchain langchain-openai tavily-python
# 设置环境变量
export OPENAI_API_KEY="你的密钥"
export TAVILY_API_KEY="你的密钥"

步骤 2:初始化核心组件

from langchain_openai import ChatOpenAI
from langchain.agents import create_react_agent, AgentExecutor
from langchain.memory import ConversationBufferMemory
from langchain_community.tools.tavily_search import TavilySearchResults
from langchain.tools import Tool
from langchain import hub
# 1. 初始化 LLM
llm = ChatOpenAI(model="gpt-4.1-mini", temperature=0)
# 2. 设置记忆
memory = ConversationBufferMemory(
    memory_key="chat_history",
    return_messages=True
)
# 3. 配置工具
search = TavilySearchResults(max_results=5)
tools = [
    Tool(
        name="Search",
        func=search.run,
        description="搜索关于任何主题的最新信息。返回相关结果。"
    )
]
# 4. 加载 ReAct 提示(处理规划)
prompt = hub.pull("hwchase17/react")

步骤 3:创建智能体

# 创建 ReAct 智能体
agent = create_react_agent(
    llm=llm,
    tools=tools,
    prompt=prompt
)
# 5. 设置执行循环
agent_executor = AgentExecutor(
    agent=agent,
    tools=tools,
    memory=memory,
    verbose=True,  # 查看智能体的思考过程
    handle_parsing_errors=True,
    max_iterations=10  # 防止无限循环
)

步骤 4:运行你的智能体

# 示例:研究并报告 AI 智能体
result = agent_executor.invoke({
    "input": "研究 2025 年 7 月 AI 智能体的最新发展,并撰写一份简要报告,重点介绍前 3 大趋势。"
})
print(result["output"])

成功关键: 该智能体将自主搜索多次,综合信息,并生成连贯的报告。它并非遵循脚本——而是根据发现的内容动态决定搜索什么。

真正提升性能的高级技巧

在分析了数千次智能体交互后,以下是真正能提高智能体性能的技巧:

1. 问题分解优于角色扮演

  •   无效的方法: 角色提示(例如,"你是一位专家研究员……")对准确性影响甚微或没有影响。
  •   有效的方法: 要求智能体将问题分解为子任务:
decomposition_prompt = """
    将此任务分解为更小的步骤:
      1. 首先,识别关键组成部分
      2. 然后,分别处理每个组成部分
      3. 最后,综合结果
    任务:{task}
"""

2. 自我批评与反思

添加自我批评步骤能显著提高输出质量:

reflection_prompt = """
审查你之前的回应并识别:
1. 任何逻辑错误或不一致之处
2. 遗漏的重要信息
3. 可以更清晰的领域
之前的回应:{response}
"""

3. 上下文重于指令

上下文的重要性被严重低估。仅仅提供更多相关的背景信息,比复杂的提示技术更能提高性能:

# 效果较差
prompt = "写一份关于 AI 智能体的报告"
# 效果更好
prompt = """写一份关于 AI 智能体的报告。
上下文:AI 智能体是可以规划并执行任务的自主系统。
它们与聊天机器人的不同之处在于做出动态决策而非遵循脚本。
关键框架包括 LangChain、AutoGen 和 CrewAI。
该报告面向熟悉 AI 概念的技术读者。
"""

导致 AI 智能体失效的常见错误

以下是我反复看到的常见错误:

1. 无限循环且无限制

 始终设置 max_iterations: 智能体可能陷入循环。设置合理的限制并实现超时处理。

2. 工具描述不清

# 差:描述模糊
Tool(name="search", description="搜索东西")
# 好:包含用例的具体描述
Tool(
    name="WebSearch",
    description="搜索网络以获取最新信息。用于:近期新闻、时事、事实数据、公司信息。返回 5 个最相关的结果。"
)

3. 忽略错误状态

智能体会遇到错误。要为它们做好计划:

try:
    result = agent_executor.invoke({"input": user_query})
except Exception as e:
    # 不要只是失败 - 帮助智能体恢复
    recovery_prompt = f"先前的操作因错误而失败:{e}。请尝试另一种方法。"
    result = agent_executor.invoke({"input": recovery_prompt})

4. 忽视令牌成本

智能体可能快速消耗令牌。需监控并优化:

  •   尽可能使用较小的模型(GPT-4.1-mini vs GPT-4.1)
  •   对长对话实施摘要记忆
  •   缓存工具结果以避免重复调用

生产就绪的智能体架构

对于生产系统,根据你的需求选择架构:

框架 最适合 架构 关键优势
LangChain + LangGraph 复杂的单一智能体 基于图的执行 模块化,工具丰富
AutoGen 多智能体系统 事件驱动的参与者 智能体协作
CrewAI 基于团队的工作流 基于角色的智能体 自然的团队动态
自定义 特定需求 你的选择 完全控制

LangChain + LangGraph 架构

LangChain 已发展成为单智能体系统的事实标准。2025 年 LangGraph 的加入带来了复杂的状态管理:

from langgraph.graph import StateGraph, State
from typing import TypedDict
class AgentState(TypedDict):
    messages: list
    current_task: str
    completed_tasks: list
# 定义图
workflow = StateGraph(AgentState)
# 为不同的智能体能力添加节点
workflow.add_node("researcher", research_node)
workflow.add_node("writer", writing_node)
workflow.add_node("reviewer", review_node)
# 定义流程
workflow.add_edge("researcher", "writer")
workflow.add_edge("writer", "reviewer")

AutoGen 多智能体架构

微软的 AutoGen 在你需要多个专业智能体协同工作时表现出色:

import autogen
# 定义专业智能体
researcher = autogen.AssistantAgent(
    name="Researcher",
    system_message="你是一名研究专家。查找并验证信息。"
)
writer = autogen.AssistantAgent(
    name="Writer",
    system_message="你是一名技术文档工程师。创建清晰、准确的内容。"
)
critic = autogen.AssistantAgent(
    name="Critic",
    system_message="你审查工作的准确性和清晰度。要有建设性但要彻底。"
)

可工作的 AI 智能体真实案例

让我们看看当今在生产环境中实际使用的智能体(查看更多真实可工作的 AI 智能体示例):

1. 客户服务智能体(电子商务)

该智能体自主处理完整的客户交互(在我们的客户服务自动化指南中了解更多):

  •   在数据库中检查订单状态
  •   处理退货和退款
  •   更新送货地址
  •   将复杂问题升级给人工处理
  •   关键创新: 根据客户需求动态选择使用多个专业工具(数据库查询、支付处理、运输 API)。

2. 代码审查智能体(软件开发)

自动审查拉取请求:

  •   分析代码变更
  •   运行安全扫描
  •   提出改进建议
  •   检查是否符合编码标准

3. 研究助手智能体(内容创作)

进行综合研究:

  •   搜索多个来源
  •   事实核查信息
  •   综合发现
  •   生成引用

AI 智能体的安全考量

⚠️ 关键警告: 基于智能体的 AI 系统比聊天机器人更容易受到攻击。随着智能体开始预订航班、发送邮件和执行代码,风险呈指数级增长。

基本安全措施

  •   工具权限: 为每个工具实施细粒度权限
  •   操作验证: 对不可逆操作要求确认
  •   提示注入防御: 验证并清理所有输入
  •   审计日志: 记录每个操作以确保可追溯性
  •   人工监督: 维持紧急停止开关和审批工作流
# 示例:安全的工具执行
def execute_with_permission(action, requires_approval=True):
    if requires_approval and action.risk_level == "high":
        approval = request_human_approval(action)
        if not approval:
            return "操作被安全策略拒绝"
   
    # 记录操作
    audit_log.record(action, user, timestamp)
   
    # 带超时执行
    return execute_with_timeout(action, timeout=30)

测试和调试 AI 智能体

测试智能体需要不同于传统软件的方法:

1. 基于场景的测试

# 测试各种场景
test_scenarios = [
    {
        "input": "预订明天飞往纽约的航班",
        "expected_tools": ["calendar_check", "flight_search", "price_compare"],
        "expected_outcome": "flight_options"
    },
    {
        "input": "取消我的订阅并退还上个月的费用",
        "expected_tools": ["account_lookup", "subscription_cancel", "refund_process"],
        "expected_outcome": "confirmation"
    }
]
for scenario in test_scenarios:
    result = agent_executor.invoke({"input": scenario["input"]})
    assert all(tool in result["tool_calls"] for tool in scenario["expected_tools"])

2. 调试工具

启用详细日志记录以查看智能体的决策过程:

agent_executor = AgentExecutor(
    agent=agent,
    tools=tools,
    verbose=True,  # 显示思考过程
    return_intermediate_steps=True  # 返回所有步骤
)

5 个即用型智能体系统提示

以下是为常见智能体类型准备的、经过实战检验的系统提示:

1. 研究智能体

你是一个可以访问网络搜索和文档分析工具的研究智能体。
对于每个研究任务:

  1. 将主题分解为关键问题
  2. 从多个来源搜索信息
  3. 通过交叉引用验证事实
  4. 将发现综合成连贯的摘要
  5. 为所有主张包含引用
    始终优先考虑近期信息和权威来源。

2. 客户支持智能体

你是一个客户支持智能体,帮助用户处理他们的账户和订单。

可用工具: order_lookup, refund_process, ticket_create, knowledge_base_search
指南:

  • 在访问账户信息前始终验证客户身份
  • 在升级前搜索知识库
  • 要有同理心并以解决方案为导向
  • 遇到以下情况升级至人工支持:法律问题、威胁或超出你工具范围的请求

切勿对你无法直接实现的功能做出承诺。

3. 数据分析智能体

你是一个专长于商业智能的数据分析智能体。
对于每个分析请求:

  1. 澄清业务问题
  2. 识别相关数据源
  3. 使用适当的统计方法执行分析
  4. 可视化关键发现
  5. 提供可操作的建议

始终在你的分析中注明数据局限性和置信水平。

4. 代码助手智能体

你是一个可以访问文件系统和执行工具的代码助手智能体。
能力:

  • 阅读和分析代码
  • 提出改进建议
  • 实施更改
  • 运行测试
  • 调试问题

切勿:

  • 未经明确许可删除文件
  • 修改系统文件
  • 执行可能有害的命令
  • 在代码中存储凭证

在进行重大更改前始终创建备份。

5. 内容创作智能体

你是一个专注于病毒式内容策略的内容创作智能体。

流程:

  1. 研究指定领域的趋势话题
  2. 分析成功的内容模式
  3. 生成多个内容创意
  4. 创建带有吸引点的详细内容
  5. 建议分发策略

关注真实性和价值,而非点击诱饵。

未来:AI 智能体的下一步是什么?

基于当前轨迹和内部知识,以下是将要发生的事情:

近期(未来 6 个月)

  •   视觉智能体: 能够查看并与 UI 交互的智能体
  •   语音优先智能体: 自然对话取代文本界面
  •   智能体市场: 针对特定行业的预构建智能体
  •   改进的安全性: 内置沙盒和权限系统

中期(2026 年)

  •   物理世界智能体: 与机器人技术集成
  •   监管框架: 为智能体行为设定法律边界
  •   智能体间经济: 智能体雇佣其他智能体
  •   个人 AI 操作系统: 管理整个数字生活的智能体

关键要点

构建真正有效的 AI 智能体需要理解五个核心组件:用于推理的 LLM、用于上下文的记忆、用于行动的工具、用于策略的规划以及一个健壮的执行循环。与聊天机器人的关键区别在于自主决策和动态适应。
从经过验证的框架开始,如用于单智能体的 LangChain 或用于多智能体系统的 AutoGen。专注于清晰的工具描述、适当的错误处理和全面的测试。最重要的是,记住上下文和问题分解比复杂的提示技巧更重要。

AI 智能体革命才刚刚开始。虽然炒作是真实的,但机遇也是真实的。通过遵循本指南并避免常见陷阱,你今天就可以构建出能够交付真正价值的智能体,同时为即将到来的自主未来做好准备。


【注】本文译自:How to Build AI Agents (Complete 2025 Guide) – Superprompt.com

Java智能体框架的繁荣是一种代码异味

停止构建编排框架,开始构建智能体。未来属于那些掌握生态系统的人,而不是那些被困在构建特定语言引擎中的人。

我需要坦白。我是一个框架狂热者。我的职业生涯建立在 Apache Camel 之上,我人生中的大部分成功都归功于企业集成模式的优雅。我懂。如果有一个社区值得获得诺贝尔框架奖,那就是 Java 社区。从早年在红帽公司到整个大数据生态系统,框架 15 年来一直是 JVM 世界的引擎。我们是抽象的大师。

因此,当智能体时代来临而 Java 在奋力追赶时,我的第一本能是原始的:构建一个框架。我甚至开始了一个,驱动力是这样一个想法:"AI 智能体的 Apache Camel 在哪里?"

三个月前,可能只有一个严肃的 Java 智能体框架。现在,包括 Embabel 在内,已经有了三个。竞赛开始了。但目睹这场爆炸式增长,我不得不提出一个难题:框架本身是否正在成为一种反模式?我们是否在为自己创造负担,而不是专注于真正重要的事情:构建智能体

最近 Java 智能体框架的繁荣并非一个健康、成熟生态系统的标志。它是一种症状。一种架构层面的代码坏味道,告诉我们我们的方法存在根本性问题。

我们最初为什么要构建框架?

让我们回顾一下。为什么像 Spring 和 Camel 这样的框架变得如此主流?原因清晰且合理:

  • 开发人员生产力: 我们当时淹没在样板代码中。框架将其抽象掉了。
  • 代码质量与治理: 它们提供了标准化的模式,防止每个开发人员重新发明轮子。
  • 可重用性: 它们为我们提供了经过实战检验的构造来构建,节省了大量的时间和精力。

目标是优化生产力、质量和治理。但这些是我们今天应该优化的相同参数吗?感觉我们像是在用 2010 年的方法解决 2025 年的问题,完全忽视了房间里的大象:AI 驱动的开发工具

这头大象有个名字:Cursor(及其伙伴)

在我们忙于将 LangChain 移植到 Java 时,情况发生了变化:

Cursor 和 Copilot 生成样板代码的速度比你输入 import 语句还快。你正在构建的那个复杂的链式抽象?Cursor 三秒钟就能写出来。你正在标准化的那个工具注册模式?Copilot 已经知道五种变体。

但在这里,我们需要停下来问一个更根本的问题:你的最终用户实际需要什么?

你真正需要构建什么?

让我们具体点。我们大多数人面临两种情况:

  • 场景 1: 你在未来 12 个月内构建一个关键智能体。也许它是一个每天处理 10,000 次对话的客户服务智能体。或者一个需要理解你公司特定标准的代码审查智能体。或者一个绝不能对监管要求产生幻觉的合规智能体。
  • 场景 2: 你正在构建一个智能体平台。成百上千个智能体,每个都有不同的上下文、不同的领域、不同的需求。也许你在一家咨询公司,为多个客户构建智能体。或者你正在创建一个内部平台,不同团队可以在上面启动自己的智能体。你需要可重用、适应性强、可演进的东西。一种能让你快速创建新智能体,同时保持所有智能体一致性和质量的东西。

在这两种情况下,诚实地问自己:你的用户需要一个代码框架吗?

还是他们需要完全不同的东西?

重新定义框架

在放弃我的框架并实际交付智能体之后,我学到了:我们不需要消除框架。我们需要重新定义在 AI 时代框架实际意味着什么。

  • 旧框架定义: 一种可重用的代码抽象,提供结构并处理横切关注点。你导入并在其之上构建的东西。
  • 新框架定义: 构建智能体的完整环境,一组协同工作的相互依赖的层,其中代码层只是更大拼图的一部分。

以下是现代智能体框架中真正重要的层次:

第 1 层:语言本身

Java(或你选择的语言)及其构造、类型和模式。不包装在抽象中,直接使用。语言已经是你的逻辑结构框架。你不需要在 Java 之上再加一个代码框架。Java 本身就是框架。

第 2 层:模型

一个真正好的大语言模型:GPT-5、Claude、Gemini、Grok。这不仅仅是你调用的 API。它是你技术栈的核心组件。模型的能力直接决定了你能构建什么。像选择编程语言一样仔细地选择它。

第 3 层:开发人员生产力工具

Cursor、Copilot 以及下一代 AI 驱动的开发工具。这些不是可选的。它们是关键基础设施。你的框架应设计成与这些工具无缝协作。如果 Cursor 不能轻松地按照你的模式生成代码,那么你的模式是错误的,或者你可能需要很好地描述你的模式。

第 4 层:提示词包与指南

你经过版本控制、测试、治理的提示词。你的组织语音。你的领域知识。你的合规规则。这是你的业务逻辑存在的地方——不在代码中,而在精心策划的上下文和指令中。将这些视为你的依赖构件,就像 JAR 包,但用于智能体行为。

第 5 层:生态系统 API

对新兴的专业化平台及其 API 的上下文感知。用于知识检索的向量数据库。上下文存储和内存管理系统,如 Zep 或 Cognee。工具执行平台,如 Arcade。用于智能体监控的可观测性平台,如 Langfuse。提示词管理和版本控制工具。这些大多暴露 REST API 或标准协议,大多提供 LLM.txt 用于上下文导入。你的框架需要知道这些存在,并知道如何连接到它们。

第 6 层:架构与设计模式

作为指南和模式捕获的架构思维。关于这些层如何在不同用例中组合在一起的可重用蓝图。不是代码抽象——关于路由逻辑、版本控制策略、部署模式和生态系统集成的文档化知识,这些知识成为你组织上下文的一部分。

想想看。当你构建那个关键的客户服务智能体时,真正决定其成功的是什么?

  • 调用 LLM 的 Java 代码吗?(那是 20 行代码,Cursor 写的)
  • 复杂的链式编排吗?(标准控制流)
  • 重试逻辑和错误处理吗?(Java 已经有这方面的模式)

还是:

  • 选择的模型以及它处理你领域的能力
  • 教导它你的升级规则和语气的提示词
  • 让你能快速迭代这些提示词的工具
  • 与像 Arcade(工具)和 Zep(内存)这样的平台的集成
  • 让你能够对变更进行版本控制、测试和部署的架构
  • 让你能在多个智能体中重用这种方法的设计模式

那就是你的框架。所有六层,协同工作。

实践中的框架

让我向你展示在构建智能体时的实际示例:

第 4 层(提示词包) 是版本化的构件,不是你代码中的字符串:

prompts/
  customer-service/
    v1.2/
      system-prompt.md
      escalation-rules.md
      tone-guidelines.md
      product-context.md
      examples/
        refund-scenarios.yaml
        technical-issues.yaml

第 5 层(生态系统 API) 配置在你的环境中:
你的生态系统上下文嵌入在指南中:

# 生态系统集成指南

## 工具发现
- 调用 Arcade API 列出可用工具: GET /tools
- 参考: 查看 Arcade LLM.txt 位于 https://docs.arcade.dev/llms.txt

## 内存管理
- Zep 会话 API: https://api.getzep.com/v2/sessions/{session_id}
- 参考: 查看 Zep API 文档位于 https://docs.getzep.com

## 基础设施与存储
- 用于提示词构件的对象存储: S3, GCS, 或 Azure Blob
- 用于长时间运行工作流的状态持久化

第 1 层(Java) 提供结构,干净简单:

public class CustomerServiceAgent {
    private final Model model;
    private final PromptPack prompts;
    private final ArcadeClient tools;
    private final ZepMemory memory;

    public Response handle(CustomerQuery query) {
        // 检索会话内存
        var history = memory.getSession(query.sessionId());

        // 从 Arcade 获取可用工具
        var availableTools = tools.listTools();

        // 使用上下文渲染提示词
        var context = prompts.render("main", query, history, availableTools);

        return model.complete(context);
    }
}

第 3 层(Cursor) 在几秒钟内生成这段代码。你专注于架构。

第 6 层(架构) 指南:

# 智能体架构指南

## 工作流路由
- 为多节点智能体工作流设计路由逻辑
  - 分类节点 → 路由到专家节点(支持、销售、技术)
  - 复杂性分析 → 路由到适当的模型层级(GPT-4o vs GPT-3.5)
  - 工具选择节点 → 根据用户意图路由到工具执行节点
- 通过 Arcade 网关路由工具执行:集中认证、速率限制、工具发现
- 提示词版本的 A/B 路由:10% 到 v2.0,90% 到 v1.5,监控质量

## 速率限制与节流
- 每用户令牌预算:10K 令牌/天(免费),100K(付费)
- 队列管理:最大 100 个并发请求,溢出到 SQS...
..
..

为什么这个框架能扩展

  • 对于一个关键智能体: 选择你的模型(第 2 层),编写清晰的代码(第 1 层),用 Cursor 迭代(第 3 层),优化提示词(第 4 层),集成生态系统 API(第 5 层),遵循架构模式(第 6 层)。
  • 对于一千个智能体: 相同的模型,相同的架构模式,相同的生态系统 API,但每个智能体都有自己的提示词包。Cursor 生成样板代码。你的语言提供结构。生态系统处理难题。

美妙之处何在?各层协同工作。Cursor 生成代码是因为模式简单。提示词是独立版本控制的。集成使用 REST API。架构无需抽象即可实现重用。

不需要编排框架。这就是框架。

引擎与 SDK 的问题

让我澄清一下:我并不是说所有框架都应该消失。我对 LangChain、LangGraph、Mastra、CrewAI、Autogen 等团队所构建的东西怀有极大的敬意。但我们需要理解一个在急于将所有东西移植到 Java 的过程中被忽视的关键区别。

不要混淆引擎SDK

我的意思是:我迫不及待地想用 Java 开发完整的智能体。我热爱 Java。但我不想仅仅因为我想用 Java 开发智能体就要一个 Java 引擎

考虑这些例子:

  • LangChain4J? 作为连接更广泛的 LangChain 生态系统的 SDK,这是一个很好的开始。你用 Java 编写,但你正在利用一个经过验证的引擎。
  • 带有 Java SDK 的 Crew AI? 完美。在 Python 中掌握编排模式,然后给我一个 Java 接口来使用它们。
  • 支持多语言的 Mastra? 正是正确的方向。构建一次引擎,为每种语言提供 SDK。
  • 为使用 Go 构建的 Not7 添加 Java SDK 或任何语言 SDK?

这里的模式是?用你喜欢的语言开发,而无需用该语言重建整个引擎。

编排层正在变薄

这就是为什么我认为即使是 SDK 方法也可能是暂时的,或者至少变得非常精简的原因:

  • 一方面: 模型正变得 dramatically 更好。GPT-5、Claude 4.5、Gemini 2.5 Pro、Grok 的推理能力使得复杂的编排模式过时了。它们可以用简单的提示词处理多步骤工作流,而这在六个月前需要复杂的链。
  • 另一方面: 真正的工程问题正在由专业平台解决。以 Arcade 为例:工具发现、认证、大规模执行、处理速率限制、管理工具版本。这才是艰难的工程工作所在。工具管理不再是编排问题;它是在平台层解决的基础设施问题。
  • 在中间: 编排框架正被挤压得越来越薄。

当你的模型能够推理工作流,并且平台处理复杂的工程问题(工具、内存、上下文)时,编排还剩下什么?

答案是:非常少。这就是为什么工程重点需要从编排转向更广泛的智能体开发挑战——提示词管理、生态系统集成、工具决策可审计性、成本优化。真正的问题已不在编排之中。

新现实:AI 原生框架

代码坏味道不仅仅是我们构建了太多框架。而是我们正在为一个不复存在的世界构建框架。以下是 2025 年构建框架实际意味着什么:

方面 过去的框架思维模式 (2005-2024) 下一代框架思维模式 (2025+)
定义 需要导入的代码库 跨越6个层级的完整环境
业务逻辑 位于代码抽象中 位于版本化提示词与指南中
关键构件 JAR 文件、软件包 提示词、上下文、API 知识
可重用性 代码继承与组合 架构模式与蓝图
开发工具 用于编写代码的 IDE 用于生成代码的 AI 工具(如 Cursor)
生态系统 自包含、单体式 集成专业化平台
样板代码 由框架抽象处理 由 AI 在几秒内生成
你导入/使用什么 Spring、Camel、框架 JAR 包 无需导入——你只需组合这些层级
  1. 接受 AI 驱动的开发现实 每个构建智能体的开发人员都将使用 Cursor、Copilot 或类似工具。这不是趋势——这是新的基线。设计你的框架以与 AI 代码生成无缝协作,而不是背道而驰。如果 Cursor 无法理解你的模式,那你的模式就是错的。
  2. 你的框架是纯文本英语,而不仅仅是代码 你的框架最关键部分将是精心设计的提示词、清晰的指南和结构化的上下文——而不是聪明的抽象。这些是你的版本化构件。这些决定了智能体行为。像对待代码一样严格对待它们。
  3. 当你需要 SDK 时,不要重新发明引擎 是的,Java SDK 至关重要。但你不需要仅仅为了用 Java 编写智能体就重建整个编排引擎。生态系统已经有平台在解决难题:内存(Zep, Mem0)、工具(MCPs, Arcade)、向量(Weaviate, Pinecone, Qdrant)、可观测性等。集成,不要重建。
  4. 框架仍然至关重要——但不是为了编排 如果你正在解决真正的问题——提示词版本控制、决策可审计性、生态系统集成模式、成本优化——那就构建这些。但编排?生态系统已经向前发展了。内存、工具、上下文、可观测性正由专业平台解决。将你的创新重点放在其他地方。
  5. 相信你的语言 如果你觉得你选择的语言中缺少一个框架,请退后一步。现代语言——Java、Python、TypeScript、Go——非常强大。凭借它们的最新特性加上 AI 代码生成工具,你可以用干净、简单的代码构建复杂的智能体。你的语言不是限制——试图用不必要的抽象包装它才是。

未来的框架不是你导入的代码库。它是对六个相互依赖层的掌握:你的语言、你的模型、你的开发工具、你的提示词、你的生态系统集成和你的架构。

也许我们不需要另一个智能体框架。也许我们所需要的只是一个智能体,一个能用你选择的语言创建智能体的智能体。一个开源的就更好了。


【注】本文译自:Java’s Agentic Framework Boom is a Code Smell

AI智能体是加速器,而非开发者替代品

将AI集成到应用开发中的核心挑战,不在于其协助能力,而在于我们能在多大程度上放心地将控制权委托给它。

尽管AI智能体可以完美地执行那些曾被认为人类专属的任务,但它们同样可能在紧接着的下一段代码中犯下令人震惊的错误。

这些错误尖锐地提醒我们,即使是最先进的AI编程助手,仍然缺乏对世界运行方式的理解。这一根本区别将当前的生成式AI与通用人工智能(AGI)的愿景区分开来。考虑到这一点,让我们来看看AI智能体如何成为出色的开发加速器,却无法取代人类开发者。

LLM的推理并非逻辑推理

即使是复杂的智能体AI——构建于拥有日益庞大的上下文窗口和复杂工作流程的大型语言模型(LLM)之上——也依赖于语义模式匹配。它们无法对底层的因果关系和相互依赖提供真正的洞见。

让人类难以理解这一点的是,LLM在阐述其决策过程时具有令人信服的方式,常常模仿一种逻辑递进,暗示其对因果关系的理解,而实际上它们并不具备这种理解。它们通过拼凑统计上可能性高的人类推理文本片段来实现这一点。虽然这看起来像是逻辑推理,但它基于从训练数据中得出的概率计算,而非对步骤之间因果关系的直接理解。

LLM模仿逻辑推理,但无法掌握因果关系。

将这比作一位主演医疗电视剧的演员,他多年来记住了数千小时的对话、纪录片和真实咨询记录。他可以完美地进行鉴别诊断,像经验丰富的医生一样自信地用专业词汇滔滔不绝地说出症状、检测结果和治疗方案。他知道"向左臂放射的胸痛"通常出现在关于心脏病的场景中,"全血细胞计数和代谢指标组"跟在"我们来做些检查"之后,而担忧的表情伴随着关于肿瘤的讨论。

一位对医疗话题表现出表面理解的医疗剧演员,是比喻AI无法掌握因果关系的绝佳例子。

他们的表演如此令人信服,以至于任何观众都会相信他们懂医。但他们根本不知道阿司匹林为什么能稀释血液,心脏病发作时会发生什么,或者为什么一种治疗有效而另一种会致命。他们只是在背诵他们记住的各种医疗对话的变体,拼凑那些在统计上共同出现的片段,却不理解这些模式代表了真实的生物过程,其中顺序和因果关系 literally 意味着生与死。翻译到应用开发中,这通常意味着出色的结果之后紧接着灾难性的失败,反之亦然。

统计模式而非因果真相

LLM非常擅长在难以想象的大量文本中寻找并连接模式。尽管这些文本中有许多描述了世界的运作方式,但LLM并不理解这些描述的实际含义。相反,它将文本转换成数字——向量——这些数字捕获的是统计关系,而非因果真相。然后,模型将这些数字翻译回人类语言,而在这一切之下,它始终只是在跟踪和 shuffling 数字,而不是意义。例如,"charge"、"payment"和"credit card"这些词可能在向量空间中位置接近,因为它们经常在文本中共同出现,而"profile"、"lookup"和"fetch"则形成另一个集群——但模型实际上并不知道一组涉及金钱,而另一组不涉及。

LLM只处理词组之间的统计关系。

事物并非表面所见

由于编程语言是高度结构化的,这种数值上的 shuffling 可以产生优秀的代码。虽然AI模型并不像开发者那样"理解"代码,但它可以可靠地将输入模式映射到输出,将框架映射到样板代码,将语法映射到语义,其方式常常看起来与人类代码无异。例如,当被要求"用Python和Flask构建一个REST API"时,模型无法推理HTTP或数据库——它只是回忆起@app.route通常出现在函数定义之前,GET请求常常映射到返回jsonify,而错误处理经常涉及try/except块。结果往往是结构良好的Flask代码,即使它源于模式回忆而非真正的理解。

人类需要保持在循环中,以应对AI缺失的上下文和推理能力。

例如,为重试逻辑加固微服务听起来很简单——然而实际情况并非如此。要求AI助手"在失败时添加重试",你可能会得到一段在任何错误时都重试所有操作的代码。这对于幂等的(或无状态的)读取操作(例如"获取配置文件")来说没问题,因为重复调用只会返回相同的数据。
将相同的逻辑应用于非幂等操作——扣款、创建订单、发送电子邮件、查询数据库——你就会招致灾难:重复扣款、重复订单、通知风暴、数据库中的重复记录。解决方法并非魔术,而是判断力。人类首先对操作进行分类——幂等与非幂等——仅在瞬态错误时重试,并且对于任何有副作用的操作,都需要幂等性密钥和服务端去重。虽然这仍然为人类开发者节省大量时间,但他们仍然需要将其技能和专业知知融入其中,否则灾难可能并且将会随机发生。

理解模式匹配的局限性很棘手

原则上,模式匹配难道不能识别出对信用卡扣款需要采用与检索客户资料或产品信息不同的API调用重试方法吗?是的,它可以,但人类无法事先知道这一点,因为这取决于该特定模型的训练数据是否包含了执行标准POST或GET请求的重试函数。
模型未能建立操作类型与其现实后果之间的联系;它仅仅回忆统计关联。为了让模型避免这个错误,训练数据需要包含清晰、一致且重复出现的配对,将操作类型与重试策略及其后果联系起来。
理想情况下,数据会明确对比可以安全重试的代码与必须避免重试的代码。或许它还包括了事后分析或警告,描述了误用重试时发生的情况。然而,模型是否摄入了足够的训练数据来做出这种区分,我们人类无法确定。更棘手的是,由于其概率性质,模型可能在某一次做出了区分,但在接下来的三次尝试中却没有。
这个例子说明了为什么简单地添加更多训练数据通常不是答案,因为必要的数据可能并不以书面形式存在。或者更糟的是,训练数据可能包含了强化错误概括的内容。无论哪种情况,人类用户都无法知道是否如此,并且需要全面理解特定问题应如何解决。

AI的价值是真实的,开发团队可以受益

只要清楚地理解其局限性,AI智能体可以显著提高人类开发者在整个开发生命周期中的生产力。从收集需求并将其转化为用户故事,一直到检测并部署应用程序,AI智能体可以为人类提供建议、自动化验证和快速原型设计,从而显著缩短迭代周期。
AI智能体应被视为力量倍增器,可以处理开发的机械性方面,例如基于现有示例和文档生成样板代码、编写测试用例和记录API。另一方面,人类则负责真正理解业务影响、决定架构权衡,以及解决需要应用抽象逻辑能力的复杂问题。

AI对SDLC的生产力影响

下表分析了AI对软件开发生命周期(SDLC)中不同活动的生产力影响,以及AI对每项活动的能力、所需的人力参与程度和每项活动的风险水平。

AI对SDLC活动的生产力影响

活动 AI的生产力影响 AI能力描述 人力参与需求 风险水平
需求收集 低 – 中 根据笔记、会议记录、电子邮件和其他材料生成用户故事。 高 – 确保故事在成本、风险和回报方面与当前业务优先级保持一致。 高 – 被误解的需求将贯穿整个项目。
架构与设计 建议模式、识别瓶颈并生成初始图表,作为人类构建的坚实起点。 关键 – 考虑系统范围影响、做出战略权衡并监控技术趋势。 高 – 糟糕的架构决策难以逆转且成本高昂。
代码生成 构建定义良好的样板代码并解决精确定义的问题。保持文档更新。 中 – 掌控业务逻辑和边缘情况。 中 – 通常难以完全掌控AI编写的代码。
代码审查 捕获语法错误、发现安全漏洞、发现性能问题并建议优化。 高 – AI会遗漏依赖于上下文的问题和架构问题。 中 – 人类需要对审查负全责。
测试 创建单元测试、集成测试、自动化回归测试并发现边缘情况。 低 – 对于测试生成,但 高 – 对于测试策略。 中 – 人类必须对测试的完整性和相关性负责。
调试 分析堆栈跟踪并就已知错误建议修复方法。 中 – 指导调试过程。 低 – 错误的修复通常很容易发现。
文档编写 生成API文档、自述文件、内联注释、用户指南和变更日志。 低 – 对于面向用户的文档。 低 – 不正确的文档通常可以在没有重大影响的情况下得到纠正。
部署与CI/CD 创建部署清单、构建IaC模板、生成流水线配置。 高 – 生产部署需要仔细检查。 高 – 任何问题都会直接影响生产环境。
监控 添加检测、分析日志并生成警报规则。 中 – AI在没有上下文的情况下难以确定优先级。 中 – 误报会浪费时间。

来源:Torsten Volk, Omdia • 获取数据 • 使用 Datawrapper 创建

结论

宣布AI智能体正在接管开发者工作的技术领导者们,对AI当前能力产生了不切实际的期望。这导致许多企业高管认为开发者工时不再是他们所能构建内容的限制因素。金融分析师可以创建自己的投资组合再平衡工具;医疗保健管理员可以构建患者排班系统;供应链经理可以开发库存优化仪表板;或者营销总监可以构建个性化的活动自动化平台,而无需编写一行代码。虽然他们可以为许多此类业务任务实现概念验证,但架构、开发和交付企业级软件仍然极大地依赖于人类开发者的技能和经验。
然而,AI智能体可以通过为人类开发者完成大量基础性工作来显著加速SDLC。创建测试用例、用监控代理自动检测复杂软件、记录数万行主机代码以及精确定义复杂的基础设施清单,仅仅是AI智能体可以帮助人类开发者的几个例子。
人类与AI智能体之间的SDLC必须是协作的、迭代的并接受持续监督。确定如何最优地调整流程、开发工具和企业文化以满足这些要求,是智能体辅助应用开发的下一个前沿领域。弄清楚如何为人类编码者提供最佳AI支持,其回报有望带来显著的生产力提升,使人类开发团队能够更快、更高质量地交付更多功能。


[注]本文译自: AI agents are accelerators, not developer replacements