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
Cyrene/docs/api/plugin-development.md
T

3.9 KiB

插件开发指南

Cyrene 插件系统允许第三方开发者为昔涟扩展新工具。插件用 Go 编写,只需实现 PluginTool 接口即可被自动发现和调用。


核心接口

Plugin(插件入口)

type Plugin interface {
    Metadata() PluginMetadata           // 插件元信息
    Init(ctx context.Context, config PluginConfig) error
    Start(ctx context.Context, host HostAPI) error
    Tools() []Tool                       // 返回插件提供的工具列表
}

Tool(工具定义)

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

type ToolDefinition struct {
    Name        string                 // 工具名(LLM 用 function_call name 匹配)
    Description string                 // 描述——LLM 据此判断要不要调用
    Parameters  map[string]interface{} // JSON Schema 参数定义
}

最小示例

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 的工具注册区添加一行:

registerPluginTools(toolRegistry, &myplugin.HelloPlugin{})

重启 ai-core,LLM 即可在对话中自动调用 hello 工具。


ToolResult 格式

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 来说无区别。


相关仓库