# 插件开发指南 面向 Agent-System v0.1.0(plugin API `1.0`)。原则:**能数据化的都数据化,代码只留接口**—— 插件 = manifest + 声明资产 + 可选代码;声明资产热加载,装卸不触碰核心二进制。 参考实现:Dev 仓 `plugins/example`(覆盖全部五类能力,可直接复制改造)。 ## 1. 目录结构 ``` my-plugin/ plugin.json # 必需:manifest tools/*.json # 声明式 HTTP 工具(v1 代码工具走远期 sidecar 档) workflows/*.json # 工作流定义(步骤:prompt/tool/hitl/artifact) intents/*.json # 意图 specs(agent-intent overlay 形态;slots 即 HITL 询问项) prompts/*.md # 提示词/画像模板 panels/*.json # 右栏面板(UI schema) cards/*.json # 对话卡片模板(UI schema) settings.json # 插件自身设置声明(自动出现在设置中心) ``` ## 2. Manifest ```json { "id": "my-plugin", // 唯一;即目录名 "name": "我的插件", "version": "0.1.0", "apiVersion": "1.0", // 宿主兼容窗口检查(不匹配整批拒绝) "requires": { "network": ["api.example.com"] }, // 权限清单(装载时可见) "provides": { // 声明各目录下的资产名(不含扩展名) "tools": ["http_fetch"], "intents": ["ask"], "panels": ["main"], "cards": ["note"], "prompts": ["writer"], "settings": ["apikey"] } } ``` **fail-closed**:任一资产缺失/非法 JSON/manifest 不合法 → 该插件整批拒绝,错误在启动日志与 `POST /api/plugins/reload` 响应中显式呈现;既有注册不受影响。 ## 3. 五类能力 ### 3.1 声明式 HTTP 工具(tools/*.json) ```json { "name": "http_fetch", "description": "获取 URL 内容", "parameters": { "type": "object", "properties": { "url": { "type": "string" } }, "required": ["url"] }, "http": { "method": "GET", "url": "{{param.url}}", "headers": { "Accept": "application/json" }, "authRef": "models.chat.apiKey", // 或 env:MY_TOKEN;引用设置密钥/环境变量 "resultPath": "data.items", // jq 点路径裁剪(支持数组索引);空取整个响应 "timeoutMs": 10000 } } ``` - 模板变量 `{{param.x}}` 从模型调用参数注入;无脚本语义(防注入)。 - 注册后受画像三清单约束(默认画像对 `http.` 前缀族要求执行前 HITL 确认)。 - 调用审计自动记录(入参摘要/状态/时长)。 ### 3.2 工作流(workflows/*.json) 步骤四类:`prompt`(发指令模板)/ `tool`(调工具)/ `hitl`(产卡片)/ `artifact`(产出工件)。 `intentId` 绑定意图后,命中即可启动(意图→工作流的联动消费在编排侧持续增强,v1 为目录数据)。 ### 3.3 意图(intents/*.json) agent-intent overlay 形态(数组): ```json [ { "id": "ask", "domain": "demo", "description": "…", "includes_any": ["示例"], "slots": [] } ] ``` slots 声明即 HITL 该问什么(能力目录理念);宿主识别闸门接入后自动成为命令/分流入口。 ### 3.4 面板与卡片(UI schema 有限词汇) panels/main.json: ```json { "id": "main", "title": "我的面板", "body": [ { "type": "markdown", "markdown": "## 说明\n…" }, { "type": "kv", "title": "状态", "kv": [["版本", "0.1.0"]] }, { "type": "list", "items": ["要点一", "要点二"] }, { "type": "doc-ref", "docId": "art_xxx" }, { "type": "actions", "actions": [{ "id": "refresh", "label": "刷新" }] }, { "type": "chart-lite", "chart": { "kind": "bar", "labels": ["A","B"], "series": [3, 5] } }, { "type": "section", "title": "分组", "children": [ … ] } ] } ``` cards/note.json:`{ "kind": "note", "data": [ …UINode ] }`。 **词汇边界**:section / list / kv / form / markdown / doc-ref / actions / chart-lite。 表达不了的高级交互 → 向 Core 提案新词汇(契约扩展流程),**不要**期望注入 React 组件——前端不开放此口子,这是插件不破坏前端的机制保证。 ### 3.5 提示词模板(prompts/*.md) 内容即模板正文;用户可复制为自有画像后微调。 ### 3.6 插件设置(settings.json) ```json [ { "key": "apikey", "group": "plugin:my-plugin", "label": "服务密钥", "type": "secret", "effect": "hot" } ] ``` 自动出现在设置中心 `plugin:my-plugin` 分区;`type: secret` 掩码显示不回显。 ## 4. 装载、热重载与卸载 - 启动装载:`agent-system serve --plugins `。 - 热重载:设置 → 插件 → ⟳(或 `POST /api/plugins/reload`)——重扫目录:新增装载、同 ID 重载(先注销旧注册再装新)、消失卸载。 - 卸载语义:注册项注销;在途任务对已卸载工具的引用按「定义缺失」稳定报错,不静默;内置能力零影响(测试断言覆盖)。 ## 5. 验证清单(发布前自测) ```bash # 1) manifest 与资产合法性(重载结果应无错误) curl -s -X POST localhost:8787/api/plugins/reload # 2) 注册结果 curl -s localhost:8787/api/tools | jq '.[] | select(.pluginId=="my-plugin")' curl -s localhost:8787/api/plugins | jq '.[] | select(.manifest.id=="my-plugin")' # 3) 装卸回退(移走目录→reload→内置功能应完全正常) mv plugins/my-plugin /tmp/ && curl -X POST localhost:8787/api/plugins/reload ``` ## 6. 领域插件立项提示(CDMO 等) 按既定决策(设计 r2/r3):领域插件基于本契约**全新设计**——工作流即数据、意图 slots 驱动 HITL、 文档产出走 artifacts、面板走 UI schema;不迁移老系统代码/接口/数据格式,老系统仅作领域业务知识参考。 立项时先写该插件的设计方案(建议放本仓 docs/proposals/)。