2026-04-14 12:00:03 +08:00
|
|
|
|
package instruction
|
2026-04-10 14:43:57 +08:00
|
|
|
|
|
2026-04-12 09:56:38 +08:00
|
|
|
|
import "strings"
|
2026-04-10 14:43:57 +08:00
|
|
|
|
|
2026-04-14 10:24:13 +08:00
|
|
|
|
const defaultGovernanceInstruction = `
|
|
|
|
|
|
你正在一个有明确工程约束的客服系统中工作。
|
|
|
|
|
|
执行时必须严格遵守当前注入的项目规则、Agent 规则和技能规则。
|
|
|
|
|
|
如果存在工具白名单限制,只能调用当前允许的工具;信息不足时优先追问,不要伪造事实或跳过必要确认。
|
2026-04-17 17:11:26 +08:00
|
|
|
|
禁止承诺未经系统确认的处理时效、完成时间、回访时间或联系时间。
|
|
|
|
|
|
禁止代表人工团队、技术团队、售后团队承诺后续动作,除非当前上下文已有明确的工具结果、人工确认或知识库事实支持。
|
|
|
|
|
|
当用户只表示已发送资料、邮件、截图或附件时,只能确认已收到当前消息或建议等待人工确认,不能自行补充内部处理流程、SLA 或跟进安排。
|
2026-04-14 10:24:13 +08:00
|
|
|
|
`
|
|
|
|
|
|
|
2026-04-14 12:00:03 +08:00
|
|
|
|
type Assembler struct {
|
2026-04-10 14:43:57 +08:00
|
|
|
|
governanceInstruction string
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2026-04-14 12:00:03 +08:00
|
|
|
|
type AssemblerInput struct {
|
2026-04-14 10:24:13 +08:00
|
|
|
|
AgentInstruction string
|
|
|
|
|
|
GovernanceInstruction string
|
|
|
|
|
|
SkillInstruction string
|
|
|
|
|
|
ToolAppendices []string
|
|
|
|
|
|
ProjectInstruction string
|
2026-04-10 14:43:57 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2026-04-14 12:00:03 +08:00
|
|
|
|
type AssemblySummary struct {
|
2026-04-11 23:02:09 +08:00
|
|
|
|
SectionTitles []string
|
|
|
|
|
|
HasProjectRule bool
|
|
|
|
|
|
HasGovernanceRule bool
|
|
|
|
|
|
HasAgentRule bool
|
|
|
|
|
|
HasSkillRule bool
|
|
|
|
|
|
HasToolRule bool
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2026-04-14 12:00:03 +08:00
|
|
|
|
type AssemblyResult struct {
|
2026-04-11 23:02:09 +08:00
|
|
|
|
Text string
|
2026-04-14 12:00:03 +08:00
|
|
|
|
Summary AssemblySummary
|
2026-04-11 23:02:09 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2026-04-14 12:00:03 +08:00
|
|
|
|
func NewAssembler() *Assembler {
|
|
|
|
|
|
return &Assembler{governanceInstruction: strings.TrimSpace(defaultGovernanceInstruction)}
|
2026-04-10 14:43:57 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2026-04-14 12:00:03 +08:00
|
|
|
|
func (a *Assembler) Build(input AssemblerInput) string {
|
2026-04-11 23:02:09 +08:00
|
|
|
|
return a.Assemble(input).Text
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2026-04-14 12:00:03 +08:00
|
|
|
|
func (a *Assembler) Assemble(input AssemblerInput) AssemblyResult {
|
2026-04-10 14:43:57 +08:00
|
|
|
|
parts := make([]string, 0, 5)
|
2026-04-14 12:00:03 +08:00
|
|
|
|
summary := AssemblySummary{SectionTitles: make([]string, 0, 5)}
|
2026-04-10 14:43:57 +08:00
|
|
|
|
projectInstruction := strings.TrimSpace(input.ProjectInstruction)
|
|
|
|
|
|
if projectInstruction == "" {
|
2026-04-12 09:56:38 +08:00
|
|
|
|
projectInstruction = strings.TrimSpace(DefaultProjectInstruction)
|
2026-04-10 14:43:57 +08:00
|
|
|
|
}
|
|
|
|
|
|
if projectInstruction != "" {
|
|
|
|
|
|
parts = append(parts, buildInstructionSection("项目级规则", projectInstruction))
|
2026-04-11 23:02:09 +08:00
|
|
|
|
summary.HasProjectRule = true
|
|
|
|
|
|
summary.SectionTitles = append(summary.SectionTitles, "项目级规则")
|
2026-04-10 14:43:57 +08:00
|
|
|
|
}
|
2026-04-14 10:24:13 +08:00
|
|
|
|
governanceInstruction := strings.TrimSpace(input.GovernanceInstruction)
|
|
|
|
|
|
if governanceInstruction == "" && a != nil {
|
|
|
|
|
|
governanceInstruction = strings.TrimSpace(a.governanceInstruction)
|
|
|
|
|
|
}
|
|
|
|
|
|
if governanceInstruction != "" {
|
|
|
|
|
|
parts = append(parts, buildInstructionSection("系统治理规则", governanceInstruction))
|
2026-04-11 23:02:09 +08:00
|
|
|
|
summary.HasGovernanceRule = true
|
|
|
|
|
|
summary.SectionTitles = append(summary.SectionTitles, "系统治理规则")
|
2026-04-10 14:43:57 +08:00
|
|
|
|
}
|
|
|
|
|
|
if agentInstruction := strings.TrimSpace(input.AgentInstruction); agentInstruction != "" {
|
|
|
|
|
|
parts = append(parts, buildInstructionSection("Agent 规则", agentInstruction))
|
2026-04-11 23:02:09 +08:00
|
|
|
|
summary.HasAgentRule = true
|
|
|
|
|
|
summary.SectionTitles = append(summary.SectionTitles, "Agent 规则")
|
2026-04-10 14:43:57 +08:00
|
|
|
|
}
|
|
|
|
|
|
if skillInstruction := strings.TrimSpace(input.SkillInstruction); skillInstruction != "" {
|
|
|
|
|
|
parts = append(parts, buildInstructionSection("当前技能上下文", skillInstruction))
|
2026-04-11 23:02:09 +08:00
|
|
|
|
summary.HasSkillRule = true
|
|
|
|
|
|
summary.SectionTitles = append(summary.SectionTitles, "当前技能上下文")
|
2026-04-10 14:43:57 +08:00
|
|
|
|
}
|
|
|
|
|
|
if appendix := buildToolAppendix(input.ToolAppendices); appendix != "" {
|
|
|
|
|
|
parts = append(parts, buildInstructionSection("工具补充规则", appendix))
|
2026-04-11 23:02:09 +08:00
|
|
|
|
summary.HasToolRule = true
|
|
|
|
|
|
summary.SectionTitles = append(summary.SectionTitles, "工具补充规则")
|
|
|
|
|
|
}
|
2026-04-14 12:00:03 +08:00
|
|
|
|
return AssemblyResult{
|
2026-04-11 23:02:09 +08:00
|
|
|
|
Text: strings.TrimSpace(strings.Join(parts, "\n\n")),
|
|
|
|
|
|
Summary: summary,
|
2026-04-10 14:43:57 +08:00
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
func buildInstructionSection(title, body string) string {
|
|
|
|
|
|
title = strings.TrimSpace(title)
|
|
|
|
|
|
body = strings.TrimSpace(body)
|
|
|
|
|
|
if body == "" {
|
|
|
|
|
|
return ""
|
|
|
|
|
|
}
|
|
|
|
|
|
if title == "" {
|
|
|
|
|
|
return body
|
|
|
|
|
|
}
|
|
|
|
|
|
return title + ":\n" + body
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
func buildToolAppendix(input []string) string {
|
|
|
|
|
|
if len(input) == 0 {
|
|
|
|
|
|
return ""
|
|
|
|
|
|
}
|
|
|
|
|
|
parts := make([]string, 0, len(input))
|
|
|
|
|
|
for _, item := range input {
|
|
|
|
|
|
item = strings.TrimSpace(item)
|
|
|
|
|
|
if item == "" {
|
|
|
|
|
|
continue
|
|
|
|
|
|
}
|
|
|
|
|
|
parts = append(parts, item)
|
|
|
|
|
|
}
|
|
|
|
|
|
return strings.TrimSpace(strings.Join(parts, "\n\n"))
|
|
|
|
|
|
}
|