Agent 能跑不等于岗位还合格:给 AI 员工做一次可回滚的上岗发布

客服 Agent 昨天还会从商品库读取当前价格,今天却在回复里引用了一段旧 FAQ。调用链没有异常,JSON 结构也完全正确。

排查后才发现,团队做了三个看似独立的小改动:换了默认模型,重新索引知识库,把查询工具从 v2 升到 v3。每个改动单独看都能运行,组合起来却已经不是上周批准上线的那个岗位版本。

Agent 进入长期生产后,真正麻烦的不是 crash,而是 silent drift:它还在工作,却不再按岗位约定工作。

先做 diff,再问"要不要修"

最近 Google Cloud 在 VM Extension Manager 的官方更新中提到声明式策略、持续漂移检测、分阶段发布和自动回滚。官方讨论的是 VM 扩展治理,并不是 AI Agent。这里借用的是控制面的思路:先描述目标状态,再持续比较观测状态。

不要把目标状态压成一段 system prompt。一个岗位版本至少要锁住这些内容:

ts 复制代码
type RoleRelease = {
  id: string;
  modelPolicy: {
    primary: string;
    fallbacks: string[];
    paramsHash: string;
  };
  instructionBundle: string;
  skills: Array<{ name: string; version: string; checksum: string }>;
  tools: Array<{
    name: string;
    schemaHash: string;
    permission: "read" | "draft" | "execute";
    approval: "never" | "before_execute";
  }>;
  knowledgeSnapshot: string;
  outputSchema: string;
  evalSuite: string;
  rollbackTo: string;
};

这份 release 不负责动态发现所有能力。它只记录当前岗位已经批准使用的组合,是下一次 diff、评测和回滚的锚点。

配置相同,也可能已经漂移

如果 reconciler 只对比 checksum,它最多发现"装错了什么",发现不了"同样的配置为什么做差了"。因此观测数据至少分两组:

ts 复制代码
type RoleObservation = {
  inventory: {
    model: string;
    skillChecksums: string[];
    toolSchemas: string[];
    knowledgeSnapshot: string;
    approvalPolicy: string;
  };
  behavior: {
    contractPassRate: number;
    citationCoverage: number;
    policyViolationCount: number;
    humanRewriteRate: number;
    costPerTask: number;
    p95Ms: number;
  };
};

模型别名背后的实现变化、知识检索分布变化、上游接口返回值变化,都可能让 inventory 一致但 behavior 退化。

这里有个重要边界:humanRewriteRate 上升不一定是模型退化,也可能是本周任务更难。行为指标适合触发复核,不能独立充当裁决器。

Reconciler 应该输出决策,不要直接"自愈"

轻量 reconciler 可以保持为纯函数:

ts 复制代码
type Action =
  | { type: "NOOP" }
  | { type: "RESTORE_PINNED_CONFIG"; paths: string[] }
  | { type: "RUN_EVAL"; suite: string }
  | { type: "REQUEST_APPROVAL"; reasons: string[] };

function decide(
  desired: RoleRelease,
  observed: RoleObservation,
  diff: Diff,
): Action {
  if (diff.empty) return { type: "NOOP" };

  if (diff.expandsPermissions || diff.removesApproval) {
    return { type: "REQUEST_APPROVAL", reasons: diff.riskReasons };
  }

  if (diff.onlyPinnedArtifactsChanged && diff.isReversible) {
    return { type: "RESTORE_PINNED_CONFIG", paths: diff.paths };
  }

  return { type: "RUN_EVAL", suite: desired.evalSuite };
}

自动恢复只适用于可确定比较、可逆、不会扩大权限的字段。模型行为、知识语义、外部写权限都不应被一个 autoHeal=true 粗暴覆盖。

给岗位升级加一个 canary cohort

一次发布可以先通过离线 fixture,再按稳定哈希分配少量真实任务:

ts 复制代码
function chooseRelease(taskId: string, plan: RolloutPlan): string {
  const bucket = stableHash(`${plan.salt}:${taskId}`) % 100;
  return bucket < plan.canaryPercent
    ? plan.candidateRelease
    : plan.stableRelease;
}

为什么用稳定哈希,而不是每次随机?同一个任务重试时应该留在同一 cohort,否则一次失败重试可能换版本,排查证据会被污染。

canary 的门禁不要只看总成功率。至少分别监控:

  • 输出契约通过率;
  • 来源引用覆盖率;
  • 权限违规次数;
  • 人工改写或驳回率;
  • 单任务成本与 P95 时延;
  • fallback 和人工接管比例。

高风险指标一旦越界,停止扩大 cohort。外部发布、付款、删除文件等动作,即使质量指标漂亮,也应保留独立审批门槛。

本地 override 不是"脏数据"

全局岗位模板经常允许门店、项目或个人做定制。全局版本升级时,本地 override 不能被静默覆盖。

官方的全局 VM 扩展策略文档也专门定义了冲突行为,默认不覆盖独立修改,并允许显式选择覆盖。映射到岗位版本,可以保存三方 diff:

ts 复制代码
type MergeInput = {
  base: RoleRelease;
  desired: RoleRelease;
  local: Partial<RoleRelease>;
};

type MergeResult = {
  merged?: RoleRelease;
  conflicts: Array<{
    path: string;
    severity: "semantic" | "permission";
  }>;
};

门店地址这类数据可能安全合并,价格来源、审批策略和写权限则应进入人工裁决。把所有 override 当作脏数据清掉,短期整齐,长期一定伤害业务。

回滚的是 release,不是某一个模型名

一个 Agent release 是经过测试的组合:模型、指令、Skill、工具 schema、知识快照和权限策略。只把模型切回旧版,剩余组件仍是新版,就构造了一个从未验证过的状态。

所以回滚应该是原子的:把流量路由回上一份不可变 release。候选 release 可以继续保留,用于复现失败,不要在事故中直接覆盖它。

重试也要幂等:

ts 复制代码
const idempotencyKey = [
  tenantId,
  roleId,
  candidateRelease,
  "rollout",
].join(":");

同一个 key 返回原发布任务,避免网络抖动创建两组 canary。

别把控制面做成新的配置税

小团队不需要先建设"Agent Kubernetes"。可以从最小闭环开始:

  1. 选一个会对外写入的高风险岗位;
  2. 保存一份不可变 release manifest;
  3. 准备十几个覆盖失败边界的 fixture;
  4. 只设一个 canary 百分比和一个稳定回滚版本;
  5. 把 diff、评测、批准和回滚写入同一审计记录。

低风险草稿、一次性脑暴没有必要通过完整发布链。治理的目标是降低不确定性,不是增加一套每天要维护的表单。

岗位产品真正要保留什么

这也是我们做 Tipkay 时的一个取舍。Tipkay 面向小微企业、一人公司和小团队,提供按需使用的垂类 AI 员工。不同岗位助手可以复制、定制和协作,携带各自的 Skill、MCP、工具与流程。

这样的系统不能只解决"第一次配置成功",还要避免岗位经验在模型、工具和知识变化时悄悄丢失。本文的基线与发布控制面是一种工程方法,不代表语义差异都应自动修复;高风险变化仍需要评测与明确批准。

Agent 上线后的关键指标,不只是今天成功调用了多少次。更值得追问的是:当前运行的到底是哪份岗位 release,它和批准版本差在哪里,失败后能否回到一个经过验证的组合。

相关推荐
IT_陈寒1 小时前
React hooks闭包陷阱让我加了一宿班
前端·人工智能·后端
beiju1 小时前
别让 Agent 只会写脚本:用 Producer 模式编排内容生产
人工智能
心易行者1 小时前
用html在线运行做数据可视化大屏,5个实战场景从入门到上线
大数据·前端·数据库·人工智能·python
Rescenix1 小时前
agent前台被批量举报的复盘:频率特征 + uv venv shim 幻影导致的进程双开误判
前端·人工智能
橘子星1 小时前
给 Agent 装上有记忆的"脑子"(三):把对话存进向量库,让 Agent 拥有"长期记忆"
javascript·人工智能
深蓝AI1 小时前
AI Agent 上生产前,先把可观测性、权限与预算做成三道闸门
人工智能
leikooo1 小时前
ARTS 0906: 辅助栈记录每层最小值、OSI 模型从未真正落地与与其被动等待被颠覆不如主动设计规则
数据结构·人工智能·tcp/ip
武子康1 小时前
从声学信号到工具阻断:实时语音安全决策门的系统设计
人工智能·llm·agent