主题
11 · DSL
你还可以用 Kotlin 或 Java 的 DSL 来创建 Agent。
这适用于这样的工作流:你想要一个自身完整的原子动作,但它内部可能包含多个步骤或动作。
标准工作流(Standard Workflows)
有一些由 builder 构建的标准工作流,用来满足常见需求。 它们既可以用来创建会暴露为 Spring bean 的 Agent,也可以用在其它 Agent 的 @Action 方法内部。 所有工作流都是类型安全的,并且尽可能使用一致的 API。
SimpleAgentBuilder:最简 Agent,没有前置条件与后置条件。ScatterGatherBuilder:用于并行处理的 fork-join 模式。ConsensusBuilder:在多个来源之间达成共识的模式。是ScatterGather的特化。RepeatUntil:重复一个步骤,直到满足某个条件。RepeatUntilAcceptable:在某条件满足期间重复一个步骤,并由一个独立的评估器提供反馈。
创建一个简单 Agent:
java
var agent = SimpleAgentBuilder
.returning(Joke.class) // ①
.running(tac -> tac.ai() // ②
.withDefaultLlm()
.createObject("Tell me a joke", Joke.class))
.buildAgent("joker", "This is guaranteed to return a dreadful joke"); // ③注记:
- ① 指定返回类型。
- ② 指定要执行的动作。它接收一个
SupplierActionContext/OperationContext参数,从而可以访问当前的AgentProcess。 - ③ 用给定名称与描述构建 Agent。
一个更复杂的例子:
java
@Action
FactChecks runAndConsolidateFactChecks(
DistinctFactualAssertions distinctFactualAssertions,
ActionContext context) {
var llmFactChecks = properties.models().stream()
.flatMap(model -> factCheckWithSingleLlm(model, distinctFactualAssertions, context))
.toList();
return ScatterGatherBuilder // ①
.returning(FactChecks.class) // ②
.fromElements(FactCheck.class) // ③
.generatedBy(llmFactChecks) // ④
.consolidatedBy(this::reconcileFactChecks) // ⑤
.asSubProcess(context); // ⑥
}注记:
- ① 开始构建一个 scatter-gather Agent。
- ② 指定整个 Agent 的返回类型。
- ③ 指定要收集的元素类型。
- ④ 指定并行运行的函数列表,每个函数生成一个元素(这里是
FactCheck类型)。 - ⑤ 指定一个用于合并结果的函数。此处它会接收一个
FactCheck列表,返回一个FactChecks对象。 - ⑥ 把该 Agent 作为当前进程的子进程构建并运行。 这是
SimpleAgentBuilder示例中buildAgent的替代方式,API 是一致的。
如果你想动手试试,embabel-agent-examples 仓库里就包含上面这个 fact checker。
注册 Agent bean(Registering Agent beans)
@Agent 注解会让类立刻被 Spring 拾取;而用 DSL 时,你还需要额外一步把 Agent 注册到 Spring。 如下例所示,任何类型为 Agent 的 @Bean 都会触发自动注册,效果与声明一个带 @Agent 注解的类相同。
java
@Configuration
public class FactCheckerAgentConfiguration {
@Bean
public Agent factChecker(FactCheckerProperties factCheckerProperties) {
return factCheckerAgent(
List.of(
LlmOptions.create(AnthropicModels.CLAUDE_35_HAIKU).withTemperature(0.3),
LlmOptions.create(AnthropicModels.CLAUDE_35_HAIKU).withTemperature(0.0)
),
factCheckerProperties
);
}
}