本教程演示如何使用方舟 Managed Agents 的 Agent 版本机制,安全地迭代一个工单分诊 Agent 的 System Prompt。
System Prompt(系统提示词)是给 Agent 的稳定指令:它告诉 Agent 承担什么角色、遵循什么规则、按什么格式输出。同一个模型在不同 System Prompt 下会表现出完全不同的行为,因此 System Prompt 是决定 Agent 质量的核心资产。
本教程的做法是:每次更新 System Prompt 自动产生新版本,用带标注的评估集量化对比新旧表现;一旦出现回归,秒级回滚;修复后按流量灰度放量。全过程不需要重新部署任何代码。
核心亮点:
- 修改 System Prompt 即发版:System Prompt 是服务端的版本化资产,更新一次产生一个新版本,秒级生效,不走代码发布链路。
- 回滚等于修改一个数字:生产配置把版本号指回旧版本,新建 Session 立即回到旧行为,无部署、无停机,也不需要删除任何东西。
- 版本号即 feature flag:灰度、A/B 对比、按用户分组放量,都用「创建 Session 时锁定哪个版本」表达。
- 量化迭代:带标注测试集给每个版本打分,回归当场检出;不依赖肉眼盲测 System Prompt diff。
一个工单分诊 Agent 的职责是:客服工单进入系统后,Agent 读完工单并输出一行 JSON:说明该派给哪个团队(billing、auth、api-platform、dashboard)、优先级如何:下游系统按结果自动派单。这类 Agent 的行为几乎完全由 System Prompt 决定,而修改 System Prompt 又非常「顺手」:一句话即可上线,不用编译、不用测试。
顺手就意味着危险。改坏 System Prompt 与改坏代码属于同一级别的生产事故,但大多数团队只对代码建立了版本控制。
本教程涉及的核心能力:
准备一台 macOS 或 Linux 设备,并安装以下命令行工具:
先设置 API 地址和 API Key。API Key 只应保存在本地环境变量或服务端密钥系统中,不要硬编码在代码中。
鉴权使用 Authorization: Bearer $ARK_API_KEY。
评估集是版本管理的另一半:没有它,「新版本更好」只是主观感觉。准备一份 tickets.jsonl,每行一条工单,带正确答案:
建议 20 到 50 条、覆盖所有团队,并刻意包含易混淆样本:例如上面第三条:通篇都是「API 用量」,但客户实际问的是计费问题。这类样本正是后续检出回归的关键。
创建分诊 Agent(纯文本判断任务,不需要挂工具)和一个运行环境:
Agent 创建响应中 version 为 1:创建即 v1,之后每次更新自动递增。
将 Agent ID 与 Environment ID 写入环境变量,供后续脚本使用。environment_id 指定 Session 使用的运行环境。创建 Session 时必须传入该字段;省略后,接口返回 HTTP 400 MissingParameter。
对评估集逐条执行同一套闭环:为指定版本创建 Session、发送工单、等待 session.status_idle,再读取最后一条 agent.message 并与标注答案比对。实现时必须设置总体超时,并把「结构不合法」、「工具错误」、「超时」与「模型判错」分开统计。
每次评估还应记录 Agent 版本、模型版本、评估集版本、运行时间、失败或超时样本,以及可获得的 request ID。准确率之外,至少单独统计「结构不合法」、「工具错误」和「超时」三类异常,避免把运行故障误判成模型质量问题。
跑出 v1 基线:
billing 有一条错分:正是那条「通篇 API 用量、实际是计费问题」的工单,被路由到了 api-platform。这是我们要修复的问题,也是版本迭代的起点。
针对 billing 错分,给 System Prompt 追加一条路由规则。调用 Agent 更新接口,必须带上当前版本号(乐观并发锁):
响应中 version 变为 2。更新接口有三条关键语义:
- version 是并发保险:传入值必须等于当前版本。不匹配时返回 HTTP 400 InvalidParameter,错误消息为 version: conflict,说明有其他协作者先一步发布了新版本。此时需重新查询最新版本,再基于最新配置提交,避免互相覆盖。
- 省略的字段继承上一版本:本次只传了 system,name、model 等字段原样保留,不会被清空。
- 仅更新 display_name 不产生新版本:只修改 display_name 且省略其他字段时,版本号保持不变。更新 system、model、tools、skills、mcp_servers 等版本化字段时,即使提交值与当前版本相同,也会生成新版本。服务端仅根据请求体中是否出现版本化字段判断,不比较新旧值。
注意
版本冲突后不要直接重复提交原请求。先查询智能体详情获取最新 version,合并其他协作者的改动,再使用新版本号更新;继续使用旧版本号会再次返回 HTTP 400 InvalidParameter。
用同一把尺子度量新版本:
v2 不但没有修好问题,还引入了回归:那条规则写得太激进:billing 的工单天然会提到「API 用量」(超量才产生扣费争议),现在全部被这条规则劫持到了 api-platform。
值得停下来看清这件事:v2 的 System Prompt diff 在 review 时看起来完全是改进:更明确、更具体、指令性更强。这个坑只有「同一评估集跑两个版本、逐类目对比」才能暴露。这正是 System Prompt 变更必须走版本加评估,而不是「看起来没问题就上」的原因。
回滚不是一个 API,而是一次配置变更。 生产代码创建 Session 时从配置读取版本号,出问题就把它指回去:
三个让回滚「秒级且无痛」的事实:
- 存量 Session 在创建时就锁定了各自版本,本来就不受发版影响;
- 新建 Session 从配置修改那一刻起全部回到 v1;
- v2 不需要删除:它留在服务端,是下一轮修复(v3)的底稿,也是事故复盘的证据。
注意
生产环境默认应使用对象形式锁定版本,以确保评估、灰度和回滚可复现。只有明确接受「自动跟随最新版本」风险的非生产或受控场景,才使用字符串形式。
修复规则后发布 v3(把「一律路由」改成「结合扣费、账单语境判断」),评估通过(billing 回到 5/5)。这次不直接全量,按用户灰度放量:版本分配是应用层的事:
按用户哈希而不是按请求随机,好处是同一用户始终落在同一版本:行为一致,出问题也能精确圈出受影响的用户群。之后按 10% > 25% > 50% > 100% 逐档放量,每一档都用线上指标或评估集复核一遍。
随时可以列出全部版本历史,核对每一版的 System Prompt 内容:
与本系列上一篇的连接:创建 Session 时 vault_ids 与 agent.version 可以同时使用:「以谁的身份行动」和「用哪一版行为」是 Session 上两个正交的旋钮,多租户凭据隔离和版本灰度可以互不干扰地组合。