内容提要
Koog 的模型调用层包含 Prompt、LLM 参数、LLM 客户端、Prompt 执行器和提供商。Prompt 用于表达消息与参数,推荐通过 Kotlin DSL 或 Java builder 创建,支持 system、user、assistant 等消息类型及 Markdown、XML 富文本。LLM 客户端直接对接具体提供商,支持执行、流式、多选、模型列表、嵌入和内容审核。Prompt 执行器提供更高层统一抽象,可管理多提供商、路由、回退、重试、超时和缓存。
延伸解读
Prompt 不是字符串,而是对话上下文
文章强调,Koog 中的 Prompt 是包含 id、messages 和 params 的数据类,最终会转换成包含多条 Message 的 Chat API 请求。这意味着开发者不应把 Prompt 当成一段拼接好的文本,而应理解为一个结构化的对话历史。扩展 Prompt 时,新消息会追加到已有消息列表之后,而不是替换原有内容。这种设计更贴近多轮对话的实际需求,也便于后续插入 system、assistant 等不同角色的消息。
LLM Client 与 Prompt Executor 的选择边界
文章给出了明确的使用建议:如果只使用单个 LLM provider,且不需要高级生命周期管理,直接用 LLM client 即可;如果需要管理多个 provider、动态切换或使用回退,则应选择 prompt executor。两者都接受 Prompt 对象,但 executor 是对 client 的包装,因此 client 支持的能力如流式、多选、审核,executor 也一并支持。理解这一层关系,有助于在项目初期就选对抽象层级,避免后期重构。
多选生成不等于模型主动给出不同答案
文章特别提醒,executeMultipleChoices 的概念是让模型针对同一个 Prompt 生成多个候选结果,而不是让模型先思考再给出三个不同答案。返回的是多个生成结果的集合,而非单个 Message。此外,该功能并非所有客户端都支持,GoogleLLMClient、BedrockLLMClient 和 OllamaClient 不适用。开发者在使用前需要确认目标 provider 是否支持,并注意 numberOfChoices 参数必须在 Prompt 中指定。
重试与超时是生产环境的基础设施
文章指出,Koog 内置了重试和超时机制来应对速率限制或临时服务不可用等瞬时错误。RetryingLLMClient 可以包装任何 LLM client,默认最多重试 3 次,并支持通过 RetryConfig 自定义重试模式。超时方面,ConnectionTimeoutConfig 允许分别设置连接、请求和 socket 超时。需要注意的是,流式重试仅适用于收到第一个 token 之前的连接失败,一旦流式传输开始,重试逻辑就会禁用。
Q&A
Koog 中 Prompt 是什么?如何创建?
Prompt 是给大语言模型的指令,用于指导模型生成响应。它是 Prompt data class 的实例,包含 id、messages 和 params。推荐使用 Kotlin DSL 或 Java builder API 创建,例如:prompt("hello-koog") { system("You are a helpful assistant.") user("What is Koog?") }。
Koog 的 LLM clients 和 prompt executors 有什么区别?
LLM clients 直接与具体 LLM provider 交互,实现 LLMClient 接口,提供执行 prompts 和流式响应等方法,适用于单个 provider 且无需高级生命周期管理的场景。Prompt executors 是管理一个或多个 LLM clients 生命周期的高级抽象,提供统一 API 跨多个 providers 运行 prompt,支持路由、回退、重试、超时和缓存,推荐用于生产环境。
Koog 中如何实现多 provider 之间的路由和回退?
可以使用 RoutingLLMPromptExecutor 配合路由策略(如 RoundRobinRouter)在多个 LLM client 实例之间分发请求,避免速率限制、提高吞吐量。回退机制可在创建 MultiLLMPromptExecutor 或 RoutingLLMPromptExecutor 时传入 FallbackPromptExecutorSettings 配置 fallback provider 和 model,当请求的 LLM client 不可用时使用 fallback。注意回退仅适用于 execute() 和 executeMultipleChoices() 方法。
Koog 的 RetryingLLMClient 如何工作?默认重试配置是什么?
RetryingLLMClient 是一个装饰器,可为任何 LLM client 添加自动重试逻辑,处理速率限制或临时服务不可用等瞬时错误。默认配置为最多 3 次重试、1 秒初始延迟、30 秒最大延迟。可通过 RetryConfig 自定义,包括 maxAttempts、initialDelay、maxDelay、backoffMultiplier、jitterFactor 等参数,也可使用预定义配置如 RetryConfig.CONSERVATIVE、PRODUCTION 等。
Koog 中 embed() 和 moderate() 分别有什么用途?
embed() 将文本转换为 embedding 向量(一串浮点数),用于计算文本语义相似度,典型用途是语义搜索和 RAG/知识库。它使用 Embedding Model,不是让 LLM 理解文本。moderate() 用于内容安全/合规检查,在用户输入或模型输出进入下一步之前检查是否包含不适当内容,通常涉及暴力、仇恨、骚扰、性内容、自残、非法活动等类别,返回结构化结果。
Koog 中如何缓存 LLM 响应以优化性能?
可以使用 CachedPromptExecutor 包装 PromptExecutor 来添加缓存功能。它存储之前执行过的 prompts 的响应,再次运行相同 prompts 时直接检索缓存。示例:val cachedExecutor = CachedPromptExecutor(cache = FilePromptCache(Path("path/to/cache")), nested = promptExecutor)。第二次执行相同 prompt 时从缓存返回,耗时仅 1ms。
Koog 的 KoogHttpClient 是什么?为什么需要它?
KoogHttpClient 是 Koog 框架用于与 LLM providers 通信的抽象 HTTP 契约,是底层的网络通信基础设施。由于 Koog 是 Kotlin Multiplatform,可运行在 Android、iOS、JS、WasmJS 等平台,不同平台的 HTTP 实现不同,KoogHttpClient 屏蔽了这些差异。Koog 提供 Ktor、JDK HttpClient、OkHttp 和 Spring WebClient 四种后端 factory,也可自定义。在 JVM 和 Android 上,Koog 通过 HttpClientFactoryResolver 使用 ServiceLoader 自动发现 factory,无需显式传入;其他平台需显式传入。
Koog 中如何配置超时以防止请求挂起?
所有 LLM clients 在 Kotlin 和 Java 中都支持超时配置。可以在创建 client 时使用 ConnectionTimeoutConfig 类指定 connectTimeoutMillis(建立连接超时)、requestTimeoutMillis(整个请求超时)、socketTimeoutMillis(socket 数据超时)。例如:ConnectionTimeoutConfig(connectTimeoutMillis = 5000, requestTimeoutMillis = 60000, socketTimeoutMillis = 120000)。对于长时间运行或流式调用,可设置更高的 requestTimeoutMillis 和 socketTimeoutMillis。