架构
A3S Code 把配置解析、逐次运行、稳定的线协议契约与持久化分成清晰边界。 TUI 和 SDK 使用同一个运行时内核,不存在另一套执行路径。
异步优先的会话构建
SessionOptions 是公开的配置补丁,不是半初始化的运行时状态。异步构建路径会把
它与 CodeConfig 合并,校验冲突选项,初始化异步资源,再生成唯一的内部
ResolvedSessionConfig。后续会话组装只消费这个已解析值,不会让不同
层各自重复决定同一个配置。
Rust 宿主应优先使用:
Agent::session_async、resume_session_async、session_for_agent_async 与
session_for_worker_async 使用同一个构建内核。文件型记忆和会话存储、队列、
轨迹记录器与会话 MCP 发现都在异步阶段初始化;失败时返回带具体资源信息的
SessionConfiguration 或 SessionInitialization 类型错误。
同步 Agent::session 只为已经显式传入预初始化记忆存储、并初始化好其他全部资源的
宿主保留兼容。它不会启动或阻塞 Tokio 运行时。任何需要异步工作的配置都会返回
CodeError::AsyncSessionBuildRequired;运行时不会悄悄换成更容易构建的后端。
通过 SessionOptions::with_mcp 传入的管理器始终需要异步发现能力;同步路径只能
继承智能体启动时已经缓存的全局 MCP 工具。
对话状态的单任务约束
对话历史通过准入机制串行化,而不是依赖乐观锁。同一个会话同时只能有一个会影响
对话记录的操作,包括 send、stream、两种附件变体、斜杠命令与 resume_run。
重叠调用会在读取历史或派发命令前立即返回
CodeError::SessionBusy。
流式调用会一直持有准入租约,直到流式运行时真正结束。丢弃或中止公开句柄不会在原 生产者仍写入事件和历史时短暂放行第二个操作。直接宿主工具调用属于控制面操作, 不占用对话租约。
调用上下文
每个已准入运行都会创建一个不可变的 InvocationContext,其中包含:
- 运行标识与会话标识
- 运行取消令牌
- 事件发送器
- 治理快照,包括当前预算守卫
它是服务提供商与工具工作的单一事实来源,也会把同一个取消令牌和会话身份安装进
ToolContext。因此取消可以传递到排队工具、嵌套的 batch/program、委派任务、
规划、结构化输出修复、压缩以及其他属于该运行的辅助调用。
大语言模型调用边界
属于运行的服务提供商工作统一经过有作用域的大语言模型调用器。它在每次服务提供商 调用前检查预算与取消,在成功响应后记录用量;流式路径会代理最终用量,并合并调用方 取消与运行取消。普通回合、规划、结构化输出及修复、压缩、记忆和辅助路径都使用这个 边界,不再各自维护预算逻辑。
硬预算拒绝会作为错误返回,绝不会转换成不受治理的回退。软上限会发出
budget_threshold_hit 事件,然后继续当前调用。
工具调用边界
工具调用器是模型选择、嵌套、程序化、委派与宿主直接调用的统一治理内核。对模型发起
的工作,它会执行当前技能限制、权限策略、前后置钩子、预算检查、人工确认、队列与
超时、取消、递归调用保护及输出净化。batch 和 program 接收的是有作用域的调用器,
而不是原始注册表,因此内部调用不能绕过这些检查。
直接 SDK 辅助方法使用显式的 HostDirectPolicy::TrustedControlPlane 来源。宿主已经
是选择该操作的权威,因此跳过面向模型的权限与人工确认决策;但前置钩子仍可阻止调用,
预算、队列与超时、取消、递归保护、后置钩子和输出净化仍然生效。应用在把这条特权
路径暴露给终端用户前,必须自行完成授权。
稳定事件协议
AgentEvent 是 Rust 内部运行时枚举。跨语言契约是无损信封:
v1 事件目录与 Rust 穷尽映射共享一个事实源,因此新增运行时变体却没有规范线协议
名称会直接导致编译失败。Node.js 与 Python 使用统一投影生成 text、toolName、
tool_name 等便捷字段。type 保持开放字符串:未来未知类型仍会完整保留载荷与
元数据,不会被压成 unknown 哨兵值。
原子会话持久化
SessionSnapshotV1 表示一个带版本号的完整持久化代次,包含对话、制品、追踪事件、
运行记录、验证报告与委派任务快照。session.save() 会物化这个聚合快照,并且只调用一次
SessionStore::save_snapshot。
文件存储先写入并同步临时文件,再通过原子替换发布一个完整 JSON 信封;内存存储在
同一把锁下替换整个聚合条目。两者都会声明原子快照能力。历史裸 SessionData 与
分片目录仍可读取以便迁移,但新保存不会发布碎片化代次。自定义存储必须显式实现
聚合保存;默认方法返回错误,不会把部分写入或空操作写入当成成功。
MCP 所有权与隔离
MCP 管理器的所有权是显式的:
- 智能体全局管理器持有从全局配置加载的服务器。
- 会话选项中由宿主传入的管理器是继承的只读能力来源。
- 每个会话都新建一个私有实时管理器。
能力按以上顺序组装,因此会话本地工具只能在当前会话内遮蔽继承工具。实时
add_mcp_server / remove_mcp_server 只改变私有管理器;移除本地遮蔽后会重新显露
继承能力。同级会话不能互相修改;委派的子智能体会继承调用同一批工具所需的有序
管理器来源,但不会取得它们的所有权。
程序化工具调用
program 工具在内嵌 QuickJS 虚拟机中运行 JavaScript,只暴露受控 ctx 对象。虚拟机
没有直接文件系统、网络、子进程或环境变量访问权;有用能力都通过 scoped tool
调用器回到 A3S Code。下一步需要判断时使用普通模型工具调用;动作序列已经确定、
只需让模型理解结果时,使用有边界的程序。
扩展点
通过带类型的会话选项、技能、智能体定义、钩子、MCP 服务器、记忆和会话存储、 安全提供程序、队列配置与工作区服务扩展运行时。优先使用显式策略和可回放证据, 不要引入平行执行路径。