The Loop Agent is an important component in the Blades framework for implementing loop execution logic. The Loop Agent determines whether to continue executing a task based on the return value of a condition function. This pattern is well-suited for scenarios that require repeated processing until a goal is achieved.

To implement loop logic in Blades, you can directly use the encapsulated NewLoopAgent function to initialize a Loop Agent. You need to pass the parameter LoopConfig, which has the following structure:
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)Use blades.NewAgent to create multiple sub-agents, each assigned a specific task. Here, we construct a writing agent for drafting and a reviewing agent for evaluation as an example.
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"),)When creating the Loop Agent, you should set a maximum number of iterations to avoid infinite loops. In this example, the maximum number of iterations is set to 3, and the loop terminates if the word “good” appears.
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, },})In this example, when running the Loop Agent, a Runner is created and its RunStream method is called, passing the context and input message. This returns a message stream, and iterating over this stream allows you to obtain the output results of each 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()) }}