动态加载工具配置

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
2026-06-17 13:13:06 +08:00
co-authored by Claude
parent 249227ef0a
commit 4e4c6b32fc
13 changed files with 704 additions and 188 deletions
+6 -53
View File
@@ -5,8 +5,6 @@ import (
"os"
"strings"
searchagent "aichat/agents/search"
"gopkg.in/yaml.v3"
)
@@ -17,10 +15,7 @@ const (
defaultToolRouterTimeout = 30
defaultToolRouterMaxTokens = 512
defaultToolRouterSystemText = `你可以按需直接调用可用工具来回答用户问题。
用户询问简单数学计算、四则运算、加减乘除、括号表达式或明确要求算出数值结果时,调用 calculator
如果用户问题包含今天、今日、明天、昨天、本周、本月、本年、最近等相对时间,且后续需要搜索或查询数据库,应先调用 time 获取绝对日期范围。
需要实时网页资料、新闻、当前版本、近期事件、网页核验或用户明确要求联网时,调用 search。
需要查询本地业务数据、日程、会议、待办、记录、统计或时间范围内数据时,调用 sql。
每个工具的 description 描述了它的适用场景和调用条件
工具结果优先于模型内置知识;工具失败时必须如实说明,不要编造结果。
只调用确实必要的工具。`
)
@@ -44,7 +39,7 @@ type ToolRouterConfig struct {
Timeout int `yaml:"timeout" json:"timeout"`
MaxTokens int `yaml:"max_tokens" json:"max_tokens"`
SystemPrompt string `yaml:"system_prompt" json:"system_prompt"`
Tools []ToolRouteConfig `yaml:"tools" json:"tools"`
Tools []ToolRouteConfig `yaml:"tools,omitempty" json:"tools,omitempty"`
}
type ToolRouteConfig struct {
@@ -105,12 +100,6 @@ func DefaultToolRouterConfig() ToolRouterConfig {
Timeout: defaultToolRouterTimeout,
MaxTokens: defaultToolRouterMaxTokens,
SystemPrompt: defaultToolRouterSystemText,
Tools: []ToolRouteConfig{
{Name: "calculator", Enabled: true, Description: ""},
{Name: "time", Enabled: true, Description: ""},
{Name: "search", Enabled: true, Description: ""},
{Name: "sql", Enabled: true, Description: ""},
},
}
}
@@ -123,7 +112,7 @@ func Default() Config {
return cfg
}
func Load(path string) (*Config, []searchagent.ProfileConfig, error) {
func Load(path string) (*Config, []map[string]any, error) {
if err := ensureFile(path); err != nil {
return nil, nil, err
}
@@ -285,7 +274,6 @@ func NormalizeToolRouterConfig(cfg *Config) (bool, error) {
func normalizeToolRouterConfig(cfg *Config) (bool, error) {
changed := false
defaults := DefaultToolRouterConfig()
cfg.ToolRouter.OpenAIName = strings.TrimSpace(cfg.ToolRouter.OpenAIName)
if cfg.ToolRouter.Timeout <= 0 {
cfg.ToolRouter.Timeout = defaultToolRouterTimeout
@@ -303,10 +291,6 @@ func normalizeToolRouterConfig(cfg *Config) (bool, error) {
cfg.ToolRouter.SystemPrompt = systemPrompt
changed = true
}
if len(cfg.ToolRouter.Tools) == 0 {
cfg.ToolRouter.Tools = defaults.Tools
changed = true
}
seen := map[string]bool{}
for i := range cfg.ToolRouter.Tools {
tool := &cfg.ToolRouter.Tools[i]
@@ -324,48 +308,17 @@ func normalizeToolRouterConfig(cfg *Config) (bool, error) {
}
seen[name] = true
}
byName := map[string]ToolRouteConfig{}
for _, tool := range cfg.ToolRouter.Tools {
byName[tool.Name] = tool
}
merged := make([]ToolRouteConfig, 0, len(cfg.ToolRouter.Tools)+len(defaults.Tools))
used := map[string]bool{}
for _, tool := range defaults.Tools {
if existing, ok := byName[tool.Name]; ok {
merged = append(merged, existing)
} else {
merged = append(merged, tool)
changed = true
}
used[tool.Name] = true
}
for _, tool := range cfg.ToolRouter.Tools {
if !used[tool.Name] {
merged = append(merged, tool)
}
}
if len(merged) != len(cfg.ToolRouter.Tools) {
changed = true
} else {
for i := range merged {
if merged[i].Name != cfg.ToolRouter.Tools[i].Name {
changed = true
break
}
}
}
cfg.ToolRouter.Tools = merged
return changed, nil
}
func readLegacySearchProfiles(data []byte) []searchagent.ProfileConfig {
func readLegacySearchProfiles(data []byte) []map[string]any {
var legacy struct {
Search searchagent.ProfileConfigs `yaml:"search"`
Search []map[string]any `yaml:"search"`
}
if err := yaml.Unmarshal(data, &legacy); err != nil {
return nil
}
return []searchagent.ProfileConfig(legacy.Search)
return legacy.Search
}
func Write(path string, cfg Config) error {