概述
代理使用工具来执行特定任务或访问外部系统。
工具工作流
Koog 框架提供了以下用于处理工具的工作流:
- 创建自定义工具或使用内置工具之一。
- 将工具添加到工具注册表。
- 将工具注册表传递给代理。
- 将工具与代理一起使用。
可用的工具类型
Koog 框架中有三种类型的工具:
- 内置工具,提供代理与用户交互和对话管理功能。有关详细信息,请参见 内置工具。
- 基于注解的自定义工具,允许您将函数公开为 LLM 的工具。有关详细信息,请参见 基于注解的工具。
- 基于类的自定义工具,允许您控制工具形参、元数据、执行逻辑以及如何注册和调用它。有关详细信息,请参见 基于类的工具。
工具注册表
在使用工具之前,您必须将其添加到工具注册表。 工具注册表管理代理可用的所有工具。
工具注册表的主要特性:
- 组织工具。
- 支持合并多个工具注册表。
- 提供按名称或类型检索工具的方法。
要了解更多信息,请参见 ToolRegistry。
这是一个关于如何创建工具注册表并向其中添加工具的示例:
val toolRegistry = ToolRegistry {
tool(SayToUser)
}
要合并多个工具注册表,请执行以下操作:
val firstToolRegistry = ToolRegistry {
tool(FirstSampleTool)
}
val secondToolRegistry = ToolRegistry {
tool(SecondSampleTool)
}
val newRegistry = firstToolRegistry + secondToolRegistry
将工具传递给代理
要使代理能够使用工具,您需要在创建代理时提供一个包含该工具的工具注册表作为实参:
// 代理初始化
val agent = AIAgent(
executor = simpleOpenAIExecutor(System.getenv("OPENAI_API_KEY")),
systemPrompt = "You are a helpful assistant with strong mathematical skills.",
llmModel = OpenAIModels.Chat.GPT4o,
// 将您的工具注册表传递给代理
toolRegistry = toolRegistry
)
调用工具
在您的代理代码中,有几种方式可以调用工具。推荐的方法是使用代理上下文中提供的方法,而不是直接调用工具,因为这可以确保在代理环境中正确处理工具操作。
TIP
确保您已在工具中实现适当的 错误处理 以防止代理失败。
工具在由 AIAgentLLMWriteSession
表示的特定会话上下文中被调用。它提供了几种调用工具的方法,以便您可以:
- 使用给定实参调用工具。
- 按其名称和给定实参调用工具。
- 按提供的工具类和实参调用工具。
- 使用给定实参调用指定类型的工具。
- 调用返回原始字符串结果的工具。
有关更多详细信息,请参见 API reference。
并行工具调用
您还可以使用 toParallelToolCallsRaw
扩展并行调用工具。例如:
@Serializable
data class Book(
val title: String,
val author: String,
val description: String
) : ToolArgs
class BookTool() : SimpleTool<Book>() {
companion object {
const val NAME = "book"
}
override suspend fun doExecute(args: Book): String {
println("${args.title} by ${args.author}:
${args.description}")
return "Done"
}
override val argsSerializer: KSerializer<Book>
get() = Book.serializer()
override val descriptor: ToolDescriptor
get() = ToolDescriptor(
name = NAME,
description = "A tool to parse book information from Markdown",
requiredParameters = listOf(),
optionalParameters = listOf()
)
}
val strategy = strategy<Unit, Unit>("strategy-name") {
/*...*/
val myNode by node<Unit, Unit> { _ ->
llm.writeSession {
flow {
emit(Book("Book 1", "Author 1", "Description 1"))
}.toParallelToolCallsRaw(BookTool::class).collect()
}
}
}
从节点调用工具
当使用节点构建代理工作流时,您可以使用特殊节点来调用工具:
nodeExecuteTool:调用单个工具调用并返回其结果。有关详细信息,请参见 API reference。
nodeExecuteSingleTool:它使用提供的实参调用特定工具。有关详细信息,请参见 API reference。
nodeExecuteMultipleTools:它执行多个工具调用并返回其结果。有关详细信息,请参见 API reference。
nodeLLMSendToolResult:它向 LLM 发送工具结果并获取响应。有关详细信息,请参见 API reference。
nodeLLMSendMultipleToolResults:它向 LLM 发送多个工具结果。有关详细信息,请参见 API reference。