feat: add ProjectInstructionProvider and ToolAppendixProvider for enhanced instruction handling

This commit is contained in:
mlogclub
2026-04-14 10:03:52 +08:00
parent 3f85c7fc2c
commit 65e65bd137
3 changed files with 67 additions and 25 deletions
@@ -21,9 +21,11 @@ import (
)
type AgentFactory struct {
chatModelFactory *ChatModelFactory
toolFactory *ToolFactory
instructionAssembler *InstructionAssembler
chatModelFactory *ChatModelFactory
toolFactory *ToolFactory
instructionAssembler *InstructionAssembler
projectInstructionProvider *ProjectInstructionProvider
toolAppendixProvider *ToolAppendixProvider
}
// BuildCustomerServiceAgentInput 定义客服 Agent 的装配输入。
@@ -57,9 +59,11 @@ type BuildCustomerServiceAgentInput struct {
func NewAgentFactory() *AgentFactory {
return &AgentFactory{
chatModelFactory: NewChatModelFactory(),
toolFactory: NewToolFactory(),
instructionAssembler: NewInstructionAssembler(),
chatModelFactory: NewChatModelFactory(),
toolFactory: NewToolFactory(),
instructionAssembler: NewInstructionAssembler(),
projectInstructionProvider: NewProjectInstructionProvider(),
toolAppendixProvider: NewToolAppendixProvider(),
}
}
@@ -102,7 +106,7 @@ func (f *AgentFactory) BuildCustomerServiceAgent(ctx context.Context, input Buil
}
handlers = append(handlers, einocallbacks.NewRuntimeTraceHandler(input.Collector, toolMetadataBy))
}
instructionResult := assembleAgentInstruction(input.AIAgent, input.SelectedSkill, input.InstructionToolDefinitions, input.StaticToolCodes)
instructionResult := f.assembleAgentInstruction(input.AIAgent, input.SelectedSkill, input.InstructionToolDefinitions, input.StaticToolCodes)
if input.Collector != nil {
input.Collector.SetInstructionSummary(einocallbacks.InstructionTraceSummary{
SectionTitles: append([]string(nil), instructionResult.Summary.SectionTitles...),
@@ -144,16 +148,25 @@ func (f *AgentFactory) buildSelectedSkillMiddleware(ctx context.Context, selecte
})
}
func assembleAgentInstruction(aiAgent *models.AIAgent, selectedSkill *models.SkillDefinition, toolDefinitions []einoadapter.MCPToolDefinition, extraToolCodes map[string]string) InstructionAssemblyResult {
func (f *AgentFactory) assembleAgentInstruction(aiAgent *models.AIAgent, selectedSkill *models.SkillDefinition, toolDefinitions []einoadapter.MCPToolDefinition, extraToolCodes map[string]string) InstructionAssemblyResult {
baseInstruction := ""
if aiAgent != nil {
baseInstruction = strings.TrimSpace(aiAgent.SystemPrompt)
}
appendixParts := buildInstructionAppendices(selectedSkill, toolDefinitions, extraToolCodes)
return NewInstructionAssembler().Assemble(InstructionAssemblerInput{
AgentInstruction: baseInstruction,
SkillInstruction: firstAppendixPart(appendixParts),
ToolAppendices: remainingAppendixParts(appendixParts),
projectInstruction := ""
if f != nil && f.projectInstructionProvider != nil {
projectInstruction = f.projectInstructionProvider.Resolve()
}
assembler := NewInstructionAssembler()
if f != nil && f.instructionAssembler != nil {
assembler = f.instructionAssembler
}
return assembler.Assemble(InstructionAssemblerInput{
AgentInstruction: baseInstruction,
SkillInstruction: firstAppendixPart(appendixParts),
ToolAppendices: remainingAppendixParts(appendixParts),
ProjectInstruction: projectInstruction,
})
}
@@ -0,0 +1,41 @@
package factory
import (
"strings"
einoadapter "cs-agent/internal/ai/runtime/internal/impl/adapter"
"cs-agent/internal/models"
"cs-agent/internal/pkg/toolx"
)
type ProjectInstructionProvider struct{}
func NewProjectInstructionProvider() *ProjectInstructionProvider {
return &ProjectInstructionProvider{}
}
func (p *ProjectInstructionProvider) Resolve() string {
return strings.TrimSpace(DefaultProjectInstruction)
}
type ToolAppendixProvider struct{}
func NewToolAppendixProvider() *ToolAppendixProvider {
return &ToolAppendixProvider{}
}
func (p *ToolAppendixProvider) Build(selectedSkill *models.SkillDefinition, toolDefinitions []einoadapter.MCPToolDefinition, extraToolCodes map[string]string) []string {
appendixParts := make([]string, 0, 2)
if skillInstruction := buildSelectedSkillActivationInstruction(selectedSkill); skillInstruction != "" {
appendixParts = append(appendixParts, skillInstruction)
}
toolCodes := make([]string, 0, len(toolDefinitions)+len(extraToolCodes))
for _, item := range toolDefinitions {
toolCodes = append(toolCodes, item.ToolCode)
}
for _, item := range extraToolCodes {
toolCodes = append(toolCodes, item)
}
appendixParts = append(appendixParts, toolx.BuildToolAppendicesForCodes(len(toolDefinitions) > 0, toolCodes)...)
return appendixParts
}
@@ -57,17 +57,5 @@ func buildRuntimeTraceToolMetadata(
}
func buildInstructionAppendices(selectedSkill *models.SkillDefinition, toolDefinitions []einoadapter.MCPToolDefinition, extraToolCodes map[string]string) []string {
appendixParts := make([]string, 0, 2)
if skillInstruction := buildSelectedSkillActivationInstruction(selectedSkill); skillInstruction != "" {
appendixParts = append(appendixParts, skillInstruction)
}
toolCodes := make([]string, 0, len(toolDefinitions)+len(extraToolCodes))
for _, item := range toolDefinitions {
toolCodes = append(toolCodes, item.ToolCode)
}
for _, item := range extraToolCodes {
toolCodes = append(toolCodes, item)
}
appendixParts = append(appendixParts, toolx.BuildToolAppendicesForCodes(len(toolDefinitions) > 0, toolCodes)...)
return appendixParts
return NewToolAppendixProvider().Build(selectedSkill, toolDefinitions, extraToolCodes)
}