把模型变成 Agent 的那层脚手架:atelier

💡 原文中文,约5800字,阅读约需14分钟。
📝

内容提要

atelier 是纯仓颉实现的 Agent Harness,即让模型能自主干活的脚手架,解决六类问题:推理循环(AgentRuntime 七阶段,插话排队不打断)、上下文管理(阈值修剪、摘要、超窗恢复、手动压缩四层)、工具系统(内置、MCP、子 Agent 三层来源,根表与 run 派生表分离)、信任权限(目录级三态判定,未决定时发结构化审批,闸门可替换)、会话(parentId 树形结构,可 fork,存储可换)、多协议接入(内核出事件,ACP、A2A、AG-UI 各自投影)。核心是 HarnessSpec 的 17 个可注入点,内核策略也可替换。它不做可视化编排、模型训练和分布式,定位为工坊而非框架。

🔎

延伸解读

Harness 与框架的分界:机制而非编排

文章把 API 客户端、编排框架与 Agent Harness 三者区分开:前者只收发请求,后者按预设图调步骤,而 Harness 提供让模型自主干活所需的全部机制,却不替使用者决定做什么。atelier 自称「成品工坊而非编排框架」,意味着它给出可挂载的零件与默认实现,而不要求应用按它的抽象来描述自身。理解这一点,才能判断它适合需要深度定制循环与权限的场景,而非只想拖拽工作流的团队。

插话语义与工具声明顺序:两个易被忽略的成本点

用户中途补充消息时,atelier 选择排队到下一次模型调用可见,并给插入内容加标注,避免模型把最后一条用户消息误当成推翻原任务的新指令;若直接打断工具,可能留下半写状态。另一处细节是工具声明必须稳定排序,否则每次请求顺序变化会让 provider 的前缀缓存失效,直接影响成本与延迟。这两点说明 Harness 的工程质量往往藏在交互语义和缓存友好性里,而非功能清单上。

17 个注入点定义了边界与主张

HarnessSpec 把工具、模型、会话存储、信任闸门、压缩器、循环工厂、事件总线等 17 项收拢为可替换字段,每项都有默认值。文章强调「哪些能换」就是框架边界,「默认值是什么」就是它的主张。对读者而言,这意味着采用 atelier 时真正要评估的不是它默认能做什么,而是默认策略(如 BasicCompactor、目录级信任)是否符合自身风险偏好,以及替换这些策略的改造成本是否可接受。

明确不做的四件事,反而划清了适用场景

atelier 不做可视化编排、不做模型训练微调、不做多机分布式,也不提供提示词市场,Skills 只给机制、内容由用户提供。这些取舍配合单进程定位,说明它面向的是愿意用代码或 TOML 定义 Agent、并自行承担内容与部署的团队。文章还提到下游世界树、星痕等产品真实在用,需求来自实际产品而非想象,这比单纯的功能罗列更能说明其迭代依据,但也提醒读者其成熟度仍处于 0.1.x 阶段。

❓

Q&A

atelier 是什么?它和普通 API 客户端或编排框架有什么区别?

atelier 是一个纯仓颉实现的 Agent Harness,即“把模型变成 Agent 的那层脚手架”。与 API 客户端(只收发请求)和编排框架(按预设图调步骤)不同,harness 不替你决定做什么,但提供模型自主干活所需的全部机制,如推理循环、上下文管理、工具调用、权限判定、会话持久化和多协议接入。

atelier 的推理循环是如何设计的?用户中途插话会怎么处理?

推理循环由 AgentRuntime 实现,拆分为七个阶段:openTurn、compactBeforeRequest、invokeProvider、executeToolBatch、admitToolCall、admitAfterHooks、admitByAsking。对于用户插话,atelier 选择排队方案:当前工具执行完后,在下一次模型调用时可见,并且插入时会带标注(如 [用户中途补充]),避免模型误以为新消息推翻了原任务。

当对话超出模型上下文窗口时,atelier 有哪些应对措施?

atelier 采用阈值触发和四层递进策略:1)工具结果修剪(超长输出留头尾);2)摘要压缩(将头部历史压成一条 CompactionMessage);3)超窗恢复(强制压缩后重试);4)手动 /compact 命令。触发阈值按 min(窗口×0.8, 窗口−输出预留−headroom) 计算,并优先使用 provider 返回的用量数据。

atelier 的工具系统支持哪些来源?如何避免并发会话间的工具冲突?

工具来源有三层:内置工具、通过 MCP 接入的工具、以及将另一个 Agent 作为工具(Agent-as-Tool)。工具注册表分为根表(全局可见)和 run 派生表(run 作用域,结束即弃),避免 run 级工具写入根表导致并发会话互相看见对方的工具,从而可能按别人的工作目录过信任闸门。

atelier 如何判断模型执行命令是否安全?未决定时会发生什么?

atelier 采用目录级三态信任判定(Undecided/Trusted/Untrusted),按 per-session 覆盖、sessionTrusts、目录级持久信任的顺序查询。当状态为 Undecided 时,不是直接拒绝,而是发起结构化审批请求,用户可选择允许本次、总是允许或拒绝。审批请求走统一的 UserRequest → UserAnswer 通道,且信任闸门(TrustGate)可替换。

atelier 的会话结构是怎样的?支持分支吗?

会话不是线性消息列表,而是树形结构,每个 Entry 包含 parentId 指向父节点,因此支持 fork/clone 出分支,回到某个节点重新尝试另一条路径时无需重放历史。消息类型包括 UserMessage、AssistantMessage、ToolResultMessage、CompactionMessage 和 ArchiveMessage。存储层可替换,默认内存存储,也可换成基于 storm-cj 的持久化实现。

atelier 如何支持多种协议接入?新增协议需要改内核吗?

atelier 内置 ACP、A2A、AG-UI 三种协议适配,它们都是同一套内核事件(AgentEvent)的不同投影:内核只产生事实,各协议适配层决定如何投影。因此新增一个协议只需增加适配层,无需改动内核。

atelier 的 HarnessSpec 是什么?它提供了哪些可定制点?

HarnessSpec 是 atelier 的核心装配面,包含 17 个可注入点,涵盖工具、模型、会话、信任、扩展、外部 MCP、交互以及内核策略(如压缩器、循环工厂、状态注册表、事件总线)。每个字段都有默认值,也都可以替换,因此 atelier 不是写死的实现,而是一组约定接口加默认实现。

🏷️

标签

➡️

继续阅读