在 Koog 框架中,Strategy(策略) 是工作流编排的核心单元,而 Node(节点) 则是构成 Strategy 的基本执行块。定义和配置节点主要依赖于 Koog 提供的声明式 DSL(领域特定语言),结合 Kotlin 的类型安全特性,实现从简单函数调用到复杂 Agent 交互的灵活配置。
以下是定义和配置 Strategy 节点的详细指南:
1. 核心概念:节点的类型
在 Koog 中,节点通常分为以下几类,每种类型有不同的配置方式:
Agent Node:执行大模型推理或 Agent 逻辑。
Tool Node:调用外部工具、API 或本地函数。
Function/Code Node:执行纯 Kotlin 代码逻辑(如数据清洗、格式转换)。
Control Node:控制流节点,如条件分支(If-Else)、并行聚合(Join)等。
2. 定义节点的基础语法
Koog 使用基于 Kotlin DSL 的构建器模式来定义 Strategy。你通常在 strategy { ... } 块中通过链式调用或作用域函数来添加节点。
基本结构示例
kotlin
import ai.koog.strategy.Strategy
import ai.koog.agent.Agent
val myStrategy = Strategy.build {
// 1. 定义输入节点 (Start Node)
start {
// 配置初始上下文或参数映射
}
// 2. 定义处理节点
node("DataProcessor") {
// 节点逻辑配置
}
// 3. 定义输出节点 (End Node)
end {
// 配置最终输出
}
}
3. 配置不同类型节点的详细方法
A. 配置 Agent 节点
Agent 节点用于与大模型交互。你需要指定使用的 LLM 模型、系统提示词(System Prompt)以及输入输出的映射。
kotlin
node("ResearchAgent") {
// 绑定具体的 Agent 实例
agent = researchAgent
// 配置输入映射:将上游节点的输出映射到 Agent 的输入参数
inputMapping {
mapFromPrevious("query") to "userQuestion"
mapFromContext("history") to "chatHistory"
}
// 配置输出映射:将 Agent 的回答映射到下游可用的变量
outputMapping {
mapResult("answer") to "researchResult"
}
// 可选:配置重试策略
retry {
maxAttempts = 3
backoffMillis = 1000
}
}
B. 配置 Tool 节点
Tool 节点用于执行具体操作,如搜索网页、查询数据库。Koog 强调类型安全,因此工具的定义通常是强类型的。
kotlin
node("WeatherChecker") {
// 绑定已注册的工具
tool = weatherTool
// 动态参数配置:可以从上下文中提取参数
arguments {
param("city") fromContext "currentCity"
param("date") fromValue LocalDate.now()
}
// 错误处理:如果工具调用失败,提供降级值
onError {
fallbackValue = "Unknown Weather"
}
}
C. 配置 Function/Code 节点
对于不需要 LLM 参与的纯逻辑处理,可以直接嵌入 Kotlin 代码块。这是进行数据清洗、格式转换最高效的方式。
kotlin
node("FormatOutput") {
// 直接编写 Kotlin lambda 表达式
execute { context ->
val rawText = context.get<String>("researchResult")
val formatted = rawText.trim().replace("\n", " ")
// 将结果写回上下文,供后续节点使用
context.set("formattedText", formatted)
}
}
D. 配置控制流节点(并行与分支)
Koog 支持复杂的 DAG(有向无环图)结构,包括并行执行和条件分支。
并行执行配置:
kotlin
parallel("ParallelSearch") {
// 并行执行多个节点,直到所有完成
node("SearchWeb") { ... }
node("SearchDB") { ... }
// 聚合结果
join {
combineResults { webResult, dbResult ->
listOf(webResult, dbResult)
}
}
}
条件分支配置:
kotlin
branch("CheckSentiment") {
// 根据上下文中的情感评分决定走向
condition { context ->
context.get<Double>("sentimentScore") > 0.5
}
onTrue {
node("PositiveResponse") { ... }
}
onFalse {
node("NegativeResponse") { ... }
}
}
4. 关键配置项详解
在配置任何节点时,以下通用属性至关重要:
表格
配置项 说明 示例
Name/ID 节点的唯一标识,用于调试和日志追踪。 node("UniqueID")
Input Mapping 定义数据如何从全局 Context 或上游节点流入当前节点。 mapFromPrevious("out") to "in"
Output Mapping 定义节点执行结果如何保存回全局 Context。 mapResult("data") to "savedKey"
Timeout 节点执行的最大允许时间,超时则触发错误处理。 timeout = 5000.milliseconds
Retry Policy 失败时的重试策略,包括次数和退避算法。 retry { maxAttempts = 3 }
Metadata 附加元数据,可用于监控、日志分类或前端可视化展示。 metadata["category"] = "preprocessing"
5. 最佳实践与注意事项
保持节点原子性:每个节点应只负责单一职责(如“获取数据”、“清洗数据”、“生成摘要”)。避免在一个节点中混合 LLM 调用和复杂的业务逻辑,以提高可维护性和重试效率。
利用类型安全:Koog 的优势在于 Kotlin 的类型系统。在定义 inputMapping 和 outputMapping 时,尽量使用强类型对象,避免使用通用的 Map<String, Any>,以便在编译期发现数据流错误。
上下文管理:所有节点通过共享的 Context 对象传递状态。确保在 outputMapping 中明确指定键名,避免不同节点写入相同的键导致数据覆盖。
可视化调试:Koog 支持将 Strategy 导出为图形化表示(如 Mermaid 或 JSON 格式)。在定义节点时,提供清晰的 name 和 description,有助于在可视化工具中理解工作流结构。
错误隔离:为关键节点配置独立的 onError 处理器。例如,当外部 API 不可用时,可以返回缓存数据或默认值,而不是让整个 Strategy 崩溃。
通过上述方式,你可以灵活地定义和配置 Koog Strategy 中的各类节点,构建出高效、可靠且易于维护的 AI 工作流。
发布评论