给 Claude Code 写插件的人迟早会撞上一堵墙:插件需要记住用户的选择,但你不能写数据库,不能装 Redis,连环境变量都不好使。Claude Code 的插件运行在 hooks、commands 和 agents 里,每次启动都是全新的 shell 进程。
多数人第一反应是写个 JSON 配置文件丢在项目根目录。然后你会发现在 bash 里解析 JSON 有多痛。即使你用 jq 绕过去,存什么格式、怎么读写、用户怎么改,每个插件都得重新发明一遍轮子。
configured-agent 是 Anthropic 在 Smithery 上发布的一个 Skill,本质上是一套经过验证的模式和代码模板,专门解决这个“插件到底把配置放哪”的月经问题。它不是库,不是依赖,就是一个设计模式加几个复制即用的脚本。

说真的,这篇文章就是把这套模式拆开看看,从文件结构到解析技巧到真实案例,帮你理解为什么它选 YAML frontmatter 而不是 JSON / TOML / .env,以及它在 multi-agent-swarm 和 ralph-wiggum 这两个插件的实际用法里暴露了哪些取舍。
环境准备
前置条件低到几乎没有。configured-agent 不是一个要安装的包,它是一套约定和代码模板,你只需要一个能用 Claude Code 的项目。
唯一的外部依赖是 bash 里的 sed 和 awk,用来解析 YAML frontmatter。好消息是这两个工具在任何 Unix-like 系统上都有,Windows 下用 Git Bash 或者 WSL 同样没问题。
还有一个容易被跳过的步骤:.gitignore。configured-agent 明确要求把 .local.md 文件加入 gitignore,这是因为它存的是用户本地的配置和运行时状态,不应该被提交到仓库里。加一行就行:
.claude/*.local.md
配置文件和敏感信息混进 git 历史这种事,犯过一次之后就再也不想犯第二次了。
创建配置文件的路径是固定的:.claude/插件名.local.md,直接放在项目根目录。文件格式是标准的 YAML frontmatter 夹在两个 --- 之间,正文部分放 markdown。一个最简的模板长这样:
---
enabled: true
mode: standard
max_retries: 3
---
# Plugin Configuration
This plugin is configured for standard validation mode.
Contact @team-lead with questions.
你的插件只需要用一段不到十行的 bash 代码读这个文件。configured-agent 甚至已经把解析模板写好了,复制粘贴然后改一下字段名就行。

验证配置有没有生效也很直观。创建一个默认的 .local.md 文件,在插件的 hook 脚本开头加一行 echo "DEBUG: enabled=$ENABLED",跑一次就能看到值确实被读到了。如果读不到,常见的坑有两个:frontmatter 前后的 --- 分隔符不完整,或者 sed 的正则匹配到了文件中间的其他横线(configured-agent 的文档里对这两个坑都给了明确的规避写法)。
操作流程
搞清楚 configured-agent 的工作链路其实就三件事:文件放在哪、怎么读、怎么用。但它把这“三件事”做得格外干净,每一步都给出了快捷出口,这才是值得花篇幅讲的地方。
插件的 hook 脚本启动后,第一时间检查 .claude/插件名.local.md 是否存在。不存在?直接 exit 0。这个设计是整套模式里最聪明的一步。没有配置文件就等于“用户没装这个插件”,不报错、不中断、不留痕迹,跟 Claude Code 本身的行为一模一样。很多插件的 hook 脚本一上来就疯狂报 Warning,configured-agent 的策略是沉默即优雅。
读到文件之后,用 sed 提取 frontmatter 区域,再逐字段 grep 取值。核心解析代码简约到只有四行:
STATE_FILE=".claude/my-plugin.local.md"
[[ ! -f "$STATE_FILE" ]] && exit 0
FRONTMATTER=$(sed -n '/^---$/,/^---$/{ /^---$/d; p; }' "$STATE_FILE")
ENABLED=$(echo "$FRONTMATTER" | grep '^enabled:' | sed 's/enabled: *//')
这里它没有用 yq 或 jq,而是纯 bash 硬解。原因很简单:如果引入一个外部解析器,你的插件安装文档就得从”丢一个 .local.md 文件进去”变成”先去装 yq,配置包管理器,确认 PATH 正确”。对于一个配置方案来说,依赖链每多一个节点就多一个断点。

拿到配置值之后的行为就因插件而异了。multi-agent-swarm 用它来让 agent 向 coordinator 汇报任务完成状态,ralph-wiggum 用它来控制自动修复循环的迭代次数和退出条件。同一个模式,两种完全不同的用法。
关键设计
如果把 configured-agent 的设计决策摊开来看,有三个地方做得不太寻常。
第一是选 YAML frontmatter 而不是 JSON 或 TOML。从纯技术角度看这不算最优解,YAML 的缩进敏感和隐式类型转换在编程语言里是已知痛点。但在 Claude Code 这个具体场景里,YAML frontmatter 有一个压倒性的优势:Claude 的模型对它的解析能力是原生级别的。你把一份 .local.md 文件丢给 Claude,它比你更懂该怎么读里面的 frontmatter。选型理由不是“格式最好”,是“受众最熟悉”。
第二是 local.md 这个命名约定的双关设计。.local.md 里的 local 有两个含义:一是“本地”,提醒你加入 .gitignore;二是“用户自己的”,明确这个文件是用户编辑的,不是插件分发包的一部分。用文件名本身承载语义,省掉一大段配置文档。
第三个设计决策更容易被忽略。configured-agent 在 SKILL.md 里反复强调的“Quick Exit Pattern”,把插件未配置状态和禁用状态合并为一个逻辑分支。配置文件中 enabled: true/false 是同一个处理路径,不会因为禁用了就报错。这种设计思路在嵌入式系统和游戏引擎里很常见,但在 CLI 工具链里反而是少数派。

使用场景
场景一跟你可能遇到的情况最接近。你在开发一个 Claude Code 的 security-scan 插件,它需要在每次写入文件后做安全检查。你希望用户能按项目粒度决定要不要跑扫描,甚至决定扫描的严格程度。用 configured-agent 的模式,用户只需要在 .claude/security-scan.local.md 里设置 enabled: true 和 validation_level: strict,hooks 脚本启动时读这两个值就行。想关掉?改一行 enabled: false。不用碰 JSON,不用改 hooks.json,甚至不用重启 Claude Code 以外的任何东西。
场景二是 agent 协调。multi-agent-swarm 这个真实案例里,每个 agent 在完成任务后通过 hook 脚本通知 coordinator。通知目标的 session name、agent 自身的名字、依赖的任务编号,全存在 .claude/multi-agent-swarm.local.md 里。这个场景特别能体现 YAML frontmatter 比 .env 强的地方:它可以存列表和嵌套结构。一个 dependencies: ["Task 3.4", "Task 3.5"] 在 .env 里得写成 DEP_1=... DEP_2=...,读起来也费劲。
场景三更极端,也更接近 configured-agent 设计者最初可能预想的用法。ralph-wiggum 是一个自动修复循环插件,每次失败后自动重试。它的 .local.md 不仅存配置(max_iterations),还存状态(当前 iteration 计数)。hook 脚本每次运行后会修改这个文件,把计数加一。这意味着 .local.md 不只是配置文件,它是插件的持久化存储层。在缺乏 Redis 或任何数据库的 Claude Code 运行时里,文件就是唯一的共享状态介质。
洞察与反思
configured-agent 的核心价值不在模式本身,在于它揭示了一个被你忽视的事实:Claude Code 的插件生态缺失了一套标准的持久化基础设施。其他插件平台,无论是 VSCode Extension API 还是浏览器扩展的 storage API,都有官方提供的配置存储接口。Claude Code 目前没有。
这一点短期看是限制,长期看可能是正确的克制。如果 Anthropic 官方推出一个”插件配置 API”,它需要同时处理这些维度:
-
作用域该怎么分:全局生效、按项目生效、还是按会话生效? -
值类型和 schema 校验:布尔值、列表、嵌套结构,谁来保证格式正确? -
迁移策略:插件升级后旧配置怎么处理? -
版本兼容性:新版本插件读到旧格式配置应该报错还是静默降级?
任何一个做错了都会是生态债。而 .local.md 模式相当于把责任下放给了插件开发者:你们自己存,但用一个统一的文件格式,至少在可读性上保证一致性。
从多 agent 协作的视角重新看这套模式,它其实是一种最小化的状态通道。在没有共享内存、没有消息总线的约束下,文件成了 agent 之间唯一可靠的通信媒介。.local.md 就是这个通道的 contract,YAML frontmatter 是 schema,markdown body 是自由文本的附带信息。这种设计在分布式系统理论里有一个名字:state via file checkpointing。只是在 Claude Code 生态里它被裹上了一层”配置文件”的皮,而多数人不会多看一眼这层皮下到底是什么。
资源地址
| 资源 | 链接 |
|---|---|
| Smithery 页面 | smithery.ai/skills/anthropics/configured-agent |
| Claude Code 官方文档 | docs.anthropic.com |
总结
花一个小时看完 configured-agent 的 SKILL.md,你得到的东西其实比”一套配置方案”要多。它的三个核心资产几乎可以原样搬到任何 Claude Code 插件里:
-
bash 解析代码:read-settings-hook.sh 提供了完整的 frontmatter 读取、字段提取、默认值回退链路 -
Quick Exit 模式:一行 [[ ! -f "$STATE_FILE" ]] && exit 0解决了插件未安装和已禁用的静默处理 -
安全校验脚本:validate-settings.sh 覆盖了路径遍历、输入转义和数值范围检查
如果你正在给自己的插件设计配置层,直接把这三个文件复制过去,比从零写省一半 debug 时间。唯一需要注意的点是它假设你的用户愿意手动编辑 markdown 文件。如果你的插件面向非技术用户,这个假设就不成立。但在 Claude Code 的语境里,能跑 CLI 的用户本来就不排斥改几个文本文件。

