docs: 插件开发指南 + README清理dev_must_read和pg-backup引用
This commit is contained in:
@@ -207,8 +207,8 @@ Cyrene/
|
|||||||
| [docs/api/gateway-api.md](docs/api/gateway-api.md) | 客户端 API 文档 |
|
| [docs/api/gateway-api.md](docs/api/gateway-api.md) | 客户端 API 文档 |
|
||||||
| [docs/api/ethend.md](docs/api/ethend.md) | ethend CLI + Web 控制台文档 |
|
| [docs/api/ethend.md](docs/api/ethend.md) | ethend CLI + Web 控制台文档 |
|
||||||
| [docs/api/backend-services/](docs/api/backend-services/) | 后端服务 API 文档 |
|
| [docs/api/backend-services/](docs/api/backend-services/) | 后端服务 API 文档 |
|
||||||
| [docs/dev_must_read.md](docs/dev_must_read.md) | 开发者必读 |
|
| [docs/api/backend-services/tool-system.md](docs/api/backend-services/tool-system.md) | 工具调用系统 |
|
||||||
| [docs/pg-backup-migration.md](docs/pg-backup-migration.md) | PG 备份与迁移指南 |
|
| [docs/api/plugin-development.md](docs/api/plugin-development.md) | 插件开发指南 |
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,141 @@
|
|||||||
|
# 插件开发指南
|
||||||
|
|
||||||
|
> Cyrene 插件系统允许第三方开发者为昔涟扩展新工具。插件用 Go 编写,只需实现 `Plugin` 和 `Tool` 接口即可被自动发现和调用。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 核心接口
|
||||||
|
|
||||||
|
### Plugin(插件入口)
|
||||||
|
|
||||||
|
```go
|
||||||
|
type Plugin interface {
|
||||||
|
Metadata() PluginMetadata // 插件元信息
|
||||||
|
Init(ctx context.Context, config PluginConfig) error
|
||||||
|
Start(ctx context.Context, host HostAPI) error
|
||||||
|
Tools() []Tool // 返回插件提供的工具列表
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### Tool(工具定义)
|
||||||
|
|
||||||
|
```go
|
||||||
|
type Tool interface {
|
||||||
|
Definition() ToolDefinition // 工具的 name/description/parameters
|
||||||
|
Execute(ctx context.Context, args map[string]interface{}) (*ToolResult, error)
|
||||||
|
Validate(args map[string]interface{}) error
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
**LLM 通过 `Definition()` 返回的 `description` 判断何时调用此工具**——所以描述要写得清晰准确。
|
||||||
|
|
||||||
|
### ToolDefinition
|
||||||
|
|
||||||
|
```go
|
||||||
|
type ToolDefinition struct {
|
||||||
|
Name string // 工具名(LLM 用 function_call name 匹配)
|
||||||
|
Description string // 描述——LLM 据此判断要不要调用
|
||||||
|
Parameters map[string]interface{} // JSON Schema 参数定义
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 最小示例
|
||||||
|
|
||||||
|
```go
|
||||||
|
package myplugin
|
||||||
|
|
||||||
|
import "git.yeij.top/AskaEth/Cyrene-Plugins/sdk"
|
||||||
|
|
||||||
|
type HelloPlugin struct{}
|
||||||
|
|
||||||
|
func (p *HelloPlugin) Metadata() sdk.PluginMetadata {
|
||||||
|
return sdk.PluginMetadata{
|
||||||
|
Name: "hello", Version: "1.0.0", Author: "your-name",
|
||||||
|
Description: "示例插件:向用户问好",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *HelloPlugin) Init(ctx context.Context, cfg sdk.PluginConfig) error { return nil }
|
||||||
|
func (p *HelloPlugin) Start(ctx context.Context, host sdk.HostAPI) error { return nil }
|
||||||
|
func (p *HelloPlugin) Stop(ctx context.Context) error { return nil }
|
||||||
|
|
||||||
|
func (p *HelloPlugin) Tools() []sdk.Tool {
|
||||||
|
return []sdk.Tool{&HelloTool{}}
|
||||||
|
}
|
||||||
|
|
||||||
|
// --- Tool ---
|
||||||
|
type HelloTool struct{}
|
||||||
|
|
||||||
|
func (t *HelloTool) Definition() sdk.ToolDefinition {
|
||||||
|
return sdk.ToolDefinition{
|
||||||
|
Name: "hello",
|
||||||
|
Description: "向用户打招呼。当用户说你好/嗨/哈喽时调用。",
|
||||||
|
Parameters: map[string]interface{}{
|
||||||
|
"type": "object",
|
||||||
|
"properties": map[string]interface{}{
|
||||||
|
"name": map[string]string{"type": "string", "description": "用户名字(可选)"},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (t *HelloTool) Execute(ctx context.Context, args map[string]interface{}) (*sdk.ToolResult, error) {
|
||||||
|
name, _ := args["name"].(string)
|
||||||
|
if name == "" { name = "开拓者" }
|
||||||
|
return &sdk.ToolResult{Success: true, Output: name + ",昔涟向你问好♪"}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (t *HelloTool) Validate(args map[string]interface{}) error { return nil }
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 注册到 Cyrene
|
||||||
|
|
||||||
|
在 `ai-core/cmd/main.go` 的工具注册区添加一行:
|
||||||
|
|
||||||
|
```go
|
||||||
|
registerPluginTools(toolRegistry, &myplugin.HelloPlugin{})
|
||||||
|
```
|
||||||
|
|
||||||
|
重启 ai-core,LLM 即可在对话中自动调用 `hello` 工具。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## ToolResult 格式
|
||||||
|
|
||||||
|
```go
|
||||||
|
type ToolResult struct {
|
||||||
|
ToolName string `json:"tool_name"`
|
||||||
|
Success bool `json:"success"`
|
||||||
|
Output string `json:"output,omitempty"` // 成功时的结果文本
|
||||||
|
Error string `json:"error,omitempty"` // 失败时的错误信息
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
`Output` 会直接注入 LLM 对话,所以要写成自然语言格式。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 调用机制
|
||||||
|
|
||||||
|
```
|
||||||
|
用户: "帮我打个招呼"
|
||||||
|
→ LLM 看到所有工具的 Definition()
|
||||||
|
→ 判断需要调用 hello 工具
|
||||||
|
→ function_call: {name: "hello", arguments: {name: "开拓者"}}
|
||||||
|
→ ToolRegistry.Execute("hello", {name: "开拓者"})
|
||||||
|
→ HelloTool.Execute() → "开拓者,昔涟向你问好♪"
|
||||||
|
→ LLM 将结果融入回复
|
||||||
|
```
|
||||||
|
|
||||||
|
17 个内置工具也是同样的机制,插件和内置工具对 LLM 来说无区别。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 相关仓库
|
||||||
|
|
||||||
|
- [cyrene-plugins](https://git.yeij.top/AskaEth/Cyrene-Plugins) — 插件 SDK + 内置插件源码
|
||||||
|
- [工具调用系统介绍](tool-system.md) — 完整调用链路说明
|
||||||
Reference in New Issue
Block a user