ARTICLE DETAIL

资讯详情

深耕编程入门与网站建设的一线实战洞察。

gbrain 插件作者指南:通过 `GBRAIN_PLUGIN_PATH` 为下游 Agent 定义自定义 Subagent

gbrain 插件作者指南:通过 `GBRAIN_PLUGIN_PATH` 为下游 Agent 定义自定义 Subagent gbrain 插件作者指南通过GBRAIN_PLUGIN_PATH为下游 Agent 定义自定义 Subagent【免费下载链接】gbrainGarrys Opinionated OpenClaw/Hermes Agent Brain项目地址: https://gitcode.com/gh_mirrors/gb/gbrain本指南面向插件作者如果你维护一个下游 Agent自己的 OpenClaw 部署、工作流宿主、私有工具并希望随它一起分发自定义的 subagent 定义gbrain会在 worker 启动时通过GBRAIN_PLUGIN_PATH环境变量从仓库外部发现这些定义。读完本文你将掌握如何编写一个最小可用插件、配置gbrain.plugin.json清单与 subagent Markdown 定义文件、理解三条严格设计的安全规则路径策略、冲突策略、信任策略并能结合源码验证加载行为、排查启动期报错把自定义 subagent 无缝接入gbrain agent run流水线。两套插件系统别混淆。本文只覆盖subagent 定义即subagentjob handler 运行的 Markdown 提示词。自定义job handler由 Minion worker 执行的代码是另一套独立系统见 docs/guides/plugin-handlers.md。CLI 普通用户无需阅读本指南这是写给插件维护者的。插件体系一览从环境变量到 subagent 定义gbrain的插件机制本质上是一个**“宿主仓库外下发提示词”**的约定它不加载任何外部可执行代码只从磁盘上你指定的目录里读取两类文件gbrain.plugin.json—— 插件清单声明插件身份与契约版本subagents/*.md—— 每个文件是一份带 YAML frontmatter 的 subagent 定义正文即系统提示词。这套约定在源码中的落地实现位于 src/core/minions/plugin-loader.ts。加载器是纯文件系统 字符串解析的读 manifestJSON.parse、遍历子目录里以.md结尾的文件、用dataFrontmatter解析 frontmatter 与正文随后做注册表校验。它绝不执行插件目录里的任何脚本这是整个信任模型的基础。最小可用插件一个最小的插件只需要两个文件/path/to/my-plugin/ ├── gbrain.plugin.json └── subagents/ └── my-summarizer.mdgbrain.plugin.json{ name: my-plugin, version: 1.0.0, plugin_version: gbrain-plugin-v1 }subagents/my-summarizer.md--- name: my-summarizer model: claude-sonnet-4-6 allowed_tools: - brain_search - brain_get_page --- You are a brain page summarizer. Given a slug, fetch the page and produce a 3-sentence summary.注意allowed_tools里的工具名带有brain_前缀。这与 worker 启动时的校验逻辑对应jobs.ts在发现插件时会把 src/core/minions/tools/brain-allowlist.ts 中定义的操作名逐一加上brain_前缀构造成合法集合再交给加载器做子集校验见下文“信任策略”。开启插件环境变量与验证插件通过环境变量GBRAIN_PLUGIN_PATH开启多条路径用冒号分隔语义与$PATH完全一致export GBRAIN_PLUGIN_PATH/path/to/my-plugin gbrain jobs work # worker 启动时会打印插件加载日志 gbrain agent run summarize meetings/2026-04-20 --subagent-def my-summarizer多插件写法export GBRAIN_PLUGIN_PATH/path/to/plugin-a:/path/to/plugin-b插件发现发生在worker 启动阶段即gbrain jobs work。源码见 src/commands/jobs.tsworker 注册完内置 handler 后无条件调用loadPluginsFromEnvGBRAIN_PLUGIN_PATH为空时是安全的 no-op并把每条警告与每个成功加载的插件逐行写到 stderr格式为[plugin-loader] loaded my-plugin v1.0.0 (1 subagents)因此“插件有没有被加载”最直接的验证方式就是观察 worker 启动输出。若环境变量为空或路径不存在加载器只记录警告、不阻断 worker 启动源码中“Non-existent paths logged and skipped (do not fail worker startup)”。运行时通过 src/commands/agent.ts 的--subagent-def name参数指定使用哪个插件 subagentgbrain agent run prompt --subagent-def name Named plugin subagent (from GBRAIN_PLUGIN_PATH) --model id Model id as provider:model (default: subagent tier model, anthropic:claude-sonnet-4-6) --max-turns n Max assistant turns (default 20) --tools a,b,c Subset of registered tool names (comma list) --source id Brain source the subagents writes are scoped to --fanout-manifest path JSON array of {prompt, input_vars?} — one child eachagent.ts会把--subagent-def值写入提交数据的subagent_def字段再由 subagent handler 据此解析。若你希望整个部署环境默认带上插件也可参考 docs/guides/minions-deployment-snippets/gbrain.env.example 中对该环境变量的部署写法。三条规则严格是设计使然路径策略只接受绝对路径加载器对每条路径先做三项检查源码见plugin-loader.ts的rejectIfNotAbsolute情况处理相对路径拒绝警告“relative path rejected”~前缀路径拒绝警告“~-prefixed path rejected (expand explicitly)”URL 风格路径https://、file://等协议拒绝警告“remote URL rejected”设计理由在源码注释里写得很清楚不做隐式 cwd 或 home 展开——太容易误加载一个被篡改的同级目录插件加载必须走文件系统由用户控制磁盘上放了什么。此外不存在的路径会被跳过并告警但不会让 worker 启动失败避免一个失效路径拖垮整个部署。冲突策略左侧优先first wins如果两个插件都发布了同名 subagentGBRAIN_PLUGIN_PATH中靠前的那个获胜后者被丢弃并在 stderr 打出同时包含双方来源的警告[plugin-loader] collision: subagent my-summarizer from plugin-b at /path/to/plugin-b shadowed by earlier plugin-a at /path/to/plugin-a (first wins)实现上加载器维护一个subagentByName映射按路径顺序依次注册遇到同名即告警并跳过源码见loadPluginsFromEnv中的碰撞跟踪逻辑。这保证同名单的解析结果是确定性的不会依赖并发或读取顺序。信任策略只能下发 subagent 定义仅此而已插件能做的和不能做的边界非常硬不能声明新工具不能扩展 brain 工具 allow-list不能覆盖任何agentSafe之类的标志位allowed_tools:frontmatter 字段必须是派生 brain 工具注册表的子集。最关键的是校验时机在插件加载时worker 启动校验而不是在 subagent 派发时。这样插件里的一个拼写错误比如把brain_search写成brain_seach会在启动期响亮地失败[plugin-loader] rejected /path/to/my-plugin: subagent my-summarizer allowed_tools references unknown tools: brain_seach而不是在凌晨三点静默出现“工具从未触发”。源码中这段校验位于loadSinglePlugin当validAgentToolNames存在时逐一比对allowed_tools中的名字任何不在集合内的名字都让整个插件被拒绝。为什么插件不能声明新工具因为那需要一个新的plugin_version契约。当前契约锁定为gbrain-plugin-v1SUPPORTED_PLUGIN_VERSION常量该版本下不开放任何工具声明能力。加载器对plugin_version严格比对不匹配即整体拒绝该插件并提示 gbrain 支持的版本号。gbrain.plugin.json清单字段字段类型必填说明namestring是人类可读的插件 ID出现在警告与冲突日志中。源码要求非空字符串versionstring是插件的 semver仅作信息展示加载日志会打印plugin_versionstring是契约锁定。必须等于gbrain-plugin-v1否则整个插件被拒绝subagentsstring否subagent 子目录名默认subagents。转义尝试会被拒绝descriptionstring否信息性字段出现在加载/冲突警告中清单结构对应源码中的PluginManifest接口。两个容易踩的坑subagents字段的目录逃逸防护加载器会把subagents字段值path.resolve到插件根目录下若解析结果不在插件根目录内即出现../逃逸插件被拒绝错误信息为subagents path escapes plugin root。想用subagents: ./defs或subagents: defs/这类写法都可以但不要尝试subagents: ../outside。JSON 必须是合法 JSON清单解析失败invalid manifest JSON同样导致该插件被整体拒绝。Subagent 定义文件subagent 定义是带 YAML frontmatter 的普通 Markdown正文是系统提示词frontmatter 控制运行时行为。加载器只认subagents/目录或清单里自定义的子目录下的.md文件并用dataFrontmatter解析。被识别的 frontmatter 字段字段类型必填说明namestring否subagent 标识用作--subagent-def。默认取文件 basename去掉.mdmodelstring否Anthropic 模型 ID默认使用 handler 默认模型sonnet 档max_turnsnumber否assistant 轮次上限默认 20allowed_toolsstring[]否工具名白名单必须为派生 brain 注册表子集不匹配即拒绝未知 frontmatter 字段会被保留但被 handler 忽略——加载器把整个 frontmatter 原样存入SubagentDefinition.frontmatter不会因为多写了字段而报错。从源码补充的运行时行为细节除了上述字段subagent handlersrc/core/minions/handlers/subagent.ts还读取以下数据max_turns默认值data.max_turns ?? DEFAULT_MAX_TURNS与 CLI 帮助文本中的 “Max assistant turns (default 20)” 一致max_tokens每轮输出上限subagent 定义中可写max_tokens其解析优先级为显式data.max_tokens→ 配置项agent.max_output_tokens→ 模型感知默认值。也就是说虽然文档表格里没列它但从源码看它是被 handler 实际消费的合法字段model的能力校验提交 subagent job 时handler 会对模型做能力分类。若模型不支持原生工具调用unusable:no_tools、所属 provider 的配方声明不支持 subagent 循环unusable:no_subagent_loop、或 provider 未知unknown作业会被直接拒绝并抛出明确错误。--model的格式约定是provider:model默认anthropic:claude-sonnet-4-6provider 需匹配src/core/ai/recipes/中的配方。工具选择逻辑allowed_tools的过滤发生在 handler 内selectAllowedTools(registry, data.allowed_tools)从完整工具注册表中挑出你白名单里的工具组装成模型可见的 tool 列表选中的名字还会回填到作业数据里。所以白名单的作用是裁剪模型可见的工具面而注册表本身来自 brain 工具 allow-listsrc/core/minions/tools/brain-allowlist.ts当前包含query、search、get_page、list_pages、get_backlinks、traverse_graph、list_link_sources、resolve_slugs、get_ingest_log、put_page、add_timeline_entry、get_recent_salience、find_anomalies插件中需写作brain_name形式。会坑到你的注意事项插件定义在运行期间不可变更。加载器只在 worker 启动时读一次磁盘运行中编辑 subagent 定义不会生效必须重启 worker。这是刻意设计——热重载会破坏“崩溃可恢复重放”crash-resumable replay的语义。~/.gbrain/audit/subagent-jobs-*.jsonl是本地文件。如果 worker 与调用gbrain agent logs的 CLI 不在同一台主机上CLI 将看不到该 worker 的心跳。请假设 worker 与 CLI 共享文件系统。工具调用永远以ctx.remote true执行。即使是本地 CLI 调用也是如此源码中 subagent 循环的工具执行上下文多处硬编码remote: true。依赖remotetrue做门控的工具如file_upload的严格隔离、put_page的命名空间检查会照常生效。这是个好的默认值想通过 subagent 定义获取 brain 之外本地文件系统访问能力是做不到的。put_page写入受命名空间约束。id 为 42 的 subagent 只能写入wiki/agents/42/...之下。这同时体现在两个层面模型看到的工具 schema 中的 slug 模式以及put_page操作的服务端校验当viaSubagenttrue时 fail-closed。别试图绕过它——你会得到permission_denied。同理add_timeline_entry也被同样的 slug 围栏约束subagent 只能向自己本就能写的页面追加时间线条目。端到端示例一个下游 OpenClaw 插件假设你的 OpenClaw 部署要随自身仓库分发三个个人脑 subagent~/your-openclaw/ └── gbrain-plugin/ ├── gbrain.plugin.json └── subagents/ ├── meeting-ingestion.md ├── signal-detector.md └── daily-task-prep.md~/your-openclaw/gbrain-plugin/gbrain.plugin.json{ name: your-openclaw, version: 2026.4.20, plugin_version: gbrain-plugin-v1, description: Your OpenClaws personal-brain subagents }环境变量export GBRAIN_PLUGIN_PATH$HOME/your-openclaw/gbrain-plugin注意$HOME在 shell 中展开为绝对路径后才会被接受加载器本身不接受~前缀的原始写法。然后你的 OpenClaw 调用gbrain agent run --subagent-def meeting-ingestion --fanout-by transcript ...其定义会在 worker 启动时自动加载无需任何额外注册步骤。如何验证与排查测试与日志线索仓库自带针对加载器的测试套件test/plugin-loader.test.ts覆盖路径拒绝、清单校验、plugin_version不匹配、allowed_tools 越界、subagents目录逃逸等场景可作为插件行为的权威参照。排查故障时按以下顺序检查worker 启动 stderr是否有[plugin-loader] loaded ...成功或[plugin-loader] rejected .../[plugin-loader] collision: ...失败行环境变量形态echo $GBRAIN_PLUGIN_PATH确认是冒号分隔的绝对路径列表且路径真实存在、是可写目录清单字段name非空、plugin_version精确等于gbrain-plugin-v1、JSON 语法合法、subagents值未逃逸插件根目录定义文件文件名以.md结尾allowed_tools中的每个名字都在 brain 注册表内记得brain_前缀派发参数--subagent-def name里的名字与定义文件的name或 basename精确一致。小结插件机制是gbrain面向下游 Agent 生态的“提示词扩展点”你只需提供一个清单文件 一个 Markdown 目录就能让自己的 OpenClaw 或其他工作流宿主随仓库携带专属 subagent 定义。它的严格性体现在三处绝对路径才接受、左侧优先解决冲突、加载期而非派发期校验allowed_tools。理解并顺着这三条规则设计插件你就能获得“启动即亮眼报错、运行期稳定可控”的体验——正如源码注释所强调的错误宁可发生在 worker 启动时也不要发生在凌晨三点的静默失败里。【免费下载链接】gbrainGarrys Opinionated OpenClaw/Hermes Agent Brain项目地址: https://gitcode.com/gh_mirrors/gb/gbrain创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表