自定义智能体
Codeg 内置了十二个智能体,它们都是逐个手工适配的——每一个都获得了针对其会话文件的解析器,以及智能体列表中的一个位置。但 Agent Client Protocol 是一项开放标准,而许多智能体虽然会说这门语言,却从未与 Codeg 打过照面。从 0.22 起,你可以自己把它们加进来。
自定义智能体并非二等公民。一旦注册,它就会出现在智能体列表、composer 选择器、状态栏、对话搜索以及委派目标中——凡是内置智能体会出现的地方,它都会出现。Codeg 会安装它、对它运行预检,并且——因为这类智能体通常不会留下 Codeg 能读取的历史——自己记录对话记录,让它的会话像其他智能体的一样出现在工作区里。
一切都在同一个地方进行:设置 → 智能体,页面标题栏右上角有一个 + 添加自定义智能体按钮。点击后打开一个带两个标签页的对话框——"注册任何兼容 ACP 的智能体。从公开的 ACP 注册表中挑选一个,或粘贴它的注册表信息。"
从 ACP 注册表添加
ACP 注册表标签页是最省事的路径。Codeg 会下载该协议的公开目录——cdn.agentclientprotocol.com/registry/v1/latest/registry.json——并列出其中发布的每一个智能体,包含它的标识、名称、描述和版本。在搜索框中输入即可筛选;下载失败时可用重试重新获取。
每一行都带有一个添加按钮,除非出现以下两种情况之一:
- 已添加——你已经有这一个了。
- 该平台没有可用的构建——这个条目发布的内容都无法在你的机器上运行。Codeg 会预先说明,而不是让你安装一个永远启动不了的东西。
按下添加后,该行会短暂转圈,随后变为已添加,智能体也随之加入左侧列表。添加操作会原样引入该条目的整个 distribution 对象,挑选能在你机器上运行的渠道,并把智能体的图标内联进保存的定义中——这样即便日后离线,标识依然能正常渲染。
手动添加
手动标签页用于注册表未收录的任何东西:你正在开发的智能体、一个内部工具、一个包名不同的分支。它就是一张简短的表单。
| 字段 | 用途 |
|---|---|
| Registry ID | 智能体的身份标识——用作它的传输名称(custom:<id>)、对话记录目录名和二进制缓存键。最多 64 个字符,可用字母、数字、-、_ 和 .;不能以 . 开头,也不能占用内置智能体的名称(codex、gemini、claude_code 等) |
| 显示名称 | 你在选择器和状态栏中看到的名称 |
| 版本 | 一个标签,显示在版本状态行中 |
| Distribution(JSON) | 如何启动它——见下文 |
| 启动方式 | 当 JSON 发布了不止一个渠道时,使用哪一个 |
| 图标 (可选) | 小于 256 KB 的图片,"与智能体一起保存,因此离线也能用。不提供时会使用一个带颜色的首字母。" |
| 版本探测命令 (可选) | 一条打印已安装版本的命令。留空时,Codeg 会用 --version 运行智能体命令 |
| 技能 | 两项声明——见下文 |
distribution JSON
这是唯一有些深度的字段,而且它刻意与 ACP 注册表保持粘贴兼容:输入框既接受一个裸的 distribution 对象,也接受一整条注册表条目(Codeg 会把它拆开,并保留其中携带的名称、版本和图标)。从注册表里复制一条粘贴进来,就能直接用。
它能理解三种渠道,模板一行可为每种渠道插入一份填好的起始范例:
npx——一个 npm 包,用npx运行。需要 Node.js。json{ "npx": { "package": "@scope/agent-cli@1.0.0", "args": ["--acp"], "cmd": "agent-cli" } }uvx——一个 Python 包,用uv运行。json{ "uvx": { "package": "agent-cli==1.0.0", "args": ["--acp"], "cmd": "agent-cli" } }binary——一个可下载的归档包,按平台建键。模板会预填你这台机器的平台键(darwin-aarch64、linux-x86_64等),所以你写下的就是这台机器真正能安装的东西。json{ "binary": { "darwin-aarch64": { "archive": "https://example.com/agent-darwin-aarch64.tar.gz", "cmd": "./agent", "args": ["acp"] } } }
有两个键值得说明,因为它们在不同渠道下含义不同:
cmd——对 npx/uvx 而言,它是该包安装的可执行文件(@qwen-code/qwen-code对应qwen)。你不填时 Codeg 会从包名推导,所以当两者不一致时要显式填写。对 binary 而言,它是归档包内部的启动路径。sha256——binary 条目上的可选项;填写后,Codeg 会用它校验下载内容。
三种渠道一个都没发布的 spec 会被直接拒绝——"未找到 npx、uvx 或 binary 分发"——而不是让表单悄无声息地一直处于未就绪状态。JSON 格式有误则提示"不是有效的 JSON"。
同时发布二进制文件和包
少数注册表条目会提供不止一个渠道。启动方式就是你给出的明确答案,它随定义一起保存,因此不会在版本之间悄悄改变。当你从注册表添加时,Codeg 会挑选能在这台机器上运行的渠道——只为其他平台发布的二进制文件会回退到 npx,而不是直接失败。
安装并确认它已就绪
自定义智能体会经过与内置智能体相同的预检,版本行上也有同样的安装 / 升级 / 卸载按钮。npx 和 uvx 智能体需要它们的运行时;binary 智能体则下载到 Codeg 已经在为 OpenCode 和 Cursor 使用的、带校验和验证的缓存中。
已经自己装过这个 CLI 了? 现在 Codeg 会认这一点。当它没有自己托管的安装记录时,会去探测系统:先用你声明的版本探测命令,然后对 npx 包用 npm list -g,最后是 --version 这个惯例——并报告真实版本,而不是未安装。(从 0.22 起,这对内置智能体同样适用。)
版本行会因定义的来源不同而显示不同内容:
- 从注册表添加——完整对比,远程:1.4.0 · 本地:1.3.2,并附升级提示。
- 手动添加——只显示本地版本,本地:1.3.2。已安装。 你手输的版本并非已发布的版本号,拿它去比对只会产生噪音。
如果该智能体在这里根本无法运行,详情面板会就地说明原因:"该智能体无法在此启动:…"。
它的历史保存在哪里
每个内置智能体都保存着自己的会话文件,Codeg 会原生读取它们。而任意一个 ACP 智能体通常什么可用的东西都不会留下——于是 Codeg 自己来写这份历史。
每个会话都会在 acp-transcripts/<registry-id>/ 下得到一份只追加的 JSONL 对话记录,直接依据协议记录发出的提示词与收到的更新。这个目录默认位于 ~/.codeg/,并且会跟随 CODEG_HOME(若只设置了 CODEG_DATA_DIR,则跟随后者),与 Codeg 自身的其余数据一致——在服务器上你多半正需要这一点。→ 配置随后 Codeg 会把它投影回对话,方式与投影内置智能体的原生存储完全一致:这些会话会出现在对话列表中、能带着完整记录打开,也会出现在导入里。打开过但从未发过提示词的会话不会被列出;而智能体已经不再记得的会话,会被串接到它的后继会话上,因此不会重复显示。
这正是自定义智能体无需适配工作的原因:对话记录就是 ACP 流量,而 ACP 对所有人都是一样的。
为它配置技能
Codeg 无法探知任意一个智能体从何处加载技能——所以由你来告诉它。自定义智能体的详情面板上有一张技能卡片,包含两项相互独立的声明:
- 共享的
.agents/skills存储——这是 OpenCode、Gemini、Cline、Codex、Pi 和 Cursor 都已在读取的跨智能体约定(~/.agents/skills加上项目本地的.agents/skills)。勾选它即声明"这个智能体会读取共享存储",并把它加入每一张技能矩阵。 - 专属技能目录——该智能体加载技能的绝对路径,属于它自己的存储。
~会展开为你的主目录;这个字段有独立的保存更改按钮,因此半途输入的路径绝不会被送去后端。
两者任选其一,都足以让该智能体出现在专家、科研、Office 和自定义技能矩阵中。两者都设置时,专属目录会排在前面,因此链接技能会落在它那里,不会波及共享存储——这与 Pi 和 Cursor 采用的次序相同。
从注册表添加的智能体两项都默认关闭
从目录添加时,两项声明都是关闭的,因为注册表并不会说明该智能体从何处读取技能。在你做出声明之前,它根本不会作为一列出现在技能矩阵中——这才是诚实的答案,因为那里的链接只会失败。
委派与 MCP
委派可以正常工作。 自定义智能体可以在 composer 中用 @ 提及,也是多智能体协作的有效目标——它以 custom:<id> 的形式传输,Codeg 会把它追加到委派工具的目标列表中。它在设置 → 通用 → 多智能体协作 → 智能体默认设置下也有自己的标签页,像内置智能体一样实时探测,因此被委派的会话会按你希望的方式启动。
至于它能否担任主智能体,则取决于它自己:委派工具是以 MCP 工具的形式通过 ACP 送达的,因此能通过协议接受 MCP 服务器的智能体可以发起委派,不能的则只能被委派。
MCP 服务器无法在设置 → MCP 中分配给它。 那个页面是往每个智能体自己的配置文件里写内容,而 Codeg 刻意对自定义智能体的配置文件一无所知——所以它们不会出现在那里的目标中。它们能得到的是随协议本身传输的东西:Codeg 自己的 codeg-mcp 伴随服务,条件与内置智能体完全相同。只要设置 → 通用中它的四项功能——委派、实时反馈、提问和会话查询——至少有一项开启,它就会被挂上;而每项功能的工具只在该功能开启时才出现。因此,delegate_to_agent 要在你启用委派之后才能到达自定义智能体,在那之前不会。→ MCP 服务器
编辑或移除智能体
自定义智能体详情面板的底部有两张卡片(面板标题里的 Custom 徽章会告诉你哪些智能体有它们)。
编辑智能体会重新打开手动表单,并用已保存的定义预填——"更新名称、图标、分发方式和技能声明。智能体 ID 无法更改。" ID 被锁定,是因为它就是身份:对话引用的是 custom:<id>,改动它等于新建一个智能体并让旧智能体的历史成为孤儿。
移除智能体会删除该定义——"已有的对话会保留其历史;只是该智能体无法再被启动。" 确认弹窗还提供一个额外选项:同时删除它记录的对话历史,勾选后会一并清除 JSONL 对话记录。不勾选,过往的工作依然可读。
值得了解
- ID 是永久的。 要慎重挑选:它决定了传输类型名、对话记录目录和二进制缓存条目。其余的一切——名称、图标、版本、分发方式、技能——都可以编辑。
- 禁用即隐身。 启用开关的行为与内置智能体一致,而从 0.22 起它的影响更远了一步:被禁用的智能体会从委派工具的目标列表中剔除,而不只是从 composer 选择器中消失。
- 图标是保存下来的,不是外链。 添加时注册表的标识会被内联进定义中,因此智能体列表离线也能渲染。单色 SVG 会以遮罩方式跟随你的主题,而不是原样渲染。
- 在服务器上同样可用。 该对话框也存在于浏览器构建中,而它用来填充 binary 模板的平台键是服务器的——即真正执行安装的那台机器。
- 没有针对具体智能体的特殊处理。 Codeg 的内置智能体各自带有针对其非标准行为的小适配。自定义智能体拿到的是纯粹的 ACP 语义,实时和历史都一样——这也正是二者永不出现分歧的原因。