feat: implement supervisor agent with 3 sub-agents

This commit is contained in:
2026-05-05 11:34:19 +08:00
parent 18790f1bcd
commit a25de092b1
7 changed files with 185 additions and 1 deletions
+2 -1
View File
@@ -11,7 +11,8 @@ require (
github.com/cloudwego/base64x v0.1.6 // indirect
github.com/cloudwego/eino v0.8.13 // indirect
github.com/cloudwego/eino-ext/components/embedding/openai v0.0.0-20260427010451-749e3706378b // indirect
github.com/cloudwego/eino-ext/libs/acl/openai v0.1.15 // indirect
github.com/cloudwego/eino-ext/components/model/openai v0.1.13 // indirect
github.com/cloudwego/eino-ext/libs/acl/openai v0.1.17 // indirect
github.com/dustin/go-humanize v1.0.1 // indirect
github.com/eino-contrib/jsonschema v1.0.3 // indirect
github.com/evanphx/json-patch v0.5.2 // indirect
+4
View File
@@ -20,8 +20,12 @@ github.com/cloudwego/eino v0.8.13 h1:z5dhaZNN8TWZbP/lgKxGmF26Ii8fPeUlQCGV/NTtms0
github.com/cloudwego/eino v0.8.13/go.mod h1:+2N4nsMPxA6kGBHpH+75JuTfEcGprAMTdsZESrShKpU=
github.com/cloudwego/eino-ext/components/embedding/openai v0.0.0-20260427010451-749e3706378b h1:pOqupZQyc46rw2Z0HeybtTmSMTwqfTrbRuGDuDsNf2A=
github.com/cloudwego/eino-ext/components/embedding/openai v0.0.0-20260427010451-749e3706378b/go.mod h1:zyPrZT2bO6LyRJgVksQowR18jVgyLSvqK93hnO53/Lc=
github.com/cloudwego/eino-ext/components/model/openai v0.1.13 h1:5XHRTiTD5bt9KQrMHcfvuWNklEC3tpm3XHejdozt9vM=
github.com/cloudwego/eino-ext/components/model/openai v0.1.13/go.mod h1:mgIoqYYOc0eECCqvLbEYpOJrQNTNxkwXzSJzFU+v5sQ=
github.com/cloudwego/eino-ext/libs/acl/openai v0.1.15 h1:LbdSG9+qWzzp9RFW6dSFkaUW171JvCoYn/K63zX6dQE=
github.com/cloudwego/eino-ext/libs/acl/openai v0.1.15/go.mod h1:p+l0zBB0GjjX8HTlbTs3g3KfUFwZC11bsCGZOXW/3L0=
github.com/cloudwego/eino-ext/libs/acl/openai v0.1.17 h1:EeVcR1TslRA2IdNW1h/2LaGbPlffwGhQm99jM3zWZiI=
github.com/cloudwego/eino-ext/libs/acl/openai v0.1.17/go.mod h1:Zkcx6DPTR2NfWmtSXbhItswGw6hqUezNPhNcke0pOG8=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/dustin/go-humanize v1.0.1 h1:GzkhY7T5VNhEkwH0PVJgjz+fX1rhBrR7pRT3mDkpeCY=
+18
View File
@@ -0,0 +1,18 @@
package agent
import (
"context"
"eino-test/config"
"github.com/cloudwego/eino-ext/components/model/openai"
"github.com/cloudwego/eino/components/model"
)
func NewChatModel(ctx context.Context, cfg *config.Config) (model.ToolCallingChatModel, error) {
return openai.NewChatModel(ctx, &openai.ChatModelConfig{
BaseURL: cfg.OpenAIBaseURL,
APIKey: cfg.OpenAIAPIKey,
Model: cfg.OpenAIModel,
})
}
+37
View File
@@ -0,0 +1,37 @@
package agent
import (
"context"
"eino-test/internal/rag"
"eino-test/internal/tools"
"github.com/cloudwego/eino/adk"
"github.com/cloudwego/eino/components/model"
"github.com/cloudwego/eino/components/tool"
"github.com/cloudwego/eino/compose"
)
func NewOrganizerAgent(ctx context.Context, chatModel model.ToolCallingChatModel, pipeline *rag.RAGPipeline) adk.Agent {
agent, _ := adk.NewChatModelAgent(ctx, &adk.ChatModelAgentConfig{
Name: "OrganizerAgent",
Description: "Organizes notes with tags and discovers relationships between notes. Use for categorization and knowledge graph operations.",
Instruction: `You are a knowledge organization expert. Your job is to help users categorize their notes and discover hidden connections.
Use suggest_tags when the user wants to categorize or label a note.
Use find_related when the user wants to discover notes related to a specific topic or note.
Help users build a well-organized knowledge base with meaningful connections.`,
Model: chatModel,
ToolsConfig: adk.ToolsConfig{
ToolsNodeConfig: compose.ToolsNodeConfig{
Tools: []tool.BaseTool{
tools.NewSuggestTagsTool(pipeline, chatModel),
tools.NewFindRelatedTool(pipeline),
},
},
},
MaxIterations: 8,
})
return agent
}
+37
View File
@@ -0,0 +1,37 @@
package agent
import (
"context"
"eino-test/internal/rag"
"eino-test/internal/tools"
"github.com/cloudwego/eino/adk"
"github.com/cloudwego/eino/components/model"
"github.com/cloudwego/eino/components/tool"
"github.com/cloudwego/eino/compose"
)
func NewRetrievalAgent(ctx context.Context, chatModel model.ToolCallingChatModel, pipeline *rag.RAGPipeline) adk.Agent {
agent, _ := adk.NewChatModelAgent(ctx, &adk.ChatModelAgentConfig{
Name: "RetrievalAgent",
Description: "Searches the knowledge base to find relevant notes. Use for information retrieval and discovery.",
Instruction: `You are a knowledge retrieval expert. Your job is to find the most relevant notes from the user's knowledge base.
Use semantic_search for conceptual or fuzzy queries where the user describes something by meaning.
Use keyword_search when the user provides specific terms, titles, or exact keywords.
Always return the most relevant results with enough context for the user to understand what was found.`,
Model: chatModel,
ToolsConfig: adk.ToolsConfig{
ToolsNodeConfig: compose.ToolsNodeConfig{
Tools: []tool.BaseTool{
tools.NewSemanticSearchTool(pipeline),
tools.NewKeywordSearchTool(pipeline),
},
},
},
MaxIterations: 10,
})
return agent
}
+50
View File
@@ -0,0 +1,50 @@
package agent
import (
"context"
"eino-test/config"
"eino-test/internal/rag"
"github.com/cloudwego/eino/adk"
"github.com/cloudwego/eino/adk/prebuilt/supervisor"
)
func NewSupervisorAgent(ctx context.Context, cfg *config.Config, pipeline *rag.RAGPipeline) (adk.Agent, error) {
chatModel, err := NewChatModel(ctx, cfg)
if err != nil {
return nil, err
}
retrievalAgent := NewRetrievalAgent(ctx, chatModel, pipeline)
writerAgent := NewWriterAgent(ctx, chatModel, pipeline)
organizerAgent := NewOrganizerAgent(ctx, chatModel, pipeline)
supervisorAgent, err := adk.NewChatModelAgent(ctx, &adk.ChatModelAgentConfig{
Name: "KnowledgeSupervisor",
Description: "Personal knowledge assistant that routes tasks to specialized agents.",
Instruction: `You are a personal knowledge assistant supervisor. Your job is to understand the user's request and route it to the right specialist agent.
Available agents:
- RetrievalAgent: For searching and finding information in the knowledge base. Use when the user asks to find, search, or look up notes.
- WriterAgent: For creating new notes or generating summaries. Use when the user wants to write, create, or summarize content.
- OrganizerAgent: For tagging notes and discovering related content. Use when the user wants to organize, categorize, or find connections.
Workflow:
1. Analyze the user's request to determine which agent(s) should handle it.
2. Transfer the task to the appropriate agent.
3. If the task requires multiple agents (e.g., search then summarize), coordinate them in sequence.
4. After all sub-agents complete, synthesize their results into a clear final response for the user.
If the request is simple conversation (greetings, general questions), respond directly without transferring.`,
Model: chatModel,
})
if err != nil {
return nil, err
}
return supervisor.New(ctx, &supervisor.Config{
Supervisor: supervisorAgent,
SubAgents: []adk.Agent{retrievalAgent, writerAgent, organizerAgent},
})
}
+37
View File
@@ -0,0 +1,37 @@
package agent
import (
"context"
"eino-test/internal/rag"
"eino-test/internal/tools"
"github.com/cloudwego/eino/adk"
"github.com/cloudwego/eino/components/model"
"github.com/cloudwego/eino/components/tool"
"github.com/cloudwego/eino/compose"
)
func NewWriterAgent(ctx context.Context, chatModel model.ToolCallingChatModel, pipeline *rag.RAGPipeline) adk.Agent {
agent, _ := adk.NewChatModelAgent(ctx, &adk.ChatModelAgentConfig{
Name: "WriterAgent",
Description: "Creates new notes and generates summaries. Use for content creation and processing.",
Instruction: `You are a writing assistant. Your job is to help users create, organize, and summarize notes.
Use create_note when the user wants to save new content to their knowledge base.
Use generate_summary when the user wants a concise overview of an existing note.
Always write in clear, well-structured Markdown format.`,
Model: chatModel,
ToolsConfig: adk.ToolsConfig{
ToolsNodeConfig: compose.ToolsNodeConfig{
Tools: []tool.BaseTool{
tools.NewCreateNoteTool(pipeline),
tools.NewGenerateSummaryTool(pipeline, chatModel),
},
},
},
MaxIterations: 8,
})
return agent
}