This repository has been archived on 2026-08-12. You can view files and clone it. You cannot open issues or pull requests or push a commit.
Files
AskaEth caa9bfced5 docs: 工具调用系统介绍文档
- 17个工具完整列表(共享插件 + AI-Core专属)
- 注册机制 + ToolExecutor接口
- 对话中完整调用流程(含LLM API请求/响应示例)
- 工具调用循环(最多5轮)
- 后台思考白名单机制
- 超时异步处理

Co-Authored-By: Claude <noreply@anthropic.com>
2026-06-23 12:53:23 +08:00

184 lines
5.4 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Cyrene 工具调用系统
> **日期**2026-06-23
> **适用范围**:对话 + 后台自主思考
---
## 概述
昔涟可以调用 16 个工具来完成任务——从搜索互联网、控制智能家居,到创建提醒、检索知识库。
工具调用的核心机制是 **OpenAI Function Calling 协议**:每次 LLM 请求时,将所有可用工具的名称、描述、参数格式一并发送。LLM 自行判断是否需要调用工具,返回工具名和参数,由服务端执行后把结果送回 LLM 生成最终回复。
---
## 注册机制
### 启动时注册
`ai-core/cmd/main.go` 在服务启动时将全部工具注册到 `ToolRegistry`
```
共享插件 (pkg/plugins)
calculator 数学表达式求值
datetime 日期时间计算/格式化
text 文本处理(统计/截断)
crypto 哈希/加解密
random 随机数/字符串
markdown Markdown 渲染
json JSON 解析/查询
file 文件读写/列表
http HTTP 请求
web_search SearXNG 网络搜索
web_fetch 网页内容提取
AI-Core 专属 (internal/tools)
iot_query IoT 设备状态查询
iot_control IoT 设备操控
knowledge_search 知识库 RAG 检索
knowledge_ingest 知识库文档导入
reminder_create 创建提醒
reminder_list 列出提醒
reminder_delete 删除提醒
```
### 工具定义
每个工具实现 `ToolExecutor` 接口:
```go
type ToolExecutor interface {
Execute(ctx context.Context, args map[string]interface{}) (*ToolResult, error)
Definition() ToolDefinition
}
type ToolDefinition struct {
Name string // 工具名,LLM 用它来选择
Description string // 工具用途描述,LLM 据此判断是否需要调用
Parameters map[string]interface{} // JSON Schema 参数定义
}
```
`Description` 就是 LLM 的"说明书"——它通过阅读描述来判断当前对话是否需要调用这个工具。
---
## 对话中的调用流程
```
用户: "帮我查一下今天天气"
Synthesizer.Synthesize()
├─ 1. buildOpenAITools()
│ 从 ToolRegistry 取出全部工具的定义
│ 转换为 OpenAI Function Calling 格式
├─ 2. ChatWithTools(messages, tools)
│ POST LLM API:
│ {
│ "model": "deepseek-v4-flash",
│ "messages": [
│ {"role":"system","content":"你是昔涟..."},
│ {"role":"user","content":"帮我查一下今天天气"}
│ ],
│ "tools": [
│ {
│ "type": "function",
│ "function": {
│ "name": "web_search",
│ "description": "搜索互联网获取实时信息...",
│ "parameters": {
│ "type": "object",
│ "properties": {
│ "query": {"type": "string", "description": "搜索关键词"}
│ },
│ "required": ["query"]
│ }
│ }
│ },
│ // ... 其余 15 个工具
│ ],
│ "tool_choice": "auto"
│ }
│ LLM 判断: 用户要查天气 → 需要 web_search
│ 返回:
│ {
│ "choices": [{
│ "delta": {
│ "tool_calls": [{
│ "id": "call_abc123",
│ "function": {
│ "name": "web_search",
│ "arguments": "{\"query\":\"今天天气\"}"
│ }
│ }]
│ }
│ }]
│ }
├─ 3. ToolRegistry.Execute("web_search", {query: "今天天气"})
│ → 发送 HTTP 请求到 SearXNG
│ → 返回: {success: true, data: "晴转多云 22°C..."}
├─ 4. 工具结果追加到对话历史
│ messages += {
│ role: "tool",
│ tool_call_id: "call_abc123",
│ content: "{\"success\":true,\"data\":\"晴转多云 22°C...\"}"
│ }
└─ 5. 再次 ChatWithTools
LLM 读取工具结果 → 生成最终回复:
"今天晴转多云,22°C♪ 很适合出门走走呢~"
```
---
## 工具调用循环
LLM 可以在一轮对话中**多次调用工具**,最多 **5 轮**
```
第 1 轮: LLM → web_search("今天天气")
第 2 轮: LLM → web_fetch("https://weather.com/detail")
第 3 轮: LLM 综合结果 → 生成回复
```
每轮 LLM 都可以选择继续调工具或直接回复。达到 5 轮上限后强制生成回复。
---
## 后台思考中的工具调用
后台思考器(Thinker)使用相同的工具注册中心,但通过 **`AutonomousToolPolicy`** 白名单控制:
```go
AllowedTools: []string{
"iot_query", "iot_control", "memory_search", "web_search",
"calculator", "datetime", "web_fetch",
"reminder_create", "reminder_list", "reminder_delete",
...
}
```
思考循环中只有白名单内的工具可被调用,防止自主思考执行高风险操作。
---
## 工具超时与异步
每个工具调用有 **8 秒超时**。超时的工具转入后台异步执行,结果在下一轮对话中返回。LLM 会收到提示:"该工具正在后台运行,你可以继续聊天"。
---
## 如何添加新工具
1. 实现 `ToolExecutor` 接口(`Definition()` + `Execute()`
2.`main.go``toolRegistry.Register(wrapTool(...))`
3. 如需在思考中可用,加入 `AutonomousToolPolicy.AllowedTools`
工具注册后,LLM 会在下次请求时自动感知到新工具——无需修改 prompt。