在 Nemia 中创建一个智能体
智能体就是一名“雇员”:一个有工作、有标准(它的技能)和装备(它的工具)的人。工作流中的一个步骤就是它担任的一个职位;一个智能体可以在多个工作流中担任职位。个人的工厂不会从 Nemia 获得智能体:仓库的团队在 workflows/ 中,个人的在 ~/.agent-workflows/workflows/ 中,看板的“智能体”页面则写入后者。请阅读 Nemia 的 README《智能体是节点的附件》以了解完整格式;以下是操作步骤及其背后的学习成本。
身份
- 其名称即是其文件名,
agents/<name>.md,小写的个人名字(nora),步骤通过该名称引用它(agent: nora)。看板将名称显示为个人名字(Nora),旁边是根据它生成的头像(Blobatar),在显示的任何位置都保持一致。 role:是其担任的职位,用几个词描述(Product engineer);description:说明何时使用它,一行即可。两者都是智能体自身的行,与harnessPrompt:相同:试图设置这些字段的步骤会被拒绝。步骤的skills:会追加到其智能体的技能中(参见《技能》部分)。mcp:指定其会话加载的 MCP 服务器,使用检出目录中.mcp.json给出的名称(mcp: playwright)。步骤的mcp:会像skills:一样追加到其智能体中:仅由一个仓库拥有的服务器由需要它的步骤来命名,这样智能体保持可移植。会话加载其智能体和步骤(以及两者中都没有指定的服务器,则加载无服务器),如果检出目录未声明某个名称,则在会话启动时拒接。加载服务器并不会允许其任何工具:围栏仍然负责决定。指定服务器的智能体无法被试用,因为试用没有检出目录。name:行必须等于文件名;card:已废弃(卡片现在从其技能生成:npx wf agents card <name>)。
文件
文件由前置元数据(frontmatter)及随后的指令组成。其他键控制其会话的运行方式——harness、model、effort、context、remote、output 以及围栏——除非步骤自行设置,否则引用它的步骤会使用这些设置。接线(wiring)属于步骤的职责,在此处被拒绝:after、input、workspace、check、gate、loop、budget、background。
- 围栏位于其 harness 的块内:
claude: { fence: { permissionMode, tools, allowedTools, disallowedTools } },或codex: { fence: { sandbox } }。该块仅包含fence,如果文件中的 harness 与块不匹配,则会被拒绝。顶层级别的围栏键是旧式拼写,仍然可读;nemia frontmatter rewrite <folder>会将其移入块内。 - 声明步骤可以覆盖哪些项:
overridable: model, effort, fence, skills,每个单词是OVERRIDABLE中的一项(model,effort,context,harness,remote,output,fence,skills,mcp)。尝试设置其他内容的步骤在加载时会被拒绝,并指出键和智能体名称。如果没有该行,步骤可以覆盖所有内容,nemia start会提示添加一个。
---
role: Code reviewer
harness: claude
model: opus
overridable: model, effort, fence
claude:
fence:
permissionMode: dontAsk
tools: Read, Grep, Glob, Bash
allowedTools: Bash(git log:*), Bash(git diff:*)
---
- 前置元数据是 YAML 格式,与步骤和技能一样,每个值都按原样读取。如果值包含
:或#,或以 YAML 符号([,{,*,&,!,|,>,-,?)开头,则需要用引号括起来,例如description: "Reviews a change: its correctness"。长篇值可以写成字面块(literal block),使用|-并在下面的缩进行中写入值。列表键可以采用Read, Grep或[Read, Grep]形式;看板使用前一种形式。 - 设置
effort:和context:(200k):任务不读取用户设置,未设置边界的会话每次调用可能读取多达一百万个 token。 auto在那些被评估为会降低性能的模型(如 haiku、claude-sonnet-4-5)上会被加载时拒绝;在有规则的地方使用dontAsk。
指令
正文部分是指令,会追加到 Claude Code 自身的提示词之后(harnessPrompt: keep;no-coding 会移除 harness 的编码部分,replace 则将指令完全替换到其位置)。保持通用和简短:说明它是谁、它负责什么、它从不做什么、如何结束一个回合、其结案包含什么。操作步骤应放在技能中,而机制本身(如围栏、门控)持有的规则不需要用句子描述。恢复的会话会保持其开始时使用的正文:对文件的编辑只会影响下次运行,而不会影响正在进行的运行。
五层影响因素
指令是塑造智能体(除其具体任务外)的五个层级之一,每个层级由对应负责人编写:
- 指令(Instructions)——智能体的主体:无论在哪里被雇佣,都说明它是什么身份。
- 自定义指令(Custom instructions)——个人在不重写智能体的情况下对其添加的内容,存储在个人的存储中,每个智能体名称一个文件(
wf agents custom <name>),永远不会放在智能体的文件夹中。仅限文字:它们不设置任何键,因此永远不会扩大围栏或提供工具。运行开始时将其冻结,因此对文件的编辑只会影响其后的运行。 - 文件夹中的文件(The folder's files)——harness 从智能体工作的文件夹中读取的文件(目前是
CLAUDE.md、AGENTS.md):其中包含供所有在其中工作的智能体使用的信息。Nemia 不会对其进行编排。它们的优先级高于智能体自身的指令,低于工厂规则和步骤策略,尽管 harness 可能将它们呈现为覆盖一切:这种框架是 harness 自身的。 - 工厂规则(The factory's rules)——一个工厂的规则和政策,告知所有被雇佣进入该工厂的智能体:每个工厂一个文件,存储在存储中(
nemia factory rules <name>),永远不会放在仓库中。仅限文字,并在运行开始时冻结,与自定义指令相同。远程智能体上的步骤不会被告知这些规则。 - 步骤策略(The step's policy)——步骤自身的文字和键:这个流程的这个职位对其所扮演的角色提出什么要求。这是一个正常层级,而不是变通方案:在那里说明这个工作流期望什么,并保持它不进入指令。步骤可以添加技能,但绝不能移除技能。
数字表示优先级:当两个层级说的内容不同时,编号较高的层级获胜,而任务本身高于所有层级。文字到达的顺序是另一回事——按指令、自定义指令、工厂规则、步骤策略、然后任务的顺序,而文件夹中的文件由 harness 在智能体工作的任何位置读取。哪个层级拥有新指令取决于 Nemia 自身的路由规则《新指令去哪里》,在随附的《五层影响因素》章节中说明过一次:询问而不是猜测。围栏只会收紧:步骤可以缩小其智能体的围栏,但绝不能扩大它——步骤的 disallowedTools: 会追加到其智能体的围栏中,加载器会拒绝步骤中的 tools:、allowedTools:、permissionMode: 或 sandbox:,如果它们会给予智能体其文件中没有的权限。因此,指令应说明该角色在任何地方都适用的内容,而不涉及某个具体工作流或工作空间。
结案模式
output: <name>.schema.json,一个与智能体同目录的 JSON Schema:步骤移交出去的内容,严格解码。团队风格:每个字段都有 described、required、additionalProperties: false。
- 保留字段:
outcome、summary、artifacts、needs是每次结案时运行自身的字段;如果 schema 声明了其中一个,加载器会拒绝。(因此,Iris 的意图使用了proposedOutcome。) - 在同一会话的多次尝试中保持 schema 不变:如果继续运行的会话遇到更改的 schema,会重建其整个提示缓存。
- 步骤通过
input: <step>从它所依赖的任何步骤(包括中间步骤)读取结案;进行循环的步骤(loop:)只能依赖一个步骤,因此通过这种方式读取循环之前的内容(例如,审查步骤读取规范)。
技能
skills: <a>, <b> 指定包含 SKILL.md 的文件夹名称,搜索顺序为:skills/ 目录(与智能体文件夹同级)、仓库的 .claude/skills/ 目录、存储区,最后是 Nemia 自身的技能。tools: 必须允许 Skill。仓库的 .claude/skills/ 仅在仓库是步骤所在位置时才被找到,因为 start 会传入该位置;加载文件夹的测试也会传入位置。带有智能体的步骤可以通过自己的 skills: 添加技能:会话会先获得智能体的技能,然后是步骤的技能,每个技能只出现一次。智能体的围栏必须已经允许加载这些技能;步骤绝不能扩大围栏。
- 编写技能应遵循技能创建者的方法:一个说明何时使用的
description:,简短的主体,以及详细信息放在旁边的文件中。 - 使用他人技能而不作修改:在临时项目中,执行
DO_NOT_TRACK=1 npx skills add <owner>/<repo> --skill <name> --agent claude-code --copy -y;将文件夹复制到.claude/skills/,将其条目合并到skills-lock.json中,并将其作者、来源和许可证添加到THIRD_PARTY_NOTICES.md(MIT 要求在每个副本中都包含声明)。切勿编辑它——锁定文件会固定它——而是通过智能体主体进行调整。引入模型可能调用的技能:如果技能设置了disable-model-invocation: true,则它变为用户的斜杠命令(grill-me只能调用grilling)。
围栏
- 只读角色使用
dontAsk。 只能在其工作空间内读取,只能运行只读命令,以及允许规则指定的命令;其余操作无需询问直接拒绝。仓库的设置可能允许其他角色需要的写入工作空间的命令(例如构建),因此被授予Bash的智能体需要通过disallowedTools:逐个拒绝这些命令。子智能体会继承模式和规则;在allowedTools:中列出Agent,以确保调度本身不会被拒绝。根据角色运行的每个检查的精确名称进行允许,前提是设置不允许它;其技能以裸命令形式(每次调用一个命令;任何包装、管道、重定向、或在cd、git -C、VAR=或for之后的命令都会被拒绝)写出每个检查,并将读取或搜索操作发送到 Read、Grep 或 Glob,而不是 Bash。 - 编辑角色使用
auto,并通过名称拒绝其绝不能做的事情:Bash(git push)、Bash(git push:*)、Bash(git branch -D:*)、Bash(git branch --delete --force:*)、Bash(pkill:*)、Bash(killall:*)、mcp__playwright__browser_run_code_unsafe。 - 步骤只能收紧围栏,并且只有在
overridable:指定了fence时才允许。如果步骤需要的工具、允许项或模式在智能体的文件中未提供,则需要另一个智能体;步骤的disallowedTools:会追加到其智能体的围栏中:只写下步骤新增的拒绝项;它绝不能移除智能体已有的任何拒绝项。
与人类对话
步骤是 Agent SDK 上的一个任务:它不能在对话中等待。要提问,它需要以 blocked 状态签出,并附上问题;用户在看板上回答,或使用 wf retry <run> <step> --message "…",同一个会话继续,带着答案进入下一轮。在需要访谈的智能体的主体中说明这一点,并为需要用户接受结案的步骤设置门控(gate: true)。任务的最后一轮是其签出:运行长命令的智能体(例如 e2e)应该被告知在前台运行它们或等待它们完成,绝不能在命令还在运行时签出(曾有一位工程师的首次 web 构建在其 e2e 结束前就签出了)。以 blocked 状态签出的结案会被单独读取,因此进行多轮提问的智能体需要在每一轮中都携带迄今为止已确定的所有内容:曾有一位面试官在第三轮中丢失了之前轮次中的决定。将问题声明为输出 schema 的一个字段,使用 { "x-shape": "questions", "description": "…" },加载器会将其扩展为一个严格的形状:看板将其绘制为用户通过点击即可回答的选项。一个已门控的步骤如果知道其后继步骤的成本,可以在旁边声明 { "x-shape": "budgets", "description": "…" }:这是一个 { step, usd, why } 对象的列表,每个对象代表门控之后的一个步骤,一次一个,金额以美元为单位且大于零,why 说明金额的依据。门控会将其显示在结案旁边,批准后它们将成为这些步骤的费用上限,用户可以更改任何金额(nemia approve <run> <step> --budget <step>=<amount>);如果某个步骤自身设置了 budget:,而此处给出的上限更高,会在此处说明,并且未经询问不会被批准。如果结案中的预算引用了另一个步骤,或者金额为零,则会被拒绝返回给其会话。
验证
- 在仓库中运行
npx wf agents card <name>:真实的加载器会读取文件——其键、其 schema 的保留名称、每个已找到的技能——并打印卡片,如果出错则会用文字说明如何修复。 - 运行仓库自身的检查,其中其守卫会读取它发布的每个文件夹(围栏、冻结的步骤、渲染往返测试):绕过任何未看到 workflows 文件夹的缓存运行它们。
- 运行它:一个已门控的工作流,使用一个新的小卡片,并在批准前读取其结案。
- 在仓库列出其智能体的地方添加新智能体的名称。
当您学到新东西时
创建智能体就是测试这个技能的方式。当此处的步骤有错误或遗漏——您遇到的拒绝、让您惊讶的键——在与智能体相同的更改中修复此文件,最多三行,并与包含该规则的文件一起提交。