用途
architect-manage-procedures 用于可靠地管理智能体的 procedure,涵盖列表、读取、创建、编辑和发布。Procedure 是独立的数据,不属于智能体配置的一部分,无法通过修改 conversation_config 访问。本技能关注的是如何正确调用接口,而非撰写优质触发器和清晰步骤的方法(后者见 architect-structured-procedures 技能)。
所有操作均以分支为范围,通过 ConvAI REST API 进行,主机为 https://api.elevenlabs.io,请求头为 xi-api-key: $API_KEY。需要 $AGENT_ID 和所操作分支的 $BRANCH_ID。
主要能力
1. 先读取当前状态
在创建或编辑任何内容之前,先读取现有数据:
- 列出分支上的所有 procedure:GET /v1/convai/agents/$AGENT_ID/branches/$BRANCH_ID/procedures。每个条目包含 procedure_id、version_id、name、type(free_form 或 deterministic)、trigger 和 has_draft。它不包含 content——该列表只是索引,不能用于读取正文。不要据此响应衡量 procedure 的内容长度;缺失的 content 字段会让每个 procedure 都显示为空,看似数据丢失,实则正常。没有这里的 procedure_id,就无法编辑 procedure。
- 读取单个 procedure 正文:GET /v1/convai/agents/$AGENT_ID/branches/$BRANCH_ID/procedures/$PROCEDURE_ID。这是获取 content 的唯一方式,编辑前必须调用,以免覆盖其余内容。如果该 procedure 存在草稿,此 GET 返回的是草稿内容,而非已发布内容。
- 对于内容从未发布过的 procedure,即使 id 正确且出现在列表中,此 GET 也会返回 404。这是创建后立即出现的预期状态,而非 id 错误。用列表确认 procedure 存在并检查 has_draft。
- 用 GET /v1/convai/agents/$AGENT_ID?branch_id=$BRANCH_ID 确认所在分支,因为 procedure 是按分支划分的。
- 如果用户要求编辑“某个 procedure”,请从列表的 name 值中匹配,并在写入前确认确切的 procedure_id。不要假设 id。
2. 创建与编辑:草稿后发布模型
写入会在分支上暂存草稿。草稿在单独发布步骤将其提交为新版本之前不会生效。
创建新 procedure:POST /v1/convai/agents/$AGENT_ID/branches/$BRANCH_ID/procedures,包含 name 和 content。type 默认为 free_form;仅当编写 JSON 流程形式时才传入 type: "deterministic"。
创建需要两次调用,而非一次。POST 注册 procedure 并存储 name,但你发送的 content 不会持久化——它返回 200,正文只含 procedure_id(name 和 type 返回 null),procedure 以空正文落地。必须紧接着执行下方的草稿 PATCH,重新发送相同 content,否则会在分支上留下一个有名无实的空 procedure。发布后请用单 procedure GET 验证,而不是用 POST 响应。
编辑或重命名现有 procedure,并完成创建:PATCH /v1/convai/agents/$AGENT_ID/branches/$BRANCH_ID/procedures/$PROCEDURE_ID/draft。这会写入分支草稿。没有直接的 PATCH .../procedures/$PROCEDURE_ID(没有 /draft 后缀);那会返回 405。
此端点要求 name、content 和 type 三者齐全。即使只是纯正文编辑,省略 type 也会报 422 {"type":"missing","loc":["body","type"]}。这与创建端点的行为相反,因此不要原样照搬创建载荷。
发布待处理草稿:PATCH /v1/convai/agents/$AGENT_ID?branch_id=$BRANCH_ID,任何部分合并正文都会将分支上所有待处理的 procedure 草稿发布为新版本。最简单的空操作正文是重新发送分支当前的 prompt。先按此分支获取它,以免覆盖分支本地差异,然后原样 PATCH 回去。
告知用户,已编辑或创建的 procedure 在发布步骤运行前停留在分支草稿上,且只有当分支合并后才会在生产智能体上生效。
完整创建序列
创建带正文的 procedure 需要三次调用。跳过第二次会留下空 procedure;跳过第三次则无法读取。
- POST .../procedures,含 name + content → 返回 procedure_id。content 尚未存储。
- PATCH .../procedures/$PROCEDURE_ID/draft,含 name + content + type → 将正文存入草稿。响应回显真实 name 和 content 长度;检查该长度是否与发送一致。
- PATCH /v1/convai/agents/$AGENT_ID?branch_id=$BRANCH_ID,重新发送分支当前 prompt → 将草稿发布为新版本。
然后用 GET .../procedures/$PROCEDURE_ID 验证(此时返回 200,含 content),并确认列表中的 has_draft: false。在第 3 步之前,该 GET 返回 404,正文只存在于草稿中。
用 JSON 序列化器构建请求体,而非手写字符串——procedure 内容是多行 markdown,手写载荷中的原始换行会报 json_invalid "Invalid control character" 422,看似 schema 问题,实为引号 bug。
3. 导致失败的内容形态陷阱
- content 是单个字符串,不是结构化字段。对于 free_form,它是一个 markdown 字符串,将触发器和步骤折叠其中。没有单独的 trigger / instructions / steps 参数。将其拆分为独立参数或发送嵌套对象,是最常见的验证失败。
- 编辑草稿会替换整个正文。你发送的任何 content 都会成为整个 procedure;省略的内容都会丢失。始终从第 1 步读取的当前 content 出发,修改后发送完整结果。这是意外数据丢失的首要原因。
- 在草稿编辑中,name、content 和 type 每次都必须提供——即使是重命名。要在不动正文的情况下重命名,请将现有 content 和 type 与新 name 一起重新发送;要在不重命名的情况下编辑正文,请重新发送现有 name 和 type。
- type 在草稿编辑中是必需的——不能省略以继承当前类型。先从列表读取 procedure 的现有 type 并重新发送该确切值;发送错误的值会转换 procedure 的形式。只有 free_form 和 deterministic 有效;空字符串或任何其他值都会失败。(type 在创建 POST 中确实是可选的,默认 free_form。)
- 确定性 procedure:content 必须是描述流程的有效 JSON 字符串。格式错误的 JSON,或在 type 为 deterministic 时使用自由形式 markdown,都会失败。如果不确定 schema,请阅读现有确定性 procedure 的 content 作为模板,或参见 architect-structured-procedures 技能。编辑确定性 procedure 会自动重新编译,因此请保持 JSON 格式正确。可通过 POST /v1/convai/agents/$AGENT_ID/branches/$BRANCH_ID/procedures/compile 显式编译。
- name 上限为 200 个字符。保持简短;将细节放在 content 中。
4. 按错误恢复失败调用
- schema_mismatch(通常无字段细节):content 形态与 type 不匹配。重新检查第 3 节。通常是你将触发器和步骤拆分为独立字段、发送了对象而非字符串,或为确定性 procedure 发送了 JSON 损坏的 markdown。将 content 重建为单个正确类型的字符串;不要盲目重试相同载荷。
- validation:缺少具体的必需参数,通常是草稿编辑中的 content、name 或 type,或 procedure_id。提供指定字段,对不打算更改的内容重新发送现有值。
- not_found / 404 单 procedure GET:判断属于哪种情况。(a) procedure 存在但尚无已发布内容——它刚被创建,或只做过草稿编辑。在发布提交正文之前 GET 返回 404,而列表仍显示该 procedure。用列表确认;如果在,这是预期情况,修复方法是发布,而不是重试读取。(b) id 确实错误或过期,或你所在分支与其所在不同。在目标分支重新列出 procedure 以获取当前 id,然后重试。不要跨分支切换携带 procedure_id。
- 草稿编辑报 422 {"type":"missing","loc":["body","type"]}:你省略了 type。这里即使创建端点默认它也是必需的。用列表中的现有 type 重新发送。
- PATCH .../procedures/$PROCEDURE_ID 报 405:你丢掉了 /draft 后缀。请对 .../procedures/$PROCEDURE_ID/draft 重新发起。
5. 防护栏提示词不在 procedure 正文中
procedure 的 guardrails 是 procedure 上独立的一等字段,而非 content 中的文本。如果用户要求编辑“防护栏提示词”,不要到 content 字符串中寻找。读取 procedure 查看其配置的 guardrails,明确告知用户草稿编辑路径仅涵盖 name、content、trigger 和 type,不要将 guardrail 文本偷偷塞进 content(它不会被作为防护栏强制执行,反而会静默更改正文)。
6. 确认与交叉引用
成功写入后,准确告知用户更改了什么(创建、编辑或重命名)、在哪个分支上,以及它在发布前停留在分支草稿上,且仅合并后才生效。关于在生效前为审查而暂存更改的分支与流量拆分工作流,参见分支和版本控制指南。如果用户实际想通过 prompt、LLM、语音或工具更改行为,而非 procedure,那属于配置更改,不是 procedure 编辑。