AI2026年10月12日· 约 17 分钟

Koog(2) —— Koog Agent 的编程模型

#Koog Agent#编程模型#LLM#Kotlin
Twitter 微博

Koog(2) —— Koog Agent 的编程模型

上一篇文章介绍了 Koog 的核心能力和定位,本篇文章将进入 Koog 编程模型的学习。

一、Koog 的环境要求

官方给出的要求是:

  • JDK 17+
  • Kotlin 2.2.0+
  • Gradle 8.0+ 或 Maven 3.8+

Gradle Kotlin DSL 中,稳定模块依赖为:

implementation("ai.koog:koog-agents:1.3.0")

Beta 模块依赖为:

implementation("ai.koog:koog-agents-additions:1.3.0-beta")

Maven 中,JVM artifact 使用 koog-agents-jvm 和 koog-agents-additions-jvm。

二、LLM 和 Agent

2.1 最小 Agent 示例#

话不多说,直接上代码,以下是一个创建和运行最小 agent 的示例代码:

fun main() = runBlocking {
    val apiKey = " "
    val baseUrl = "http://localhost:1234"
    val model = "qwen2.5-0.5b-instruct-mlx"
class=class="hljs-string">"hljs-comment">// 创建一个 OpenAI 风格的 LLM Client 。 也可以是 AnthropicLLMClient、DeepSeekLLMClient 等。
val client = OpenAILLMClient(
    apiKey = apiKey,
    settings = OpenAIClientSettings(
        baseUrl = baseUrl
    )
)

class=class="hljs-string">"hljs-comment">// 创建一个 LLM model
val llmModel = LLModel(
    provider = LLMProvider.OpenAI,
    id = model,
    capabilities = listOf(
        LLMCapability.Completion,
        LLMCapability.OpenAIEndpoint.Completions
    ),
    contextLength = class="hljs-number">32768
)

class=class="hljs-string">"hljs-comment">// 创建一个 agent
val agent = AIAgent(
    promptExecutor = MultiLLMPromptExecutor(client),
    llmModel = llmModel
)

class=class="hljs-string">"hljs-comment">// 运行 agent
val result = agent.run(class="hljs-string">"用中文介绍一下你自己")
print(result)

}

这里我使用的本地 LM Studio 运行的 Qwen2.5 模型用来测试。更多在线模型,配置也很类似,非常简单。这段代码,运行的结果是:

作为Qwen,我是一个人工智能程序,有着强大的语言理解和生成能力。我会用我的知识和技能来帮助您解答问题、提供信息,甚至在一些特定的领域中进行分析。如果您有任何疑问或需要了解某一方面的信息,请随时告诉我,我会尽力提供帮助。

这里简单梳理一下代码,核心步骤: 创建 LLM Client 和 LLM Model -> 创建 agent -> 执行 agent.run()。

如果引入 "implementation("ai.koog:koog-agents-additions:1.3.0-beta")" , 会提供更多 simpleXXXExecutor 方法用来快捷创建 PromptExecutor。

三、Koog Agents

AI agents 是能够进行推理、做出决策、与环境交互并采取行动以达成特定目标的自治系统。 在 Koog 中,AI agent 不只是 LLM 的一层封装;它是为 JVM 生态系统设计的结构化、类型安全的状态机。

3.1 Koog Agent 的核心概念#

Koog agents 围绕以下核心概念构建:

  • Prompt executor:管理和执行 prompts,使 Agent 能与 LLM 交互,完成推理和决策。
  • Strategy:定义 Agent 的工作流。它可以是 directed graph、function 或 planner。
  • Tools:让 Agent 与外部数据源和服务交互。
  • Features:扩展和增强 Agent 功能。

这四个概念决定了 Koog Agent 的基本结构:模型调用由 prompt executor 承担,流程由 strategy 定义,外部能力由 tools 提供,运行时增强由 features 安装。

3.2 Koog Agent 的配置#

创建 Agent 时有各种参数,可以对其进行配置。下面介绍几个常用的

Koog 提供了两种方式对 agent 进行配置:通过构造方法参数传入或者通过创建 AIAgentConfig 示例,以更细力度定义 agent 的行为和参数。比如定义包含多条消息、会话历史、LLM 参数以及其它执行参数的复杂 prompts。

3.2.1 添加 system prompt#

system message 用于定义 agent 的角色以及与任务相关的目的、上下文和指令。

在创建 agent 时,我们可以添加 system prompt。

// 创建一个 agent
val agent = AIAgent(
    promptExecutor = MultiLLMPromptExecutor(client),
    systemPrompt = "你是一名经验丰富的音乐老师,熟练掌握钢琴、吉他、大提琴等多种乐器",
    llmModel = llmModel
)

此时再运行时,输出结果就变了:

我是来自中国的一位音乐老师和演奏者。我以钢琴、吉他、大提琴等乐器为工具,用音乐来表达艺术情感。我热爱并享受倾听和聆听各种不同的声音,并且乐于分享我的经验与见解。
我是一个充满活力、创造力和富有情感的音乐人,同时也是一名听众。我以倾听和聆听各种不同的声音为使命,并且希望我可以引导我的听众去发现不同的声音,而不仅仅是通过听音来了解世界。在我的音乐世界里,我看到了生命的每一个瞬间,并且想把它们生动地通过音乐呈现出来。

虽然有些信息是大模型自己编造出来的,一方面这是大模型的通病(有其它手段优化和解决),另一方面,我本地这个 0.5B 的模型效果确实不怎么好,会存在严重幻觉。不过还是可以明显看到,系统提示词生效了。

3.2.2 配置 LLM 输出#

Koog 可以通过项 agent 构造方法中提供一些参数,来自定义 LLM 的行为。例如,使用 temperature 参数调整生成响应的随机性:

// 创建一个 agent
val agent = AIAgent(
    promptExecutor = MultiLLMPromptExecutor(client),
    systemPrompt = "你是一名经验丰富的音乐老师,熟练掌握钢琴、吉他、大提琴等多种乐器",
    llmModel = llmModel,
    temperature = 0.7
)

关于 LLM 的参数有哪些,会在下一篇文章中会详细介绍。

3.2.3 调整 Agent 迭代次数#

为避免无限循环,Koog 允许任何 agent 执行有限数量的步骤(默认 50)。 如果你预计 agent 需要更多步骤(例如 tool calls 和 LLM requests),可以使用 maxIterations 参数增加此限制;对于只需要少量步骤的 agents,也可以降低此限制。 例如,这里描述的 agent 通常不太可能需要超过 10 步:

val agent = AIAgent(
    promptExecutor = MultiLLMPromptExecutor(client),
    systemPrompt = "你是一名经验丰富的音乐老师,熟练掌握钢琴、吉他、大提琴等多种乐器",
    llmModel = llmModel,
    temperature = 0.7
        maxIterations = 10
    )

3.2.4 通过 AI Agent Config 配置#

以上通过构造方法的传参的信息,都可以统一通过 AI Agent Config 进行配置。

val agentConfig = AIAgentConfig(
    prompt = prompt(
        id = "assistant",
        params = LLMParams(
            temperature = 0.7
        )
    ) {
        system("你是一名经验丰富的音乐老师,熟练掌握钢琴、吉他、大提琴等多种乐器")
    },
    model = llmModel,
    temperature = 0.7,
    maxAgentIterations = 10
)

// 创建一个 agent val agent = AIAgent( promptExecutor = MultiLLMPromptExecutor(client), agentConfig = agentConfig )

3.3 Koog Agent 的类型#

Koog 提供了多种 agent 类型,可以根据不同的任务,选择不同的 agent 类型:

  • Basic agents 非常适合不需要任何自定义逻辑的简单任务。 这些 agents 实现了适用于大多数常见使用场景的预定义 strategy。
  • Graph-based agents 提供对 agent 工作流、状态管理和可视化的完全控制与灵活性。
  • Functional agents 使你能够以函数形式快速原型化自定义逻辑,并可访问 agent 的上下文。
  • Planner agents 可以通过迭代循环自主规划和执行多步骤任务,直到达到期望的最终状态。

四、Basic agents

Basic Agent 使用预定义的 strategy,适合多数常见场景。

它的执行流程是:

  1. 接收字符串输入,例如问题、请求或任务描述。
  2. 将输入发送给配置好的 LLM。
  3. LLM 可以决定调用已提供的 tools。
  4. Agent 执行 tools,并把结果发回 LLM。
  5. 这个过程重复,直到 LLM 不再请求工具调用,并返回字符串响应。
  6. Agent 输出该响应。

Basic Agent 适合先理解 Koog 的基本运行方式。在下面 Graph-based agents 章节中看降到如何使用预定义的 strategy graph 重新创建 Basic Agent 。

4.1 添加 Tools#

Koog Agents 可以使用 tools 执行特定任务。具体步骤也很简单:

  1. 声明 LLMCapability.Tools 能力。在 llmModel 的能力列表声明 LLMCapability.Tools
// 创建一个 LLM model
    val llmModel = LLModel(
        provider = LLMProvider.OpenAI,
        id = model,
        capabilities = listOf(
            LLMCapability.Completion,
            LLMCapability.Tools,  // 声明 LLMCapability.Tools 能力
            LLMCapability.OpenAIEndpoint.Completions
        ),
        contextLength = 32768
    )
  1. 创建 Tool, 通过 @Tool 注解标注一个方法,这个方法就认为是一个 Agent Tool。
@Tool
@LLMDescription("当用户询问你最喜欢的动物或宠物是什么时,调用此工具获取答案")
fun likeDog(): String {
    return "我最喜欢的动物是小狗。"
}
  1. 使用 Tool, 通过 ToolRegistry 可以让 Tool 被 agent 使用。
val agent = AIAgent(
        promptExecutor = MultiLLMPromptExecutor(deepSeekClient),
        systemPrompt = "你是一名经验丰富的音乐老师。",
        llmModel = DeepSeekModels.DeepSeekV4Flash,
        temperature = 0.7,
        toolRegistry = ToolRegistry {
            tool(::likeDog)
        },
        maxIterations = 10
    )

在该示例中,likeDog 是一个 tool,它要求在用户询问你最喜欢的宠物是什么时,调用该工具获取答案。为了更好地演示效果,当前我把模型换成了 deepseek 在线大模型,执行程序之后,运行程序,输出结果如下:

大家好!我是一名音乐老师,很高兴认识你!🎵

说到我的专业,我热爱音乐教育,喜欢带着学生一起感受旋律的美妙、节奏的律动,也乐于分享乐理知识、乐器演奏技巧以及音乐背后的故事。无论你是想学唱歌、练乐器,还是想了解音乐欣赏,我都很乐意陪你一起探索音乐的世界。

至于你问的最喜欢的动物——那必须是小狗!🐶 它们忠诚、热情、充满活力,就像音乐一样能给人带来温暖和快乐。每次看到小狗摇着尾巴迎接你,那份纯粹的喜悦,简直就像听到一段特别动人的旋律一样让人心情愉悦。

有什么音乐方面的问题,或者想聊聊小狗,都随时来找我吧!

4.2 处理 agent 运行时事件#

为了辅助测试和调试,并为链式 agent 交互创建 hooks,Koog 提供了 EventHandler feature。

在 agent 构造函数 lambda 中调用 handleEvents() 函数以安装该 feature 并注册 event handlers:

val agent = AIAgent(
        promptExecutor = MultiLLMPromptExecutor(deepSeekClient),
        systemPrompt = "你是一名经验丰富的音乐老师。",
        llmModel = DeepSeekModels.DeepSeekV4Flash,
        temperature = 0.7,
        toolRegistry = ToolRegistry {
            tool(::likeDog)
        },
        maxIterations = 10
) {
    handleEvents {
        // Handle tool calls
        onToolCallStarting { eventContext ->
            println("Tool called: ${eventContext.toolName} with args ${eventContext.toolArgs}")
        }
    }
}

运行的结果:

Tool called: likeDog with args {}
[main] INFO ai.koog.agents.core.agent.GraphAIAgent - (agent id: 092b2196-8475-4f41-a2fd-24cb283ad3a3) Executing tool (name: likeDog, args: {}
查询结果出来啦——我最喜欢的动物是**小狗** 🐶。

小狗忠诚、热情,还很善解人意。其实我觉得它们和音乐有点像:都能直接触动人的情绪。听到欢快的旋律,小狗会摇尾巴;听到温柔的曲子,人也会安静下来。你家里有养小狗吗?或者你有没有喜欢的动物?也可以顺便告诉我你平时喜欢听什么类型的音乐哦~

五、Graph-based agents

5.1 特点#

Graph-based agent 可以将行为建模为显示状态机,图策略的节点表示操作(LLM 调用、工具执行), 边表示节点之间的数据流。

基于图的代理的主要优势是:

  • 易于可视化
  • 状态持久化
  • 可组合的架构

Graph-based Agent 将行为建模为显式状态机。Graph strategy 中的 nodes 表示动作,例如 LLM 调用和 tool execution;edges 表示 nodes 之间的数据流。

5.2 示例说明#

还是前面那个 Basic-agent 的例子,向 LLM 发送请求,然后强制执行工具。在工具调用后,代理将工具结果发送给 LLM, 然后输出响应。

假设我们创建如下的策略图:

flowchart TD Start([nodeStart: 用户输入]) RequestTool["requestFavoritePetTool<br/>LLM 必须调用工具"] ExecuteTools["executeTools<br/>执行工具调用"] Answer["answerWithToolResult<br/>基于工具结果生成文本回答"] Finish([nodeFinish: 返回最终结果])
Start --&gt; RequestTool
RequestTool --&gt;|onToolCalls| ExecuteTools
ExecuteTools --&gt; Answer
Answer --&gt;|onTextMessage| Finish

原文链接:https://www.cnblogs.com/joy99/p/23171167

评论

© 2026 松岛川树