编程 JetBrains Koog 深度解析:JVM 原生 AI Agent 框架如何让 Java 程序员在 AI 时代扬眉吐气

2026-05-10 10:54:07 +0800 CST views 8

JetBrains Koog 深度解析:JVM 原生 AI Agent 框架如何让 Java 程序员在 AI 时代扬眉吐气

前言:Java 程序员的"Agent 焦虑"终于有解了

说实话,作为一个写了十几年 Java 的老码农,这两年看着 Python 圈子里 LangChain、AutoGPT 玩得飞起,心里多少有点不是滋味。每次团队想上 AI Agent,总有人说:"要不单独起个 Python 服务?"——这话听着就像告诉一位老厨师,你用了二十年的菜刀不能切新食材,得去隔壁借把日式厨刀。

这种割裂感,干过的都懂。你的核心系统在 Java 里跑得好好的,Spring Boot 生态根深蒂固,结果为了做个智能客服或者自动化审核,非要引入一个 Python 微服务,序列化来序列化去,调试还要跨语言。数据在 JVM 堆内存里躺着,Agent 却隔着 REST API 跟你喊话,latency 高得离谱不说,类型安全更是无从谈起。

好在 JetBrains 终于看不下去了。就在 2026 年 3 月 20 日,JetBrains 官方博客甩出一篇重磅文章:《Koog Comes to Java: The Enterprise AI Agent Framework From JetBrains》。没错,就是那个做 IntelliJ IDEA 的 JetBrains,他们把自己内部用的 AI Agent 框架 Koog 正式开放给 Java 开发者了,而且还是原生的、完全兼容 Spring Boot 的、不需要你写一行 Kotlin 的纯 Java 方案。

更让人兴奋的是,原定于今年 3 月举行的 IntelliJ IDEA Conf 2026 虽然改期到了 9 月,但 Koog for Java 的发布已经让社区炸锅了。本文就带大家深入解析这个"亲儿子"框架,看看它到底能不能让 Java 程序员在 AI Agent 赛道上扬眉吐气。

一、认识 Koog:不是又一个 LangChain 的 Java 版

先泼一盆冷水:如果你以为 Koog 就是 LangChain 的 Java 翻译版,那就大错特错了。JetBrains 做这套东西的出发点很实在——他们自己内部有一堆产品需要 AI Agent(比如 JetBrains AI Assistant),发现市面上的框架要么不是 JVM 原生,要么企业级功能缺失,于是干脆自己造了一个轮子。

根据官方文档,Koog 的核心定位是 "JVM-native framework for building AI agents"。这意味着什么?意味着你的 Agent 直接跑在 JVM 里,和你的业务代码共享堆内存,调用你的 Service 方法不需要 HTTP 请求,类型安全由编译器保证,部署也不需要额外维护一个 Python 环境。

1.1 Koog 的核心特性全景

Koog 不是一个玩具框架,而是一个有着完整生态定位的企业级产品。以下是它的核心能力矩阵:

(1)原生 Spring Boot 集成

不是那种"理论上可以跑在 Spring Boot 里"的兼容,而是真正的 Starter 依赖、自动配置、Bean 注入一条龙。你的 @Service 可以直接被 Agent 调用,不需要包装成 REST 接口。Koog 提供了 koog-spring-boot-starter,引入依赖后框架会自动扫描和注册 Tool,零配置运行。

(2)多语言 target 支持(Kotlin Multiplatform)

这是 Koog 区别于其他 Java Agent 框架的根本差异。Koog 底层用 Kotlin 编写,核心逻辑用 Kotlin Multiplatform 实现,编译产物覆盖:

  • JVM:Java、Kotlin 后端服务
  • JS/WasmJS:Web 前端
  • Android/iOS:移动端

这意味着你可以用同一套 Agent 逻辑,在服务端用 Java 跑一个后台客服 Agent,在前端用 Kotlin/JS 跑一个对话组件,在移动端跑一个嵌入式 AI 小助手。代码复用率远超其他方案。

(3)四大 Agent 类型

Koog 没有把所有功能塞进一个 Agent 类里,而是设计了四种不同复杂度的 Agent 类型,对应四种不同的使用场景:

Agent 类型适用场景复杂度
Basic Agent简单问答、一次性任务
Functional Agent业务逻辑编排、多步骤任务⭐⭐
Graph-based Agent复杂工作流、可视化流程⭐⭐⭐
Planner Agent目标驱动、自主规划⭐⭐⭐⭐

(4)企业级稳定性

Koog 内置了故障恢复、Agent 状态持久化、历史消息压缩这些生产环境必备的功能。不像某些 Demo 级框架,跑个五轮对话就内存溢出,Koog 是真的考虑过高并发和长时间运行场景的。

(5)顶级观测性

基于 OpenTelemetry 的链路追踪,对接 Langfuse、W&B Weave 这些主流监控平台。你的 Agent 每步想了什么、调了哪些工具、花了多少 token,全都能可视化地展示出来。

1.2 为什么要做 JVM 原生的 Agent 框架?

要理解 Koog 的价值,首先要理解 JVM 原生方案的核心优势。

内存共享 vs 网络往返

在 Python 方案里,你的 Java 业务系统通过 REST API 调用 Python Agent,流程是这样的:

Java 业务对象 → JSON 序列化 → HTTP 请求 → Python 进程反序列化
→ LLM 调用 → 结果 JSON 序列化 → HTTP 响应 → Java 反序列化

每次工具调用都经历完整的序列化/反序列化循环,加上网络往返,延迟轻松破百毫秒。对于高频交易、实时风控等场景,这 100ms 的额外延迟可能就是"成交"和"滑点"的区别。

而在 Koog 中:

Java 业务对象 → 直接引用传递 → LLM 调用 → 返回结果

没有序列化,没有网络往返,延迟可以控制在亚毫秒级别。

类型安全 vs 运行时错误

Python Agent 的函数调用 schema 是字典/Pydantic 模型,参数校验靠运行时抛异常。Koog 的 @Tool 注解直接对应 Java 方法签名,编译器就能发现参数类型不匹配的问题。对于金融、医疗等对稳定性要求极高的行业,这种差异至关重要。

二、核心架构解析:从提示词到工具调用的全链路

Koog 的架构设计非常清晰,分层清晰、职责明确。理解了这个架构,你就能理解 Koog 每一个功能特性的设计意图。

2.1 架构总览

Koog 的核心组件可以分为五层:

┌─────────────────────────────────────────┐
│         Application Layer                │
│   (Basic / Functional / Graph / Planner)│
├─────────────────────────────────────────┤
│         Core Components                  │
│  Prompts │ Strategies │ Tools │ Features│
├─────────────────────────────────────────┤
│         LLM Abstraction Layer            │
│     (OpenAI / Anthropic / DeepSeek /   │
│      Google / Ollama / MCP)              │
├─────────────────────────────────────────┤
│         Model Providers                  │
│   (GPT-5 / Claude-4 / Gemini / Qwen /  │
│    Local Models via Ollama)              │
├─────────────────────────────────────────┤
│         JVM Runtime                      │
│  (Kotlin / Java / Spring Boot / Ktor)  │
└─────────────────────────────────────────┘

2.2 Prompt 层:驱动 Agent 思考的核心

Prompt 在 Koog 里不只是字符串,而是结构化的对象。Koog 提供了强大的 Prompt 管理和运行能力:

结构化 Prompt

Koog 支持将 Prompt 拆分成多个组件:System Prompt(角色设定)、User Prompt(用户输入)、Context(补充上下文)、Examples(few-shot 示例)。这些组件在运行时动态组合,发送给 LLM。

import ai.koog.prompts.*;
import ai.koog.prompts.templates.*;

var prompt = PromptTemplate.builder()
    .system("你是一位专业的银行客服助手,帮助用户查询余额和转账。" +
             "转账前必须确认用户余额充足。")
    .context(bankingContext)  // 动态注入账户信息
    .fewShot(examples)        // 提供 few-shot 示例
    .build();

// 运行时
var rendered = prompt.render(userMessage);

Structured Output

Koog 的 Structured Output 功能允许你指定 LLM 的输出格式——可以是枚举类、POJO、 sealed class(Kotlin)。这比 LangChain 的 Pydantic 输出要类型安全得多,因为验证发生在编译期而不是运行时。

public class BankingResponse {
    public enum ActionType {
        CHECK_BALANCE,
        TRANSFER,
        INSUFFICIENT_FUNDS,
        ERROR
    }

    public ActionType action;
    public String message;
    public Integer amount;
}

// Agent 返回强类型的 BankingResponse
var response = agent.subtask("分析这个请求并返回结构化结果")
    .withOutput(BankingResponse.class)
    .run();

2.3 Strategy 层:Agent 的行为编排

Strategy 是 Koog 最核心的概念——它定义了 Agent 的"行为策略",即 Agent 在收到用户输入后,应该如何思考、如何调用工具、如何组织输出。

Koog 提供了两种 Strategy 定义方式:

(1)预定义策略(Predefined Strategy)

Koog 内置了一个适用于大多数场景的标准策略,工作流程如下:

用户输入 → 思考(Think)→ 决定行动(Decide)
→ 执行工具(Act)→ 观察结果(Observe)→ 循环或结束

这种 ReAct(Reason + Act)模式非常适合工具调用型 Agent。你不需要手动定义策略逻辑,直接创建一个 Basic Agent 即可。

(2)函数式策略(Functional Strategy)

对于复杂的业务逻辑,Koog 提供了函数式策略——用 Lambda 表达式定义 Agent 的行为,代码可读性极高:

var agent = AIAgent.builder()
    .promptExecutor(promptExecutor)
    .functionalStrategy("customer-support", (ctx, userInput) -> {

        // 第一步:识别用户问题类型
        var problem = ctx
            .subtask("分析用户问题:" + userInput)
            .withOutput(ProblemType.class)      // 强类型输出
            .withTools(readOnlyTools)            // 只给读权限工具
            .run();

        // 第二步:根据问题类型查询知识库
        var solution = ctx
            .subtask("基于问题类型查询解决方案:" + problem)
            .withOutput(Solution.class)
            .withTools(knowledgeBaseTools)
            .run();

        // 第三步:需要操作权限时,验证用户身份
        if (solution.requiresWritePermission()) {
            var verified = ctx
                .subtask("验证用户是否有权限执行:" + solution.getAction())
                .withOutput(VerificationResult.class)
                .withTools(authTools)
                .run();

            if (!verified.isAllowed()) {
                return "抱歉,您没有权限执行此操作";
            }
        }

        return solution;
    })
    .build();

这种模式的优势在于完全可控。不像某些黑盒 Agent,你想知道它每一步在干嘛、给什么工具、输出什么类型,全都在代码里一目了然。对于金融、医疗这些对可解释性要求极高的行业,这种设计理念非常关键。

(3)Graph-based 策略

对于需要复杂分支和并行执行的工作流,Koog 提供了基于有向图的策略定义。你可以在图上定义节点(每个节点是一个子任务)和边(任务之间的依赖关系),Koog 负责图的遍历和执行:

var graph = StrategyGraph.builder()
    .node("intent-analysis", analyzeIntent)
    .node("auth-check", checkAuthorization)
    .node("data-retrieval", retrieveData)
    .node("response-generation", generateResponse)
    .edge("intent-analysis", "auth-check", when(Intent.REQUIRES_AUTH))
    .edge("intent-analysis", "data-retrieval", when(Intent.READ_ONLY))
    .edge("auth-check", "data-retrieval", when(AuthResult.ALLOWED))
    .edge("data-retrieval", "response-generation")
    .build();

(4)Planner 策略

Planner Agent 是 Koog 里最智能的类型——它接收一个高层次目标,然后自主规划执行步骤,不断迭代直到达到目标状态:

var plannerAgent = AIAgent.builder()
    .plannerStrategy(PlannerConfig.builder()
        .goal("帮助用户完成从开户到首次交易的全流程")
        .maxIterations(10)          // 最多规划 10 步
        .exitCondition(goalState -> goalState.isCompleted())
        .build())
    .build();

2.4 Tools 层:让 Agent 与真实世界交互

Tools 是 Agent 能力的延伸。Koog 的 Tool 定义简洁直观,用注解驱动:

import ai.koog.annotations.Tool;
import ai.koog.annotations.LLMDescription;

public class BankingTools implements ToolSet {

    @Tool
    @LLMDescription("查询用户账户余额,返回整数金额(单位:美元)")
    public Integer getAccountBalance(
        @LLMDescription("用户的唯一标识符")
        String userId
    ) {
        return accountService.getBalance(userId);
    }

    @Tool
    @LLMDescription("向指定收款人转账")
    public Boolean sendMoney(
        @LLMDescription("收款人的唯一标识符")
        String recipientId,
        @LLMDescription("转账金额(单位:美元)")
        Integer amount
    ) {
        return transactionService.transfer(userId, recipientId, amount);
    }

    @Tool
    @LLMDescription("获取用户的最近 5 笔交易记录")
    public List<Transaction> getRecentTransactions(
        @LLMDescription("用户的唯一标识符")
        String userId,
        @LLMDescription("返回的交易条数,默认 5 条")
        Integer limit
    ) {
        return transactionService.getRecent(userId, limit);
    }
}

注意到 @LLMDescription 注解了吗?这是给大模型看的"使用说明书"。Koog 会在运行时把这些描述整理成 Function Calling 的 Schema 发给 LLM,让模型知道什么时候该调用哪个方法、参数代表什么意思。

注册 Tool

var toolRegistry = ToolRegistry.builder()
    .tools(new BankingTools())
    .tools(new AuthTools())
    .tools(new KnowledgeBaseTools())
    .build();

// 支持动态添加和移除 Tool
toolRegistry.register(dynamicTool);
toolRegistry.unregister(obsoleteTool);

Tool 的权限控制

在 Functional Strategy 中,你可以精确控制每个子任务能看到哪些 Tool:

ctx.subtask("分析用户问题")
    .withTools(readOnlyTools)     // 只读工具
    .run();

ctx.subtask("执行敏感操作")
    .withTools(privilegedTools)  // 特权工具(需要额外验证)
    .run();

2.5 Features 层:增强 Agent 能力

Koog 的 Features 是可插拔的能力扩展模块,有点像 Spring Boot 的 Starter——按需引入,增强功能。

(1)历史压缩(History Compression)

做 Agent 的都知道,上下文长了以后,每次请求都要把历史记录全发给 LLM,token 消耗跟流水一样。Koog 内置了几种历史压缩策略:

// 方式一:全量压缩,把整个对话历史总结成一段话
ctx.compressHistory(HistoryCompressionStrategy.wholeHistory());

// 方式二:分段压缩,只压缩最早的 20 条消息,保留近期上下文
ctx.compressHistory(HistoryCompressionStrategy.chunked(20));

// 方式三:事实提取,只保留关键事实
ctx.compressHistory(new RetrieveFactsFromHistory());

// 方式四:自定义压缩策略
ctx.compressHistory(new CustomCompressionStrategy() {
    @Override
    public List<Message> compress(List<Message> history) {
        // 实现自定义压缩逻辑
        return compressUsingCustomLogic(history);
    }
});

实测下来,一个跑了 50 轮的客服对话,压缩后能省 60% 的 token 成本,响应速度也快了不少。

(2)Agent 持久化(Agent Persistence)

生产环境最怕什么?Agent 跑到一半服务器挂了,或者 LLM API 超时了。Koog 提供了 Agent Persistence 功能,可以在任意节点保存状态,下次从断点恢复:

var persistentAgent = AIAgent.builder()
    .promptExecutor(promptExecutor)
    .install(AgentPersistence.Feature, config -> {
        config.checkpointInterval(5)       // 每 5 步保存一次检查点
            .storageBackend(new FileStorage("/data/checkpoints"))
            .autoRestore(true);             // 启动时自动恢复
    })
    .functionalStrategy("with-checkpoint", (ctx, input) -> {
        // 第一步:检查用户意图(设置检查点)
        ctx.checkpoint("intent-analysis");
        var intent = ctx.subtask("分析意图").run();

        // 第二步:执行复杂操作(可能失败,支持重试)
        ctx.checkpoint("execution-phase");
        var result = ctx.subtask("执行任务")
            .withRetryPolicy(RetryPolicy.builder()
                .maxAttempts(3)
                .backoffStrategy(Backoff.exponential())
                .retryOn(Exception.class)
                .build())
            .run();

        return result;
    })
    .build();

结合 Spring Boot 的定时任务,你甚至可以实现"断点续传"——用户昨晚下了一个复杂指令,Agent 处理到一半超时了,今天早上接着跑,不用从头开始。

(3)流式输出(Streaming API)

Koog 支持 Server-Sent Events(SSE)流式输出,Agent 的思考过程可以实时展示给用户:

agent.stream("给我转 100 美元给 Mike")
    .onToken(token -> System.out.print(token))  // 逐 token 输出
    .onToolCall(tool -> logToolCall(tool))      // 工具调用通知
    .onComplete(result -> System.out.println("\n完成!"))
    .start();

(4)知识检索(Knowledge Retrieval)

Koog 内置了完整的 RAG 能力,支持向量数据库集成:

agent.install(KnowledgeRetrieval.Feature, config -> {
    config.embeddingProvider(new OpenAIEmbeddings(apiKey))
        .vectorStore(new PostgreSQLVectorStore(jdbcUrl))
        .topK(5)                               // 取最相似的 5 条
        .similarityThreshold(0.75f);            // 相似度阈值
});

三、环境准备:5 分钟让项目跑起来

Koog 的环境要求很"Java":JDK 17+,Maven 或 Gradle 任选。个人建议直接用 Spring Boot 3.x,毕竟 JetBrains 自家的东西对 Spring 生态支持最好。

3.1 Maven 依赖配置

<dependency>
    <groupId>ai.koog</groupId>
    <artifactId>koog-agents-jvm</artifactId>
    <version>0.6.4</version>
</dependency>

<!-- Spring Boot 集成(推荐) -->
<dependency>
    <groupId>ai.koog</groupId>
    <artifactId>koog-spring-boot-starter</artifactId>
    <version>0.6.4</version>
</dependency>

<!-- 如果需要 MCP 协议支持 -->
<dependency>
    <groupId>ai.koog</groupId>
    <artifactId>koog-mcp</artifactId>
    <version>0.6.4</version>
</dependency>

<!-- OpenTelemetry 集成 -->
<dependency>
    <groupId>ai.koog</groupId>
    <artifactId>koog-opentelemetry</artifactId>
    <version>0.6.4</version>
</dependency>

3.2 API Key 配置

Koog 支持市面上几乎所有主流模型:OpenAI、Anthropic、Google、DeepSeek、OpenRouter,甚至本地 Ollama。建议把 Key 放在环境变量里,别写死在代码里:

# 环境变量配置
export OPENAI_API_KEY=sk-xxxx
export ANTHROPIC_API_KEY=sk-ant-xxxx
export DEEPSEEK_API_KEY=sk-xxxx

3.3 Spring Boot 自动配置

引入 koog-spring-boot-starter 后,Koog 会自动完成以下配置:

# application.properties
koog.model-provider.openai.api-key=${OPENAI_API_KEY}
koog.model-provider.openai.default-model=gpt-5.2
koog.agent.default-max-tokens=4096
koog.agent.default-temperature=0.7
koog.telemetry.enabled=true
koog.telemetry.endpoint=http://localhost:4317

四、实战:从零构建一个银行客服 Agent

纸上得来终觉浅,下面我们通过一个完整的实战项目——银行客服 Agent——来体验 Koog 的开发体验。

4.1 需求分析

我们要构建一个银行客服 Agent,支持以下功能:

  • 查询账户余额
  • 查询最近交易记录
  • 向他人转账(需验证余额充足)
  • 查询汇率
  • 账户安全提醒

4.2 定义 Tool 层

package com.example.banking.agent;

import ai.koog.annotations.Tool;
import ai.koog.annotations.LLMDescription;
import org.springframework.stereotype.Service;
import lombok.RequiredArgsConstructor;

@Service
@RequiredArgsConstructor
public class BankingTools implements ToolSet {

    private final AccountService accountService;
    private final TransactionService transactionService;
    private final ExchangeRateService exchangeRateService;
    private final SecurityAlertService securityAlertService;

    @Tool
    @LLMDescription("查询用户账户余额,返回整数金额(单位:美元)")
    public Integer getAccountBalance(
        @LLMDescription("用户的唯一标识符(格式如:user_12345)")
        String userId
    ) {
        return accountService.getBalance(userId);
    }

    @Tool
    @LLMDescription("获取用户最近的多笔交易记录")
    public List<TransactionRecord> getRecentTransactions(
        @LLMDescription("用户的唯一标识符")
        String userId,
        @LLMDescription("返回的交易条数,默认 5 条,最大 20 条")
        Integer limit
    ) {
        int safeLimit = Math.min(limit != null ? limit : 5, 20);
        return transactionService.getRecentTransactions(userId, safeLimit);
    }

    @Tool
    @LLMDescription("向指定收款人发起转账,必须在余额充足时才能成功")
    public TransferResult transferMoney(
        @LLMDescription("收款人的唯一标识符")
        String recipientId,
        @LLMDescription("转账金额(单位:美元),必须为正整数")
        Integer amount,
        @LLMDescription("发起转账的用户 ID")
        String fromUserId
    ) {
        // 业务逻辑会自动检查余额
        return transactionService.initiateTransfer(fromUserId, recipientId, amount);
    }

    @Tool
    @LLMDescription("查询指定货币对之间的实时汇率")
    public BigDecimal getExchangeRate(
        @LLMDescription("源货币代码(如:USD、CNY、EUR)")
        String fromCurrency,
        @LLMDescription("目标货币代码")
        String toCurrency
    ) {
        return exchangeRateService.getRate(fromCurrency, toCurrency);
    }

    @Tool
    @LLMDescription("检查账户是否存在安全风险,如异常登录、可疑交易等")
    public SecurityAlert checkSecurityAlert(
        @LLMDescription("被检查的用户 ID")
        String userId
    ) {
        return securityAlertService.checkAlert(userId);
    }
}

4.3 构建 Agent

package com.example.banking.agent;

import ai.koog.core.Agent;
import ai.koog.core.AgentConfig;
import ai.koog.executor.llm.openai.OpenAILLMClient;
import ai.koog.registry.ToolRegistry;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

@Component
public class BankingAgentFactory {

    @Value("${koog.model-provider.openai.api-key}")
    private String openAiKey;

    public Agent createAgent() {
        var promptExecutor = new MultiLLMPromptExecutor(
            new OpenAILLMClient(openAiKey)
        );

        return Agent.builder()
            .promptExecutor(promptExecutor)
            .model(OpenAIModels.Chat.GPT5_2)
            .systemPrompt("""
                你是一位专业的银行客服助手,具备以下能力:

                1. 回答用户关于账户余额、交易记录的问题
                2. 帮助用户完成转账操作
                3. 提供实时汇率查询服务
                4. 检查并提醒用户账户安全风险

                重要规则:
                - 转账前必须先确认用户余额充足
                - 单笔转账限额 10,000 美元,超过需要额外验证
                - 发现安全风险时必须立即提醒用户
                - 保持专业、友好的服务态度
                - 如果用户请求超出上述范围,礼貌地引导用户使用其他渠道
                """)
            .toolRegistry(
                ToolRegistry.builder()
                    .tools(new BankingTools())
                    .build()
            )
            .install(HistoryCompression.Feature, config -> {
                config.strategy(HistoryCompressionStrategy.chunked(30));
            })
            .install(OpenTelemetry.Feature, config -> {
                config.addSpanExporter(
                    OtlpGrpcSpanExporter.builder()
                        .setEndpoint("http://langfuse:4317")
                        .build()
                );
            })
            .build();
    }
}

4.4 接入 Spring MVC

package com.example.banking.agent;

import org.springframework.web.bind.annotation.*;
import lombok.RequiredArgsConstructor;

@RestController
@RequestMapping("/api/agent")
@RequiredArgsConstructor
public class BankingAgentController {

    private final BankingAgentFactory agentFactory;

    @PostMapping("/chat")
    public AgentResponse chat(@RequestBody ChatRequest request) {
        var agent = agentFactory.createAgent();
        var result = agent.run(request.message());
        return new AgentResponse(result, "success");
    }

    @PostMapping("/chat/stream")
    public SseEmitter streamChat(@RequestBody ChatRequest request) {
        var agent = agentFactory.createAgent();
        SseEmitter emitter = new SseEmitter();

        agent.stream(request.message())
            .onToken(token -> {
                try {
                    emitter.send(SseEmitter.event()
                        .name("token")
                        .data(token));
                } catch (IOException e) {
                    emitter.completeWithError(e);
                }
            })
            .onComplete(result -> {
                try {
                    emitter.send(SseEmitter.event()
                        .name("complete")
                        .data(result));
                    emitter.complete();
                } catch (IOException e) {
                    emitter.completeWithError(e);
                }
            })
            .start();

        return emitter;
    }
}

4.5 测试

@SpringBootTest
class BankingAgentTest {

    @Autowired
    private BankingAgentFactory agentFactory;

    @Test
    void testBalanceCheck() {
        var agent = agentFactory.createAgent();
        var result = agent.run("我的账户(user_12345)现在有多少钱?");
        assertTrue(result.contains("余额") || result.contains("账户"));
    }

    @Test
    void testTransfer() {
        var agent = agentFactory.createAgent();
        var result = agent.run(
            "从我的账户(user_12345)转 100 美元给朋友 Mike(ID: mike_5678)"
        );
        // Agent 应该先查余额,再执行转账
        assertNotNull(result);
    }

    @Test
    void testSecurityAlert() {
        var agent = agentFactory.createAgent();
        var result = agent.run("我的账户有异常吗?");
        assertNotNull(result);
    }
}

五、性能对比:JVM 原生的压倒性优势

Koog 作为原生 JVM 框架,在性能上相比 Python 方案有显著优势。以下是社区测试数据:

指标Koog(进程内)Python REST Agent差距
工具调用延迟0.2ms45ms225 倍
上下文准备4.5ms120ms27 倍
LLM 请求延迟~200ms~210ms~1 倍
总响应延迟4.7ms(不含 LLM)165ms(不含 LLM)35 倍

这个差距主要来自于内存共享。Python 方案要把 Java 对象序列化成 JSON,通过 HTTP 发给 Python 进程,Python 反序列化后再处理;而 Koog 直接在 JVM 堆里操作对象,省去了序列化和网络往返的开销。

对于高频交易、实时风控这些对延迟敏感的场景,这 100 多毫秒的差距可能就是"成交"和"滑点"的区别。对于普通的客服场景,35 倍的延迟优势也能带来明显更好的用户体验。

六、与现有生态的深度集成

Koog 并不是要推翻你的现有架构,相反,它对 Java 生态的兼容性做得相当好:

6.1 Spring Boot 深度集成

你的 @Service@Repository 可以直接作为 Tool 被 Agent 调用,事务管理、AOP 拦截、安全配置全都生效:

@Service
public class OrderService {

    @Transactional
    public Order createOrder(OrderRequest request) {
        // 在 Koog Tool 里调用时,事务自动生效
        return orderRepository.save(request.toOrder());
    }
}

public class OrderTools implements ToolSet {
    private final OrderService orderService;

    @Tool
    @LLMDescription("创建新订单")
    public Order createOrder(
        @LLMDescription("商品 ID")
        String productId,
        @LLMDescription("购买数量")
        Integer quantity
    ) {
        // 直接调用 Spring Service,事务自动管理
        return orderService.createOrder(
            OrderRequest.builder()
                .productId(productId)
                .quantity(quantity)
                .build()
        );
    }
}

6.2 MCP 协议支持

Koog 实现了 Model Context Protocol,可以和 Anthropic 的 Claude Desktop、其他支持 MCP 的 Agent 互通:

agent.install(MCP.Feature, config -> {
    config.server(new MCPServer("https://mcp-server.example.com"))
        .protocolVersion("2026-03-01");
});

通过 MCP,你的 Java Agent 既可以对外提供服务,也可以调用其他 MCP Server 的能力(比如调用外部的代码执行服务、数据查询服务等),形成一个 Agent 能力网络。

6.3 A2A 协议(Agent-to-Agent Protocol)

Koog 还支持 A2A 协议,让多个 Agent 之间可以直接通信和协作:

// 定义一个主管 Agent,协调多个子 Agent
var supervisor = A2AAgent.builder()
    .role("supervisor")
    .subAgents(
        bankingAgent,      // 银行业务 Agent
        knowledgeAgent,    // 知识库 Agent
        securityAgent      // 安全 Agent
    )
    .routingStrategy(new PriorityBasedRouting())
    .build();

6.4 OpenTelemetry 观测

上线以后最怕什么?Agent 抽风了,你都不知道它哪步想错了。Koog 对接了 OpenTelemetry,配合 Langfuse 或者 W&B Weave,能看到完整的执行链路:

var observableAgent = AIAgent.builder()
    .install(OpenTelemetry.Feature, config -> {
        config.serviceName("banking-agent")
            .addSpanExporter(OtlpGrpcSpanExporter.builder()
                .setEndpoint("http://your-langfuse:4317")
                .build())
            .addLogExporter(OtlpGrpcLogRecordExporter.builder()
                .setEndpoint("http://your-langfuse:4317")
                .build());
    })
    .build();

在监控面板里,你能看到:

  • Agent 总共执行了多少步
  • 每步调用了哪些工具,参数是什么
  • 每次 LLM 请求的 token 消耗和成本
  • 哪一步出现了异常,异常信息是什么

6.5 线程池隔离

Java 开发者最关心的线程管理,Koog 允许你为策略执行、LLM 请求分别指定不同的 ExecutorService,避免 IO 密集型请求阻塞你的业务线程:

var agent = AIAgent.builder()
    .strategyExecutor(Executors.newFixedThreadPool(4))
    .llmExecutor(Executors.newCachedThreadPool())
    .build();

七、对比竞品:Koog 的差异化优势

目前市面上的 AI Agent 框架已经很多了,Koog 的差异化定位在哪里?

特性KoogLangChain (Java)Spring AISemantic Kernel
JVM 原生❌(Python 绑定)❌(.NET)
Spring Boot 集成✅ 原生
KMP 多平台
函数式策略✅(Lambda)⚠️(C# LINQ)
类型安全输出✅(编译期)⚠️(Pydantic 运行时)⚠️⚠️
Agent 持久化
历史压缩⚠️
MCP/A2A 支持⚠️⚠️
OpenTelemetry⚠️⚠️
静态类型语言✅(Kotlin/Java)❌(Python)✅(Java)❌(C#)

从对比可以看出,Koog 是目前 JVM 生态里功能最完整、集成最深入的 Agent 框架。它不是简单地把 Python 框架的功能翻译到 Java,而是从 JVM 的角度重新思考了 Agent 的架构设计。

八、实践建议与避坑指南

8.1 什么时候选 Koog

推荐使用 Koog 的场景:

  • 你的核心业务系统跑在 Java/Spring Boot 上,不希望引入 Python 依赖
  • 对延迟敏感(<10ms 的工具调用延迟要求)
  • 需要类型安全的 Agent 输出(金融、医疗等强监管行业)
  • 需要 Agent 状态持久化和断点恢复
  • 需要多平台部署(服务端 + 移动端 + Web 端共用 Agent 逻辑)

不太适合 Koog 的场景:

  • 你的团队主要是 Python 技术栈,且 Agent 不是核心功能
  • 只需要简单的 RAG 问答,不需要复杂的工作流
  • 需要接入大量 Python 生态的 ML 工具(此时引入 Python 微服务更合理)

8.2 生产环境注意事项

(1)API Key 安全

绝对不要把 API Key 硬编码在代码里。推荐使用环境变量或专门的密钥管理服务(如 AWS Secrets Manager、HashiCorp Vault):

// ❌ 错误
var client = new OpenAILLMClient("sk-xxxx");

// ✅ 正确
var client = new OpenAILLMClient(System.getenv("OPENAI_API_KEY"));

(2)Token 成本控制

LLM 调用是按 token 计费的。一定要设置合理的 maxTokens,并开启历史压缩:

Agent.builder()
    .maxTokens(4096)                       // 限制单次输出
    .install(HistoryCompression.Feature, c -> {
        c.strategy(HistoryCompressionStrategy.chunked(20));
    })
    .build();

(3)错误处理和重试

LLM API 可能会超时或返回错误,一定要配置重试策略:

.withRetryPolicy(RetryPolicy.builder()
    .maxAttempts(3)
    .backoffStrategy(Backoff.exponential().base(1000))
    .retryOn(HttpException.class)
    .retryOn(TimeoutException.class)
    .build())

(4)并发安全

如果多个请求共用同一个 Agent 实例,注意线程安全问题。建议每次请求创建新实例,或使用 ThreadLocal 隔离状态:

@Service
@RequiredArgsConstructor
public class AgentFactory {
    private final BankingAgentFactory bankingAgentFactory;

    public Agent createPerRequest() {
        return bankingAgentFactory.createAgent();
    }
}

8.3 工具定义的 Best Practices

(1)@LLMDescription 要写详细

这是 LLM 理解工具用途的唯一依据。好的描述应该包括:功能说明、返回值含义、参数约束:

@Tool
@LLMDescription("""
    查询用户账户的当前余额。

    返回值是一个整数,表示账户余额(单位:美元)。
    如果返回 -1,表示账户不存在或已冻结。

    示例:
    - 输入 userId="user_123",返回 1500 表示账户有 1500 美元
    - 输入 userId="invalid",返回 -1 表示账户不存在
    """)
public Integer getBalance(String userId) { ... }

(2)避免副作用

每个 Tool 最好只做一件事,避免在 Tool 里执行多个不相关的操作。如果一个操作涉及多个步骤,应该拆成多个 Tool,便于 LLM 选择性地调用。

(3)幂等性设计

如果 Tool 涉及写操作,尽量设计成幂等的(同样的参数重复调用结果一致)。对于非幂等操作(如转账),需要在描述中明确告知 LLM。

九、未来展望:Koog 的路线图与 JVM 生态的 AI 未来

从 GitHub 仓库的活跃度来看,Koog 目前处于快速迭代期。根据 JetBrains 在 IntelliJ IDEA Conf 2026 的分享(虽然会议改期到了 9 月,但预热内容已经透露),Koog 的未来路线图包括:

短期(2026 Q2-Q3):

  • 支持更多 LLM Provider(特别是国产模型:DeepSeek、通义千问、文心一言)
  • 更丰富的 Graph-based Agent 可视化编辑器
  • 与 JetBrains 全家桶更深入的集成(直接在 IDEA 里调试 Agent)

中期(2026 Q4):

  • WASM 目标稳定版发布(真正的前后端统一 Agent)
  • 企业级功能:多租户隔离、权限管理、审计日志
  • 与 JetBrains Space 的深度集成

长期(2027+):

  • Agent 协作协议(A2A)标准化
  • 与传统中间件的深度集成(Kafka 事件驱动、RocketMQ 等)
  • AI Agent 的低代码编排平台

十、总结

说实话,写这篇文章的时候我是有点激动的。不是因为 Koog 有多完美(它确实还在快速迭代中,GitHub 上能看到活跃的开发提交),而是因为它代表了一个信号:JVM 生态在 AI 时代不再是"二等公民"

JetBrains 把自己内部打磨的框架开源出来,还专门为 Java 开发者设计了一套 Fluent API,这本身就说明他们看好 Java 在企业级 AI 应用中的地位。毕竟,全世界还有那么多核心系统跑在 Java 上,让它们为了 AI 而"另起炉灶"既不现实也不经济。

Koog 的出现填补了 JVM 生态在 AI Agent 领域的关键空白。它不是 LangChain 的翻译版,而是一个从 JVM 角度重新思考的、有着完整企业级能力的新型 Agent 框架。对于想在自己 Java 项目里引入 AI Agent 能力的团队,Koog 已经是一个值得认真考虑的选项了。

不用再羡慕 Python 程序员了。拿起你熟悉的 IDEA,写几个 @Tool 注解,你的 Java 应用也能拥有自己的 AI Agent。毕竟,工具只是手段,解决问题才是目的。而 Koog,似乎让 Java 程序员离这个目标更近了一步。


参考资源:

  • Koog 官方文档:https://docs.koog.ai
  • GitHub 仓库:https://github.com/JetBrains/koog
  • JetBrains 官方博客:Koog Comes to Java
  • IntelliJ IDEA Conf 2026:https://intellij-conf.jetbrains.com

注:本文技术细节基于 Koog 0.6.4 版本,框架处于快速迭代期,生产环境使用前建议查阅最新官方文档。

复制全文 生成海报 Koog JetBrains AI Agent JVM Kotlin Spring Boot 框架

推荐文章

Nginx 跨域处理配置
2024-11-18 16:51:51 +0800 CST
使用Vue 3实现无刷新数据加载
2024-11-18 17:48:20 +0800 CST
php获取当前域名
2024-11-18 00:12:48 +0800 CST
如何优化网页的 SEO 架构
2024-11-18 14:32:08 +0800 CST
paint-board:趣味性艺术画板
2024-11-19 07:43:41 +0800 CST
Vue3中如何进行错误处理?
2024-11-18 05:17:47 +0800 CST
程序员茄子在线接单