循环Agent是Blades框架中用于实现循环执行逻辑的重要组件,循环Agent基于条件函数的返回值决定是否继续执行某个任务。这种模式非常适合需要重复处理直到达成目标的场景。

在Blades中实现循环逻辑,可直接使用已经封装好的 NewLoopAgent 函数初始化一个循环Agent,需要传入参数 LoopConfig ,结构如下:
type LoopConfig struct { Name string Description string MaxIterations int Condition LoopCondition SubAgents []blades.Agent}type LoopCondition func(ctx context.Context, output *blades.Message) (bool, error)使用 blades.NewAgent 创建多个子Agent,分别制定对应的任务。在此处举例构建一个写作Agent进行写作和一个审阅Agent进行评判。
model := openai.NewModel(os.Getenv("OPENAI_MODEL"), openai.Config{ APIKey: os.Getenv("OPENAI_API_KEY"),})writerAgent, err := blades.NewAgent( "WriterAgent", blades.WithModel(model), blades.WithInstruction(`Draft a short paragraph on climate change. {{if .suggestions}} **Draft** {{.draft}}
Here are the suggestions to consider: {{.suggestions}} {{end}} `), blades.WithOutputKey("draft"),)reviewerAgent, err := blades.NewAgent( "ReviewerAgent", blades.WithModel(model), blades.WithInstruction(`Review the draft and suggest improvements. If the draft is good, respond with "The draft is good".
**Draft** {{.draft}} `), blades.WithOutputKey("suggestions"),)创建循环Agent时应当设置最大循环次数,避免无限循环。此处例子中设置的最大循环次数为3,且设置若出现“good”则终止循环。
loopAgent := flow.NewLoopAgent(flow.LoopConfig{ Name: "WritingReviewFlow", Description: "An agent that loops between writing and reviewing until the draft is good.", MaxIterations: 3, Condition: func(ctx context.Context, output *blades.Message) (bool, error) { return !strings.Contains(output.Text(), "good"), nil }, SubAgents: []blades.Agent{ writerAgent, reviewerAgent, },})在此处例子中运行循环Agent时,创建了一个Runner并调用其RunStream方法,传入上下文和输入消息,即可得到一个消息流,遍历该消息流即可获取每个Agent的输出结果。
input := blades.UserMessage("Please write a short paragraph about climate change.")runner := blades.NewRunner(loopAgent)stream := runner.RunStream(context.Background(), input)for message, err := range stream { if err != nil { log.Fatal(err) } log.Println(message.Author, message.Text())}package main
import ( "context" "log" "os" "strings"
"github.com/go-kratos/blades" "github.com/go-kratos/blades/contrib/openai" "github.com/go-kratos/blades/flow")
func main() { model := openai.NewModel(os.Getenv("OPENAI_MODEL"), openai.Config{ APIKey: os.Getenv("OPENAI_API_KEY"), }) writerAgent, err := blades.NewAgent( "WriterAgent", blades.WithModel(model), blades.WithInstruction(`Draft a short paragraph on climate change. {{if .suggestions}} **Draft** {{.draft}}
Here are the suggestions to consider: {{.suggestions}} {{end}} `), blades.WithOutputKey("draft"), ) if err != nil { log.Fatal(err) } reviewerAgent, err := blades.NewAgent( "ReviewerAgent", blades.WithModel(model), blades.WithInstruction(`Review the draft and suggest improvements. If the draft is good, respond with "The draft is good".
**Draft** {{.draft}} `), blades.WithOutputKey("suggestions"), ) if err != nil { log.Fatal(err) } loopAgent := flow.NewLoopAgent(flow.LoopConfig{ Name: "WritingReviewFlow", Description: "An agent that loops between writing and reviewing until the draft is good.", MaxIterations: 3, Condition: func(ctx context.Context, output *blades.Message) (bool, error) { return !strings.Contains(output.Text(), "good"), nil }, SubAgents: []blades.Agent{ writerAgent, reviewerAgent, }, }) input := blades.UserMessage("Please write a short paragraph about climate change.") runner := blades.NewRunner(loopAgent) stream := runner.RunStream(context.Background(), input) for message, err := range stream { if err != nil { log.Fatal(err) } log.Println(message.Author, message.Text()) }}