Ohhnews

分类导航

$ cd ..
Jetbrains Blog原文

JetBrains发布企业级Java AI智能体框架:Koog for Java

#人工智能#java#软件开发#智能体框架#企业级应用

在企业后端引入 AI Agent 不应以牺牲架构为代价。如果你的核心系统是基于 Java 构建的,那么编排大语言模型(LLM)就不应该强迫你引入独立的 Python 微服务或重写整个技术栈。

今天,我们正式推出 Koog for Java。Koog 最初是为了跟上 JetBrains 自身业务扩展的步伐而构建的,它能够取代不可预测、临时性的提示词变更,转而采用结构化、可观测且具备容错能力的 Agent 工作流。

现在,JVM 领域最强大的 Agent 框架之一正式支持完全地道的 Java API。你的 Java 团队可以直接在现有的后端中构建可靠的 AI Agent,并利用流式构建器(Builder)风格的 API、线程池执行器以及原生 Java 抽象,彻底摆脱 Kotlin 特有的兼容性摩擦。

Koog for Java 的核心功能

Java API 提供了对 Koog 所有功能的完全访问权限:

  • 多种工作流策略(函数式、基于图及基于规划):精确控制 Agent 执行任务的方式。
  • Spring Boot 集成:将 Koog 无缝集成到现有的 Spring 应用中。
  • 支持所有主流 LLM 提供商:使用你首选的模型,包括 OpenAI、Anthropic、Google、DeepSeek、Ollama 等。
  • 具备持久化功能的容错机制:在发生故障时自动恢复,无需丢失进度或重复执行昂贵的 LLM 调用。
  • 基于 OpenTelemetry 的可观测性:全面洞察 Agent 执行过程、Token 使用量及成本,并开箱即用支持 Langfuse 和 W&B Weave。
  • 历史记录压缩:在大规模场景下减少 Token 使用量并优化成本。
  • 更多特性!

请继续阅读,了解如何使用 Koog 在 Java 中构建 Agent。

简单易用的设置

AI Agent 的工作原理是将大语言模型(LLM)与应用程序中的函数(通常称为“工具”)连接起来。LLM 会根据你给出的任务,决定调用哪些工具以及何时调用。在 Java 中构建 Agent,首先需要定义这些工具。使用 @Tool 注解标注现有的 Java 方法,并添加描述,以便 LLM 理解每个函数的功能:

$ java
public class BankingTools implements ToolSet {
    @Tool
    @LLMDescription("向收款人汇款")
    public Boolean sendMoney(
        @LLMDescription("收款人的唯一标识符")
        String recipientId,
        Integer amount
    ) {
        return true; // 在此添加你的实现
    }

    @Tool
    @LLMDescription("查询账户余额(美元)")
    public Integer getAccountBalance(String userId) {
        return 1000000; // 在此添加你的实现
    }
}

接下来,使用构建器 API 创建一个 Agent。你需要配置所使用的 LLM 提供商(OpenAI、Anthropic 等)、设置定义 Agent 角色的系统提示词(System Prompt),并注册你的工具:

$ java
// 连接到一个或多个 LLM 提供商
var promptExecutor = new MultiLLMPromptExecutor(
    new OpenAILLMClient("OPENAI_API_KEY"),
    new AnthropicLLMClient("ANTHROPIC_API_KEY")
);

// 构建 Agent
var bankingAgent = AIAgent.builder()
    .promptExecutor(promptExecutor)
    .llmModel(OpenAIModels.Chat.GPT5_2)  // 选择要使用的模型
    .systemPrompt("你是一名银行助理")      // 定义 Agent 的角色
    .toolRegistry(
        ToolRegistry.builder()
            .tools(new BankingTools())  // 注册工具
            .build()
    )
    .build();

// 使用用户任务运行 Agent
bankingAgent.run("如果我有足够的钱,转 100 美元给我的朋友 Mike (mike_1234)");

当你运行该 Agent 时,它会:

  1. 使用 getAccountBalance() 检查账户余额。
  2. 如果资金充足,使用正确的参数调用 sendMoney()
  3. 向用户返回响应。

这实现了将 Java 应用的功能与完全自主的 AI Agent 连接起来,使其能够自主判断应采取哪些行动。

通过自定义策略实现可预测的工作流

上面的简单示例让 LLM 决定一切——调用哪些工具以及顺序如何。但在生产系统中,你通常需要更多的控制权。例如,如果你想确保某些操作在其他操作之前执行?或者限制每一步可用的工具?又或者实现验证循环?

Koog 提供了不同的方式来定义 Agent 工作流:函数式(基于代码)、基于图(Graph-based)以及基于规划(Planning-based)。

函数式策略允许你在代码中编排单个 Agent 执行步骤。这就像编写普通的 Java 方法,但每一步都可以涉及 LLM 调用和工具执行。你可以将大型任务拆分为较小的子任务,每个子任务都有自己的提示词、受限的工具集以及类型安全的输入/输出:

$ java
var functionalAgent = AIAgent.builder()
    .promptExecutor(promptExecutor)
    .functionalStrategy("my-strategy", (ctx, userInput) -> {
        // 第一步:识别问题
        // 此处仅授予 Agent 通信和只读数据库访问权限
        ProblemDescription problem = ctx
            .subtask("识别问题: $userInput")
            .withOutput(ProblemDescription.class)  // 类型安全输出
            .withTools(communicationTools, databaseReadTools)  // 受限工具
            .run();

        // 第二步:解决问题
        // 仅在问题识别后授予 Agent 数据库写入权限
        ProblemSolution solution = ctx
            .subtask("解决问题: $problem") // 使用第一步的输出
            .withOutput(ProblemSolution.class)
            .withTools(databaseReadTools, databaseWriteTools)
            .run();

        // 验证解决方案,直到满意为止
        while (true) {
            var verificationResult = ctx
                .subtask("验证问题是否已解决: $solution")
                .withVerification()
                .withTools(communicationTools, databaseReadTools)
                .run();

            if (verificationResult.isSuccessful()) {
                return problemSolution;
            } else {
                problemSolution = ctx
                    .subtask("根据提供的反馈修复解决方案: ${verificationResult.getFeedback()}")
                    .withOutput(ProblemSolution.class)
                    .withTools(databaseReadTools, databaseWriteTools)
                    .run();
            }
        }
    })
    .build();

这种方法在利用 AI Agent 进行单步执行的同时,赋予了你代码级的灵活性。你可以控制操作顺序以及每一步可用的工具。点击此处查看完整的可运行示例。

基于图的策略将工作流定义为具有类型安全节点和边的有限状态机。与函数式策略不同,图策略将逻辑(节点和边)与执行分离。这实现了强大的持久化功能——如果 Agent 崩溃,它可以从停止的确切节点恢复,而不是从头开始:

$ java
var graphAgent = AIAgent.builder()
    .graphStrategy(builder -> {
        var graph = builder
            .withInput(String.class)
            .withOutput(ProblemSolution.class);

        // 定义工作流元素:单个节点(步骤)和子图
        var identifyProblem = AIAgentSubgraph.builder()
            .withInput(String.class)
            .withOutput(ProblemDescription.class)
            .limitedTools(communicationTools, databaseReadTools)
            .withTask(input -> "识别问题")
            .build();

        // ... 连接节点和边
        graph.edge(graph.nodeStart, identifyProblem);
        // ...
        return graph.build();
    })
    .build();

当你需要持久化、复杂的逻辑分支或希望可视化 Agent 工作流时,图策略是理想选择。你可以分享可视化图表并与机器学习同事进行探讨。点击此处查看完整示例。

基于规划的策略使用目标导向动作规划(GOAP)或基于 LLM 的规划。你无需定义精确的执行顺序,只需定义:

  • 带有前提条件的可用动作(何时可以运行)
  • 效果(它们如何改变 Agent 的状态)
  • 目标条件(Agent 应该达成什么结果)

规划器会自动计算出达到目标的最佳执行顺序。这对于存在多条可行路径或需求动态变化的复杂场景非常有效。点击此处查看详细示例。

持久化以实现容错

AI Agent 经常处理复杂的、耗时数秒甚至数分钟的多步任务。在此期间,服务器可能会崩溃、网络连接可能会中断或发生部署。如果没有持久化,Agent 就必须从头开始,浪费时间和金钱。

Koog 的持久化功能在每一步之后将 Agent 状态保存到磁盘、S3 或数据库。如果发生故障,基于图的 Agent 可以从停止的确切位置恢复。它会还原到上一个节点并保留故障前取得的所有进展。

基于 OpenTelemetry 的可观测性

在生产环境中运行 Agent 时,你需要了解它们正在做什么。它们调用了哪些工具?每个 LLM 请求使用了多少 Token?瓶颈在哪里?成本来自何处?

Koog 与 OpenTelemetry 集成以提供这种可见性。连接到 LangfuseW&B Weave 等后端,即可查看 Agent 执行的详细追踪信息,包括嵌套事件、Token 计数、成本和计时信息。

历史记录压缩

随着 Agent 处理复杂的任务,对话历史会随着每次 LLM 调用和工具调用而增长。每次后续请求都会发送此历史记录以提供上下文,但上下文过长意味着:

  • LLM 响应变慢
  • 成本增加(按 Token 付费)
  • 最终触及上下文窗口限制

Koog 的历史记录压缩通过智能总结或提取历史记录中的关键信息来解决此问题,在减少 Token 使用量的同时保留重要内容。

管理 Java 线程

在典型的 Java 应用中,你通常需要对线程池进行细粒度控制。Koog 允许你为 Agent 执行的每个部分指定独立的 ExecutorService,从而优化资源使用,例如为 I/O 密集型的 LLM 请求使用较大的池,而为策略执行逻辑保留较小的池。

尝试 Koog for Java

Koog for Java 通过自然且地道的 API,将企业级的 Agent 工程能力带入你的 Java 应用中。无论你是要构建简单的工具调用 Agent,还是需要持久化和可观测性的复杂多步工作流,Koog 都能提供你所需的抽象。

点击此处开始体验:https://docs.koog.ai/