From f1f213420d3f3a02bb426fad3f02eb1312e3784d Mon Sep 17 00:00:00 2001 From: mlogclub Date: Sat, 11 Apr 2026 23:02:09 +0800 Subject: [PATCH] feat: add instruction summary handling in RuntimeTraceCollector and enhance instruction assembly process --- .../impl/callbacks/runlog_callback.go | 14 +++++++ .../internal/impl/callbacks/trace_callback.go | 17 +++++++++ .../internal/impl/factory/agent_factory.go | 17 +++++++-- .../impl/factory/instruction_assembler.go | 37 ++++++++++++++++++- 4 files changed, 81 insertions(+), 4 deletions(-) diff --git a/internal/ai/runtime/internal/impl/callbacks/runlog_callback.go b/internal/ai/runtime/internal/impl/callbacks/runlog_callback.go index dabaa99..02d0743 100644 --- a/internal/ai/runtime/internal/impl/callbacks/runlog_callback.go +++ b/internal/ai/runtime/internal/impl/callbacks/runlog_callback.go @@ -41,6 +41,20 @@ func (c *RuntimeTraceCollector) SetTooling(staticToolCodes []string, dynamicTool c.Data.Input.ToolSearchEnabled = toolSearchEnabled } +func (c *RuntimeTraceCollector) SetInstructionSummary(summary InstructionTraceSummary) { + if c == nil { + return + } + c.mu.Lock() + defer c.mu.Unlock() + c.Data.Instruction.SectionTitles = append([]string(nil), summary.SectionTitles...) + c.Data.Instruction.HasProjectRule = summary.HasProjectRule + c.Data.Instruction.HasGovernanceRule = summary.HasGovernanceRule + c.Data.Instruction.HasAgentRule = summary.HasAgentRule + c.Data.Instruction.HasSkillRule = summary.HasSkillRule + c.Data.Instruction.HasToolRule = summary.HasToolRule +} + func (c *RuntimeTraceCollector) AddToolItem(item ToolTraceItem) { if c == nil { return diff --git a/internal/ai/runtime/internal/impl/callbacks/trace_callback.go b/internal/ai/runtime/internal/impl/callbacks/trace_callback.go index 7833543..5966e2c 100644 --- a/internal/ai/runtime/internal/impl/callbacks/trace_callback.go +++ b/internal/ai/runtime/internal/impl/callbacks/trace_callback.go @@ -41,6 +41,15 @@ type RetrieverTraceItem struct { LatencyMs int64 `json:"latencyMs,omitempty"` } +type InstructionTraceSummary struct { + SectionTitles []string + HasProjectRule bool + HasGovernanceRule bool + HasAgentRule bool + HasSkillRule bool + HasToolRule bool +} + type RuntimeTraceData struct { Version string `json:"version"` Status string `json:"status"` @@ -54,6 +63,14 @@ type RuntimeTraceData struct { Provider string `json:"provider,omitempty"` Name string `json:"name,omitempty"` } `json:"model"` + Instruction struct { + SectionTitles []string `json:"sectionTitles,omitempty"` + HasProjectRule bool `json:"hasProjectRule,omitempty"` + HasGovernanceRule bool `json:"hasGovernanceRule,omitempty"` + HasAgentRule bool `json:"hasAgentRule,omitempty"` + HasSkillRule bool `json:"hasSkillRule,omitempty"` + HasToolRule bool `json:"hasToolRule,omitempty"` + } `json:"instruction"` Input struct { HistoryMessageCount int `json:"historyMessageCount,omitempty"` KnowledgeBaseIDs []int64 `json:"knowledgeBaseIds,omitempty"` diff --git a/internal/ai/runtime/internal/impl/factory/agent_factory.go b/internal/ai/runtime/internal/impl/factory/agent_factory.go index fe7b9a0..5aeb36f 100644 --- a/internal/ai/runtime/internal/impl/factory/agent_factory.go +++ b/internal/ai/runtime/internal/impl/factory/agent_factory.go @@ -121,10 +121,21 @@ 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) + if input.Collector != nil { + input.Collector.SetInstructionSummary(einocallbacks.InstructionTraceSummary{ + SectionTitles: append([]string(nil), instructionResult.Summary.SectionTitles...), + HasProjectRule: instructionResult.Summary.HasProjectRule, + HasGovernanceRule: instructionResult.Summary.HasGovernanceRule, + HasAgentRule: instructionResult.Summary.HasAgentRule, + HasSkillRule: instructionResult.Summary.HasSkillRule, + HasToolRule: instructionResult.Summary.HasToolRule, + }) + } inner, err := adk.NewChatModelAgent(ctx, &adk.ChatModelAgentConfig{ Name: strings.TrimSpace(input.AIAgent.Name), Description: strings.TrimSpace(input.AIAgent.Description), - Instruction: buildAgentInstruction(input.AIAgent, input.SelectedSkill, input.InstructionToolDefinitions, input.StaticToolCodes), + Instruction: instructionResult.Text, Model: chatModel, ToolsConfig: adk.ToolsConfig{ ToolsNodeConfig: compose.ToolsNodeConfig{ @@ -153,7 +164,7 @@ func resolveToolSourceType(toolCode string) string { } } -func buildAgentInstruction(aiAgent *models.AIAgent, selectedSkill *models.SkillDefinition, toolDefinitions []einoadapter.MCPToolDefinition, extraToolCodes map[string]string) string { +func assembleAgentInstruction(aiAgent *models.AIAgent, selectedSkill *models.SkillDefinition, toolDefinitions []einoadapter.MCPToolDefinition, extraToolCodes map[string]string) InstructionAssemblyResult { baseInstruction := "" if aiAgent != nil { baseInstruction = strings.TrimSpace(aiAgent.SystemPrompt) @@ -191,7 +202,7 @@ func buildAgentInstruction(aiAgent *models.AIAgent, selectedSkill *models.SkillD `)) } projectRoot, _ := os.Getwd() - return NewInstructionAssembler().Build(InstructionAssemblerInput{ + return NewInstructionAssembler().Assemble(InstructionAssemblerInput{ ProjectRoot: projectRoot, AgentInstruction: baseInstruction, SkillInstruction: firstAppendixPart(appendixParts), diff --git a/internal/ai/runtime/internal/impl/factory/instruction_assembler.go b/internal/ai/runtime/internal/impl/factory/instruction_assembler.go index 859e88a..025b94a 100644 --- a/internal/ai/runtime/internal/impl/factory/instruction_assembler.go +++ b/internal/ai/runtime/internal/impl/factory/instruction_assembler.go @@ -19,6 +19,22 @@ type InstructionAssemblerInput struct { ProjectInstruction string } +// InstructionAssemblySummary 描述 instruction 各组成部分的来源摘要。 +type InstructionAssemblySummary struct { + SectionTitles []string + HasProjectRule bool + HasGovernanceRule bool + HasAgentRule bool + HasSkillRule bool + HasToolRule bool +} + +// InstructionAssemblyResult 为 instruction 装配结果。 +type InstructionAssemblyResult struct { + Text string + Summary InstructionAssemblySummary +} + var ( projectInstructionOnce sync.Once projectInstructionText string @@ -35,27 +51,46 @@ func NewInstructionAssembler() *InstructionAssembler { } func (a *InstructionAssembler) Build(input InstructionAssemblerInput) string { + return a.Assemble(input).Text +} + +// Assemble 构建最终 instruction 文本及其来源摘要。 +func (a *InstructionAssembler) Assemble(input InstructionAssemblerInput) InstructionAssemblyResult { parts := make([]string, 0, 5) + summary := InstructionAssemblySummary{SectionTitles: make([]string, 0, 5)} projectInstruction := strings.TrimSpace(input.ProjectInstruction) if projectInstruction == "" { projectInstruction = loadProjectInstruction(input.ProjectRoot) } if projectInstruction != "" { parts = append(parts, buildInstructionSection("项目级规则", projectInstruction)) + summary.HasProjectRule = true + summary.SectionTitles = append(summary.SectionTitles, "项目级规则") } if a != nil && strings.TrimSpace(a.governanceInstruction) != "" { parts = append(parts, buildInstructionSection("系统治理规则", a.governanceInstruction)) + summary.HasGovernanceRule = true + summary.SectionTitles = append(summary.SectionTitles, "系统治理规则") } if agentInstruction := strings.TrimSpace(input.AgentInstruction); agentInstruction != "" { parts = append(parts, buildInstructionSection("Agent 规则", agentInstruction)) + summary.HasAgentRule = true + summary.SectionTitles = append(summary.SectionTitles, "Agent 规则") } if skillInstruction := strings.TrimSpace(input.SkillInstruction); skillInstruction != "" { parts = append(parts, buildInstructionSection("当前技能上下文", skillInstruction)) + summary.HasSkillRule = true + summary.SectionTitles = append(summary.SectionTitles, "当前技能上下文") } if appendix := buildToolAppendix(input.ToolAppendices); appendix != "" { parts = append(parts, buildInstructionSection("工具补充规则", appendix)) + summary.HasToolRule = true + summary.SectionTitles = append(summary.SectionTitles, "工具补充规则") + } + return InstructionAssemblyResult{ + Text: strings.TrimSpace(strings.Join(parts, "\n\n")), + Summary: summary, } - return strings.TrimSpace(strings.Join(parts, "\n\n")) } func buildInstructionSection(title, body string) string {