adam-agent-folder
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseWrite an adam agent as a folder
将 adam Agent 编写为文件夹
An adam agent with no Rust is a folder of files that the binary reads once at
startup and serves over A2A. The binary ships inside the coder image
(), so a deployment needs the image and the folder, no build.
adam-agentghcr.io/vymalo/another-adam-rs/coderEvery adam-rs path below is in at the revision you pin (replace by
that revision). The reference is
https://github.com/vymalo/another-adam-rs/blob/main/bin/adam-agent/README.md; read it at your rev
before you rely on a detail here.
vymalo/another-adam-rsmain不含 Rust 的 adam Agent 是一个文件文件夹, binary 会在启动时读取一次,并通过 A2A 提供服务。该 binary 随 coder 镜像一起分发(),因此部署只需要镜像和文件夹,无需构建。
adam-agentghcr.io/vymalo/another-adam-rs/coder下述所有 adam-rs 路径都位于 仓库中你固定的 revision 对应的版本里(将 替换为该 revision)。参考文档位于
https://github.com/vymalo/another-adam-rs/blob/main/bin/adam-agent/README.md;在依赖本文任何细节之前,请先阅读你所用 revision 对应的文档。
vymalo/another-adam-rsmainWhen to use
何时使用
- Adding an agent to a stack that already runs adam agents (a chat assistant, a researcher on a web-search MCP server, a reviewer).
- Changing an agent's persona, card, tools list, skills, subagents or MCP servers.
- Diagnosing a start that exits 78 or 69.
- Not for an agent that needs its own Rust tools: that is . Not for Docker Agent (cagent)
adam-embed: a different product with a different format.agent.yaml
- 向已经运行 adam agents 的技术栈中添加 Agent,例如聊天助手、使用 web-search MCP server 的 researcher 或 reviewer。
- 修改 Agent 的 persona、card、tools 列表、skills、subagents 或 MCP servers。
- 排查启动时以 78 或 69 退出的问题。
- 不适用于需要自有 Rust tools 的 Agent,此类 Agent 应使用 。也不适用于 Docker Agent(cagent)的
adam-embed,后者是采用不同格式的另一种产品。agent.yaml
Procedure
操作步骤
-
Create. The folder you point
agent/instructions.mdat holdsADAM_AGENT_DIR(or isagent/itself) and exactly one agent: a folder withagent/of several is refused. Start fromagents/(a chat agent) ordev/agents/assistant/agent/instructions.md(dev/agents/researcher/agent/plusinstructions.md) in the repository.mcp.json -
Frontmatter, from the table in("The agent folder"):
bin/adam-agent/README.md- : the registered name, which is the key of the agent's stored runs. Renaming it strands the runs of the old name. Two folders with the same
nameshare their runs.name - (or
description): the A2A card needs one.card.description - (
card:,namewithskills,id,name,description,tags),examples(limits:,max_turns,max_tool_calls,max_output_tokens),max_history_tokens(an alias, only when it should not bemodel:),MODEL(optional selection;tools:takes a server's tools; an unknown name is refused with a suggestion).linear__* - are the
vars:of the body. Every var needs a value in the file. A var declared without a value, a var the body does not use, or a placeholder not declared, stops the process at startup.{{placeholders}} - Secrets and endpoints never go in the file: the validator rejects ,
api_key,apiKey,token,secretandpassword(base_url, "File formats").docs/authoring.md
-
Body: the system prompt. Optional(Agent Skills format, loaded on demand by
skills/<name>/SKILL.mdandload_skill) andread_skill_file(each one tool of the parent, a child run with only the tools it lists and neversubagents/; registered asask_user). Formats:<name>/<subagent>.docs/authoring.md -
Built-in tools the agent has without writing any:,
ask_user,show(ui_catalog). Everything else comes from the folder, mainly MCP.crates/adam-ui/README.md -
MCP servers:with
agent/mcp.json; tools are named{"mcpServers": {...}},<server>__<tool>in a server entry is the allow-list. Credentials go intoolsasheaders(unset without default: exit 78 naming the variable). What kinds of server are allowed is the deployment's, not the file's:${VAR}- for a local process (
MCP_ALLOW_STDIO=true); the coder image sets none.command - for plain
MCP_ALLOW_INSECURE=trueto another machine (development only).http - to allow
MCP_ALLOW_URL_VARS=trueinside a${VAR}.url - is not supported.
type: sse
-
Make it readable by uid 10001 (the image's user) and mount it read-only. Run the image with the entrypoint overridden (the coder's entrypoint is):
adam-codershdocker run --rm --entrypoint tini \ -v "$PWD/my-agent/agent:/etc/adam/agent:ro" -e ADAM_AGENT_DIR=/etc/adam/agent \ -e DATABASE_URL=... -e MODEL_BASE_URL=... -e MODEL_API_KEY=... -e MODEL=... \ -e A2A_BEARER_TOKENS=... -e PUBLIC_URL=... -p 8080:8080 \ ghcr.io/vymalo/another-adam-rs/coder:sha-<7> -- adam-agentPin the image bytag and digest (sha-<7>).adam-upgradeandA2A_BEARER_TOKENSare required by roles that serve A2A (fail closed: no token, no server);PUBLIC_URLby roles that run workers. All variables: "Configuration" inMODEL_*.bin/adam-agent/README.md -
In a compose stack, copy the serviceof
agentin the repository (profilecompose.yaml: the folder mounted atapp,/etc/adam/agentto choose it, port fromAGENT_FOLDER, the coder's database). A new agent is a folder and about a dozen lines of that service.AGENT_PORT -
Edits apply at the next start (ADR 0004,): restart the service, no rebuild. There is no hot reload in release images.
docs/decisions/0004-agent-folders-at-run-time.md
-
创建。
agent/instructions.md指向的文件夹应包含ADAM_AGENT_DIR(也可以本身就是agent/),且其中只能有一个 Agent;如果agent/下有多个 Agent,则会被拒绝。可以从仓库中的agents/(聊天 Agent)或dev/agents/assistant/agent/instructions.md(包含dev/agents/researcher/agent/和instructions.md)开始。mcp.json -
Frontmatter:参考中“The agent folder”的表格:
bin/adam-agent/README.md- :注册名称,也是该 Agent 存储运行记录的键。重命名后,旧名称对应的运行记录将无法访问。两个具有相同
name的文件夹会共享运行记录。name - (或
description):A2A card 必须包含此项。card.description - (
card:,以及包含name、id、name、description、tags的examples)、skills(limits:、max_turns、max_tool_calls、max_output_tokens)、max_history_tokens(alias,仅当不应使用model:时设置)、MODEL(可选的选择列表;tools:表示采用某个 server 的 tools;未知名称会被拒绝并给出建议)。linear__* - 是正文中的
vars:。每个 var 都必须在文件中提供值。声明了 var 却未提供值、正文未使用该 var,或使用了未声明的 placeholder,都会导致进程在启动时停止。{{placeholders}} - Secrets 和 endpoints 绝不能写入文件:validator 会拒绝 、
api_key、apiKey、token、secret和password。参见base_url的“File formats”章节。docs/authoring.md
-
正文:即 system prompt。可选内容包括(采用 Agent Skills 格式,由
skills/<name>/SKILL.md和load_skill按需加载)以及read_skill_file(每个 subagent 都是其 parent 的一项 tool;child run 只能使用列出的 tools,且绝不能使用subagents/;注册名称为ask_user)。格式参见<name>/<subagent>。docs/authoring.md -
内置 tools:无需编写任何内容,Agent 就具备、
ask_user和show(参见ui_catalog)。其他所有 tools 均来自该文件夹,主要是 MCP。crates/adam-ui/README.md -
MCP servers:使用,格式为
agent/mcp.json;tools 命名为{"mcpServers": {...}},server 条目中的<server>__<tool>是 allow-list。Credentials 应以tools形式放入${VAR}(如果变量未设置且没有默认值,则以 78 退出并指出对应变量)。允许哪些类型的 server 由部署环境控制,而不是由文件控制:headers- 对本地进程()使用
command;coder 镜像未设置此项。MCP_ALLOW_STDIO=true - 对其他机器使用普通 时使用
http(仅限开发环境)。MCP_ALLOW_INSECURE=true - 使用 可允许在
MCP_ALLOW_URL_VARS=true中使用url。${VAR} - 不支持 。
type: sse
- 对本地进程(
-
确保 uid 10001(镜像用户)具有读取权限,并以只读方式挂载。运行镜像时需要覆盖 entrypoint(coder 的 entrypoint 是):
adam-codershdocker run --rm --entrypoint tini \ -v "$PWD/my-agent/agent:/etc/adam/agent:ro" -e ADAM_AGENT_DIR=/etc/adam/agent \ -e DATABASE_URL=... -e MODEL_BASE_URL=... -e MODEL_API_KEY=... -e MODEL=... \ -e A2A_BEARER_TOKENS=... -e PUBLIC_URL=... -p 8080:8080 \ ghcr.io/vymalo/another-adam-rs/coder:sha-<7> -- adam-agent使用tag 和 digest 固定镜像版本(sha-<7>)。承担 A2A 服务角色的部署必须设置adam-upgrade和A2A_BEARER_TOKENS(采用 fail-closed 策略:没有 token 就不会启动 server);运行 workers 的角色必须设置PUBLIC_URL。全部变量参见MODEL_*的“Configuration”章节。bin/adam-agent/README.md -
在 compose 技术栈中,复制仓库中的
compose.yamlservice(使用agentprofile:文件夹挂载到app,通过/etc/adam/agent选择,通过AGENT_FOLDER设置端口,并使用 coder 的 database)。创建一个新 Agent 只需要一个文件夹和该 service 中约十几行配置。AGENT_PORT -
修改会在下次启动时生效(ADR 0004,):重启 service 即可,无需重新构建。release 镜像不支持热重载。
docs/decisions/0004-agent-folders-at-run-time.md
Verify
验证
- Exit codes: 78 is configuration (a missing , a bad file, a
ADAM_AGENT_DIRmistake, an unsetvars, a refused MCP policy); every finding is listed as${VAR}in the onepath:line: error: ...log line. 69 is a dependency that is down (Postgres, an MCP server): a supervisor can restart until it is up.adam-agent failed - Startup logs one line (
agent files,path,digest,agent) and each warning aswarnings: read it to see which files run.path:line: warning: ... - The card is public at the agent's URL and is the folder's; a call without a bearer token gets 401.
- End to end in the repository's stack: (the card, "hi" answered in role, then a restart on an edited copy of the folder). The container smoke test is
sh dev/agent-e2e.sh(sh docker/coder/test/agent-smoke.sh <image>names anAGENT_FOLDERfolder).agent/
- 退出码:78 表示配置错误(缺少 、文件错误、
ADAM_AGENT_DIR错误、未设置的vars、MCP 策略拒绝);所有问题都会以${VAR}的形式列在一条path:line: error: ...日志中。69 表示依赖服务不可用(Postgres 或 MCP server);supervisor 可以反复重启,直到依赖恢复。adam-agent failed - 启动日志会输出一条 日志(包含
agent files、path、digest、agent),并以warnings的形式记录每条 warning;可据此确认实际运行了哪些文件。path:line: warning: ... - Card 可通过 Agent 的 URL 公开访问,并对应文件夹中的 card;没有 bearer token 的调用会返回 401。
- 在仓库技术栈中进行端到端验证:运行 (检查 card,确认“hi”会按照对应 role 得到回答,然后使用修改后的文件夹副本重启)。容器 smoke test 为
sh dev/agent-e2e.sh(sh docker/coder/test/agent-smoke.sh <image>指定一个AGENT_FOLDER文件夹)。agent/
Pitfalls
常见问题
- has no default and the binary has no embedded agent: unset is exit 78.
ADAM_AGENT_DIR - The folder's is the key of the runs: a rename is a new agent with no history.
name - A subagent inherits nothing and, without , has no tools (
tools:).docs/authoring.md - in agent frontmatter does not exist; it is only for
${VAR}.mcp.json - One agent per process. Several agents share one database by running several processes with different folders (runs are scoped by the agent's name).
- The coder image sets no , and has no extra interpreters for stdio MCP servers that need
MCP_ALLOW_STDIOornode.python - A folder that follows the persona convention (the body opens with and a line
Your name is {{display_name}}.) is greeted by the repository's mock models in role. A live model follows the whole prompt.In one sentence: <summary>.
- 没有默认值,且 binary 中未嵌入 Agent;未设置它会触发退出码 78。
ADAM_AGENT_DIR - 文件夹中的 是运行记录的键:重命名会创建一个没有历史记录的新 Agent。
name - Subagent 不会继承任何内容;如果没有 ,它将没有任何 tools(参见
tools:)。docs/authoring.md - Agent Frontmatter 中不存在 ;该语法仅适用于
${VAR}。mcp.json - 每个进程只能运行一个 Agent。多个 Agent 可以通过使用不同文件夹运行多个进程来共享同一个 database(运行记录按 Agent 的 划分范围)。
name - coder 镜像未设置 ,也没有为需要
MCP_ALLOW_STDIO或node的 stdio MCP servers 提供额外解释器。python - 遵循 persona 约定的文件夹(正文以 开头,并包含一行
Your name is {{display_name}}.)会被仓库中的 mock models 按照对应 role 问候。live model 则会遵循完整 prompt。In one sentence: <summary>.
See also
参见
- ,
bin/adam-agent/README.md,docs/authoring.md(MCP rules),crates/adam-mcp/README.md(the built-in tools).crates/adam-ui/README.md - (agents with Rust tools),
adam-embed(what the card announces),adam-a2a-extensions(changing the image pin).adam-upgrade - https://github.com/vymalo/another-adam-rs/blob/main/bin/adam-agent/README.md
- 、
bin/adam-agent/README.md、docs/authoring.md(MCP 规则)、crates/adam-mcp/README.md(内置 tools)。crates/adam-ui/README.md - (带 Rust tools 的 agents)、
adam-embed(card 声明的内容)、adam-a2a-extensions(修改镜像版本固定方式)。adam-upgrade - https://github.com/vymalo/another-adam-rs/blob/main/bin/adam-agent/README.md