From 65e65bd137f83d14c7917f4dae1db0423aa78923 Mon Sep 17 00:00:00 2001 From: mlogclub Date: Tue, 14 Apr 2026 10:03:52 +0800 Subject: [PATCH] feat: add ProjectInstructionProvider and ToolAppendixProvider for enhanced instruction handling --- .../internal/impl/factory/agent_factory.go | 37 +++++++++++------ .../impl/factory/instruction_providers.go | 41 +++++++++++++++++++ .../internal/impl/factory/tool_helpers.go | 14 +------ 3 files changed, 67 insertions(+), 25 deletions(-) create mode 100644 internal/ai/runtime/internal/impl/factory/instruction_providers.go diff --git a/internal/ai/runtime/internal/impl/factory/agent_factory.go b/internal/ai/runtime/internal/impl/factory/agent_factory.go index d4bf1e1..c194825 100644 --- a/internal/ai/runtime/internal/impl/factory/agent_factory.go +++ b/internal/ai/runtime/internal/impl/factory/agent_factory.go @@ -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, }) } diff --git a/internal/ai/runtime/internal/impl/factory/instruction_providers.go b/internal/ai/runtime/internal/impl/factory/instruction_providers.go new file mode 100644 index 0000000..be4b521 --- /dev/null +++ b/internal/ai/runtime/internal/impl/factory/instruction_providers.go @@ -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 +} diff --git a/internal/ai/runtime/internal/impl/factory/tool_helpers.go b/internal/ai/runtime/internal/impl/factory/tool_helpers.go index d4e27c6..930dace 100644 --- a/internal/ai/runtime/internal/impl/factory/tool_helpers.go +++ b/internal/ai/runtime/internal/impl/factory/tool_helpers.go @@ -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) }