Koog OpenAI模型:prompt-executor-openai-model模型定义
概述
prompt-executor-openai-model是Koog框架中专门为OpenAI兼容API设计的核心模型定义模块。作为OpenAI客户端实现的基础,该模块提供了完整的请求/响应数据模型、抽象客户端实现以及多模态内容支持,是构建OpenAI兼容LLM(Large Language Model,大语言模型)客户端的基石。
核心架构设计
模块定位与职责
核心数据模型详解
消息系统模型
// 基础消息接口
sealed interface OpenAIMessage {
val role: String
val content: String?
val name: String?
val attachments: List<Attachment>?
}
// 具体消息类型实现
data class System(
override val content: String,
override val name: String? = null,
override val attachments: List<Attachment>? = null
) : OpenAIMessage {
override val role: String = "system"
}
data class User(
override val content: String? = null,
override val name: String? = null,
override val attachments: List<Attachment>? = null
) : OpenAIMessage {
override val role: String = "user"
}
data class Assistant(
override val content: String? = null,
override val name: String? = null,
val toolCalls: List<OpenAIToolCall>? = null,
override val attachments: List<Attachment>? = null
) : OpenAIMessage {
override val role: String = "assistant"
}
data class Tool(
val toolCallId: String,
val content: String,
override val name: String? = null,
override val attachments: List<Attachment>? = null
) : OpenAIMessage {
override val role: String = "tool"
override val content: String = content
}
多模态内容支持
// 内容部件系统
sealed class OpenAIContentPart {
data class Text(val text: String) : OpenAIContentPart()
data class Image(
val imageUrl: ImageUrl,
val detail: String? = null
) : OpenAIContentPart()
data class ImageUrl(val url: String, val detail: String? = null)
data class Audio(val inputAudio: InputAudio) : OpenAIContentPart()
data class InputAudio(val data: ByteArray, val format: String)
data class File(val fileData: FileData) : OpenAIContentPart()
data class FileData(val data: ByteArray, val filename: String)
}
// 内容容器
data class Content(val parts: List<OpenAIContentPart>)
工具调用系统
// 工具定义
data class OpenAITool(
val type: String = "function",
val function: OpenAIToolFunction
)
data class OpenAIToolFunction(
val name: String,
val description: String? = null,
val parameters: JsonObject? = null,
val strict: Boolean? = null
)
// 工具调用响应
data class OpenAIToolCall(
val id: String,
val type: String = "function",
val function: OpenAIToolCallFunction
)
data class OpenAIToolCallFunction(
val name: String,
val arguments: String
)
请求响应模型体系
完整请求模型结构
响应模型层次
// 基础响应
data class OpenAIBaseLLMResponse(
val id: String,
val choices: List<OpenAIChoice>,
val created: Long,
val model: String,
val systemFingerprint: String? = null,
val usage: OpenAIUsage? = null
)
// 选择项详情
data class OpenAIChoice(
val index: Int,
val message: OpenAIMessage,
val logprobs: OpenAIChoiceLogProbs? = null,
val finishReason: String? = null
)
// 使用统计
data class OpenAIUsage(
val promptTokens: Int,
val completionTokens: Int,
val totalTokens: Int,
val completionTokensDetails: CompletionTokensDetails? = null,
val promptTokensDetails: PromptTokensDetails? = null
)
流式响应支持
流式响应模型
// 流式响应基础
data class OpenAIBaseLLMStreamResponse(
val id: String,
val choices: List<OpenAIStreamChoice>,
val created: Long,
val model: String,
val systemFingerprint: String? = null
)
// 流式选择项
data class OpenAIStreamChoice(
val index: Int,
val delta: OpenAIStreamDelta,
val logprobs: OpenAIChoiceLogProbs? = null,
val finishReason: String? = null
)
// 流式增量数据
data class OpenAIStreamDelta(
val role: String? = null,
val content: String? = null,
val toolCalls: List<OpenAIToolCall>? = null
)
音频处理模型
音频配置与响应
// 音频配置
data class OpenAIAudioConfig(
val model: String,
val voice: OpenAIAudioVoice = OpenAIAudioVoice.ALLOY,
val responseFormat: OpenAIAudioFormat = OpenAIAudioFormat.MP3,
val speed: Double = 1.0
)
enum class OpenAIAudioVoice {
ALLOY, ECHO, FABLE, ONYX, NOVA, SHIMMER
}
enum class OpenAIAudioFormat {
MP3, OPUS, AAC, FLAC, WAV, PCM
}
// 音频响应
data class OpenAIAudio(
val audio: ByteArray,
val format: OpenAIAudioFormat,
val transcript: String? = null
)
抽象客户端实现
AbstractOpenAILLMClient 核心功能
abstract class AbstractOpenAILLMClient(
protected val apiKey: String,
protected val settings: OpenAIBasedSettings
) : LLMClient {
// 核心执行方法
override suspend fun execute(
prompt: Prompt,
model: LLMModel,
options: LLMExecutionOptions? = null
): LLMResponse {
val request = buildRequest(prompt, model, options)
val response = executeRequest(request)
return processResponse(response)
}
// 流式执行
override fun executeStreaming(
prompt: Prompt,
model: LLMModel,
options: LLMExecutionOptions? = null
): Flow<LLMStreamResponse> {
val request = buildRequest(prompt, model, options).copy(stream = true)
return executeStreamingRequest(request)
}
// 请求构建模板方法
protected open fun buildRequest(
prompt: Prompt,
model: LLMModel,
options: LLMExecutionOptions?
): OpenAIBaseLLMRequest {
// 实现请求构建逻辑
}
// HTTP请求执行(需子类实现)
protected abstract suspend fun executeRequest(request: OpenAIBaseLLMRequest): OpenAIBaseLLMResponse
// 流式请求执行(需子类实现)
protected abstract fun executeStreamingRequest(request: OpenAIBaseLLMRequest): Flow<OpenAIBaseLLMStreamResponse>
}
配置系统
OpenAIBasedSettings 配置模型
open class OpenAIBasedSettings(
val baseUrl: String = "https://api.openai.com/v1",
val chatCompletionsPath: String = "/chat/completions",
val audioSpeechPath: String = "/audio/speech",
val audioTranscriptionsPath: String = "/audio/transcriptions",
val timeoutMillis: Long = 30000,
val maxRetries: Int = 3
) {
open fun configureHttpClient(builder: HttpClientConfig.Builder) {
builder.apply {
defaultRequest {
header("Authorization", "Bearer $apiKey")
header("Content-Type", "application/json")
timeout {
requestTimeoutMillis = timeoutMillis
connectTimeoutMillis = timeoutMillis
socketTimeoutMillis = timeoutMillis
}
}
// 重试配置
if (maxRetries > 0) {
retry(maxRetries) { _, response ->
response.status.isServerError
}
}
}
}
}
扩展点与自定义
自定义设置覆盖
class CustomOpenAISettings(
baseUrl: String,
customHeaders: Map<String, String> = emptyMap()
) : OpenAIBasedSettings(baseUrl = baseUrl) {
override fun configureHttpClient(builder: HttpClientConfig.Builder) {
super.configureHttpClient(builder)
builder.defaultRequest {
customHeaders.forEach { (key, value) ->
header(key, value)
}
}
}
}
模型能力验证
interface ModelCapabilities {
val supportsMultimodal: Boolean
val supportsToolCalls: Boolean
val supportsStreaming: Boolean
val supportsAudio: Boolean
val maxTokens: Int
val modalities: OpenAIModalities
}
data class OpenAIModalities(
val text: Boolean = true,
val vision: Boolean = false,
val audio: Boolean = false
)
最佳实践与使用模式
模型定义使用示例
// 创建自定义OpenAI客户端
class MyOpenAIClient(apiKey: String) : AbstractOpenAILLMClient(
apiKey = apiKey,
settings = OpenAIBasedSettings()
) {
override suspend fun executeRequest(request: OpenAIBaseLLMRequest): OpenAIBaseLLMResponse {
// 实现具体的HTTP请求逻辑
val httpClient = HttpClient {
settings.configureHttpClient(this)
}
val response = httpClient.post("${settings.baseUrl}${settings.chatCompletionsPath}") {
setBody(Json.encodeToString(request))
}
return Json.decodeFromString(response.bodyAsText())
}
override fun executeStreamingRequest(request: OpenAIBaseLLMRequest): Flow<OpenAIBaseLLMStreamResponse> {
// 实现流式请求逻辑
return flow {
// SSE流处理实现
}
}
}
多模态内容处理
// 构建包含图像的消息
val message = User(
content = "请描述这张图片的内容",
attachments = listOf(
Attachment(
data = imageBytes,
mimeType = "image/jpeg",
name = "example.jpg"
)
)
)
// 工具调用集成
val tool = OpenAITool(
function = OpenAIToolFunction(
name = "get_weather",
description = "获取指定城市的天气信息",
parameters = JsonObject(
"type" to JsonPrimitive("object"),
"properties" to JsonObject(
"city" to JsonObject(
"type" to JsonPrimitive("string"),
"description" to JsonPrimitive("城市名称")
)
),
"required" to JsonArray(JsonPrimitive("city"))
)
)
)
总结
prompt-executor-openai-model模块为Koog框架提供了完整的OpenAI兼容API模型定义体系,具备以下核心特性:
- 完整的模型覆盖:包含请求、响应、流式、音频等所有OpenAI API数据模型
- 多模态支持:原生支持文本、图像、音频、文件等多种内容类型
- 工具调用集成:完整的函数调用和工具执行支持
- 扩展性设计:通过抽象类和接口提供灵活的扩展点
- 类型安全:基于Kotlin的强类型系统,确保API使用的安全性
- 流式处理:原生支持服务器推送事件(Server-Sent Events)流式响应
该模块是构建任何OpenAI兼容LLM客户端的基础,为开发者提供了统一、类型安全且可扩展的模型定义体系。
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考



