面向异构多智能体的意图驱动型产物运行时
核心声明:本架构的核心假设是 Agent 是有状态的,产物也是有状态的。脱离这个前提,所有关于“意图路由”、“状态锚定”、“并发锁”的设计都失去意义。状态不是附属品,而是架构的第一公民。
一、 思想渊源:继承于两篇文章的“道”
本架构严格遵循 phodal 老师在两篇文章中提出的三大核心原则:
| 文章核心理念 | 核心要义 | 在本架构中的映射 |
|---|---|---|
| 以产物为中心 | AI 交互应围绕共同维护的“工作现场”(产物),而非对话历史。 | 所有状态锚定在 .workspace.md / .ipynb 文件系统中;对话仅作为触发入口。 |
| 观察→寻址→操作→验证闭环 | Agent 对产物的操作需遵循严格闭环,而非一次性生成。 | Runtime 强制执行:先读 MD 观察状态→通过意图路由寻址执行器→执行后落盘 Session→断言校验。 |
| Harness 协作环境 | 需要一个环境消化工程复杂度,承载人与 Agent 的协作。 | Runtime Core 与 Legacy 桥接器充当复杂度消化池,将底层 K8s/Git/API 的复杂性屏蔽在 Agent 认知之外。 |
二、 核心前提:Agent 有状态,产物有状态
这是本架构一切设计的逻辑原点。
1. Agent 是有状态的
| 维度 | 说明 | 架构体现 |
|---|---|---|
| 身份状态 | 每个 Agent 实例拥有唯一的 agent_id,绑定其所属用户、群聊、权限范围。 |
所有操作日志记录 agent_id,门禁校验基于 agent_id 查询权限。 |
| 会话状态 | Agent 的一次运行会话(从启动到关闭)拥有独立的 session_id,期间的所有中间变量、已加载的模块、缓存的上下文均保持有效。 |
每个 Workspace 下按 agent_id 复用或隔离 Kernel;sessions/*.md 存储会话临时状态。 |
| 记忆状态 | Agent 在不同时间点执行的结果会影响其后续行为(如“上次部署成功,本次可跳过验证”)。 | 主 .workspace.md 记录 last_successful_deploy 等累积状态,供 Agent 下次执行时读取。 |
| 并发状态 | 多个 Agent 同时操作同一产物时,必须知晓彼此的存在和进度。 | 三级锁(Workspace/Shared/Sandbox)记录当前持有锁的 agent_id 和等待队列。 |
2. 产物是有状态的
| 维度 | 说明 | 架构体现 |
|---|---|---|
| 版本状态 | 每个产物(代码文件、配置文件、部署产物)都关联一个确定的 Git Commit 或版本号。 | .workspace.md 中的 git_base 字段锁定所有产物的版本基线。 |
| 生命周期状态 | 产物经历“草稿 → 评审 → 就绪 → 已部署 → 已归档”等阶段。 | .workspace.md 中的 artifact_status 记录当前阶段;sessions/*.md 记录过渡状态。 |
| 关联状态 | 产物之间存在着依赖关系(如 design.md 依赖 api.proto)。 |
.shared_state.md 记录跨产物的哈希指纹,变更时联动校验。 |
| 历史状态 | 产物的每一次变更都应可追溯。 | logs/*.ipynb 记录每次操作的完整上下文,形成不可篡改的审计链。 |
3. “有状态”带来的架构刚性要求
- 状态必须持久化:不能仅存在于内存中。Agent 重启、Sandbox 重启后状态必须可恢复。
- 状态必须可寻址:任何 Agent 在任何时刻都能通过确定的路径(如
ws_frontend/.workspace.md)读取到当前状态。 - 状态变更必须原子化:多 Agent 并发写入时,必须通过锁机制保证状态文件不被写坏。
- 状态变更必须可审计:每一次状态变更都要记录“谁、何时、因何意图、从什么变到什么”。
三、 与 MCP/CLI/API 的关系定位:不是重造轮子
本架构没有重造 MCP,而是在 MCP/CLI/API 之上构建了 **“状态感知的参数装配层”**和 “意图驱动的编排层”。
| 层级 | 职责 | 示例 |
|---|---|---|
| MCP / CLI / API(执行层) | 提供标准化的原子能力接口,定义“工具长什么样”(参数名、类型)。 | kubectl apply -f <file>、jira.create_issue() |
| 本架构(调度与治理层) | 1. 将 Agent 的简短意图({intent:"deploy"})展开为完整参数2. 从状态文件中读取参数值( commit_hash、env)3. 调用执行层完成操作 4. 将执行结果写回状态文件 |
Runtime 读取 .workspace.md 中的 git.commit,装配为 --commit abc123,再调用 MCP 工具。 |
一句话总结:MCP 解决“怎么调用工具”,本架构解决“调用的参数从哪来、调完后状态怎么变”。
四、 核心痛点与范式转移
| 维度 | 旧范式(当前主流) | 新范式(本架构) |
|---|---|---|
| 对 Agent 的认知 | Agent 是无状态的请求响应器,每次调用独立。 | Agent 是有状态的,拥有身份、会话、记忆和并发上下文。 |
| 对产物的认知 | 产物是静态文件,用完即弃。 | 产物是有状态的,拥有版本、生命周期、关联关系和历史记录。 |
| 交互模式 | 指令式:Agent 需记忆函数名、参数拼写。 | 声明式:Agent 只表达意图({intent:"deploy"})。 |
| 技能接入 | 需显式注册工具或编写 YAML。 | 约定优于配置:脚本放入 .skills/ 即自动发现。 |
| 状态感知 | 无状态:每次执行需重新查分支、查 commit。 | 状态锚定:参数由 Runtime 从 .workspace.md 自动装配注入。 |
| 并发冲突 | 无治理:多 Agent 同时操作极易覆盖。 | 三级锁 + 哈希指纹:并发“脏写”从源头拦截。 |
| 环境变量 | 全局污染:多用户 @ 不同机器人互相覆盖。 | 作用域副本注入:平台/Bot/User 三层隔离。 |
| 数据安全 | AI 直连数据库,易被提示词注入。 | 门禁前置(Auth Hook):强制校验通过后才转发。 |
| 迁移代价 | 推倒重来。 | 零废弃兼容:旧脚本软链接即可接入。 |
| 执行安全 | AI 进程拥有脚本执行权限,易被利用。 | noexec 挂载 + 物理/逻辑隔离:AI 进程仅能通过 Intent 代理通信。 |
五、 总体逻辑分层架构
注:整体架构图(Mermaid)已统一移至本文档末尾的“附录”部分,以保持正文阅读的纯净性。
本方案采用 “薄入口 + 厚内核 + 约定式文件系统 + 安全隔离边界” 架构,完美适配“平台无法修改、仅能挂载技能”的硬约束。
各层职责简述:
- 入口与身份层:适配 IM、SDK、VSCode 等多渠道入口,提取群聊、用户身份。
- 适配与状态注入层:将群聊解析为 Workspace 上下文,从状态文件读取参数并注入子进程。
- 运行时核心层:自动发现技能、路由意图、门禁校验、并发锁、状态管理、契约仲裁。
- 执行多态层:支持原生 JS、脚本执行器、Legacy 桥接、第三方代理,按优先级决议。
- 安全隔离边界(新增):通过 noexec 挂载、Intent Proxy 设计、物理/远程执行隔离,确保 AI 进程无法直接执行任意代码。
- 状态存储与审计层:四层状态文件 + 审计黑匣子,确保持久化、可寻址、原子化、可审计。
六、 独创性构想:文章之外的核心补全拼图
| # | 独创构想 | 核心价值 |
|---|---|---|
| 1 | Agent 有状态、产物有状态作为第一性原则 | 所有架构设计的逻辑原点,决定了持久化、寻址、审计等刚性需求。 |
| 2 | 约定优于配置(.skills/ 自动发现) |
开发者放入脚本即完成接入,零 YAML 门槛。 |
| 3 | 四层状态文件模型(Sandbox/Workspace/Shared/Session) | 彻底解决并发状态污染,支持多仓库多分支。 |
| 4 | 上下文感知路由(群聊 → Workspace → 仓库 → 分支) | 多团队、多项目、多分支并行时自动决议执行目标。 |
| 5 | 状态感知的参数装配 | 脚本通过约定环境变量名或位置参数自动接收状态值,零改动。 |
| 6 | YAML 作为覆盖层,而非强制层 | YAML 仅用于覆盖默认行为,非必选项。 |
| 7 | IM 身份与环境变量作用域隔离 | 平台/Bot/User 三层变量隔离,互不污染。 |
| 8 | 守护进程调度器 + 紧急直写模式 | 解决多 Agent 真并行 + 守护进程崩溃容灾。 |
| 9 | 门禁前置(Auth Hook) | 强制校验通过后才执行业务,数据库始终为黑盒。 |
| 10 | YAML 与 DSL 分层协作 | YAML 定义常态默认契约,Notebook DSL 定义本次例外。 |
| 11 | 状态抽象模型(State Abstraction Model) | 将状态字段抽象为带元属性的智能指针,统一治理“取哪里、怎么刷、多久有效”。 |
| 12 | 轻量级客户端 SDK(JS/Python) | 复用 skykoma 命令,用 ~80 行代码封装 get/commit/eval,新技能零通信成本接入。 |
| 13 | 安全执行隔离边界(Security Isolation Boundary) | noexec 挂载 + Intent Proxy + 物理/远程隔离,彻底杜绝 AI 进程任意代码执行风险。 |
七、 关键技术组件详解
7.1 约定式技能发现机制(核心创新)
目录结构约定:
执行器多态优先级决议:
| 优先级 | 匹配规则 | 触发条件 |
|---|---|---|
| P0(最高) | Notebook 中 #override 显式指定 |
运维人员临时干预 |
| P1 | 请求中显式指定版本标签(如 --version js) |
A/B 测试新脚本 |
| P2 | skill.yaml 中 default_executor 声明 |
技能开发者配置 |
| P3(回退) | 文件扩展名优先级:.js > .py > .sh > 无扩展名 |
无任何配置时兜底 |
参数自动注入(零代码改动):
- 旧脚本可通过约定环境变量名接收参数:
$COMMIT_HASH、$WORKSPACE、$BRANCH、$ENV - 也可通过位置参数接收:
$1、$2、$3 - Runtime 从
.workspace.md读取状态后,在子进程层面完成注入,脚本源码无需任何改动
7.2 上下文感知路由(多仓库/多分支/群聊映射)
| 实体 | 定义 | 示例 |
|---|---|---|
| Sandbox | 物理容器/VM,资源池 | sb_aws_001 |
| Workspace | 逻辑工作区,映射一个或多个仓库路径及分支 | ws_frontend → /code/frontend (main) + /shared/libs (main) |
| Agent | Cursor/OpenCode SDK 实例 | cursor_pid_12345(绑定 user_id) |
| 群聊(IM Context) | 绑定默认 Workspace 的 IM 群组 | #前端群 → ws_frontend |
路由决议矩阵:
| 条件 | 决议 Workspace | 锁策略 |
|---|---|---|
消息来自 #前端群 |
ws_frontend |
加 Workspace 锁 |
消息 @了 @backend_bot |
ws_backend |
加 Workspace 锁 |
消息含 --workspace backend |
显式指定 ws_backend |
加 Workspace 锁 |
多分支并发规则:
- 同一 Workspace 下,不同分支的操作可并发执行(互不干扰)
- 同一分支的操作需排队串行化(加 Workspace 级锁,由内存队列保证)
7.3 四层状态文件模型
| 层级 | 文件 | 职责 | 写入模式 |
|---|---|---|---|
| Sandbox 层 | .sandbox.md |
资源清单、Workspace 路由表、群聊映射、Kernel PID | 覆盖 |
| 共享层 | .shared_state.md |
跨 Workspace 共享路径的读写锁 + Merkle 哈希指纹 | 原子覆盖 |
| Workspace 层 | .workspace.md |
项目真相源:Git 状态、部署状态、产物生命周期、上次成功记录 | 覆盖(永不膨胀) |
| Session 层 | sessions/*.md |
临时任务私有暂存区,执行成功后原子合并回主 MD | 追加/删除 |
| 审计层 | logs/*.ipynb |
完整执行链审计(含脱敏环境变量、Agent ID、用户 ID) | 守护进程串行追加 |
7.4 YAML 的定位:覆盖层,而非强制层
黄金法则:没有 YAML,系统照常工作(用约定和自动发现)。有 YAML,系统按照 YAML 的声明精细化工作。YAML 是可选项,而非必选项。
YAML 的唯一用途(覆盖自动发现无法处理的特殊情况):
- 脚本文件名不符合约定(如
deploy_aws.sh而非run.sh) - 需要声明特殊的
auth_hook(权限校验接口) - 需要声明特殊的
params_mapping(参数名与环境变量名不一致)
7.5 Kernel 与子进程的隔离与复用策略
| 规则 | 说明 |
|---|---|
| 每个 Workspace 独立 Kernel | ws_frontend 与 ws_backend 使用不同 Kernel,内存完全隔离 |
| 同一 Workspace,同一用户复用 Kernel | zhangsan 在 ws_frontend 的多次操作共享 Kernel,保留中间状态 |
| 不同用户隔离 Kernel | zhangsan 与 lisi 即使在同一个 Workspace 也使用不同 Kernel(按 user_id 区分),避免变量互相污染 |
| 空闲回收 | Kernel 空闲超时(如 30 分钟)后自动回收,释放资源 |
| 显式重启 | 支持通过 VSCode 或 IM 指令显式重启 Kernel |
7.6 日志守护进程容灾:紧急直写模式
| 路径 | 触发条件 | 行为 |
|---|---|---|
| 正常路径 | 守护进程存活 | 技能进程通过 HTTP 调用 /api/log 写入日志 |
| 紧急路径 | 守护进程心跳超时(5 秒) | 降级为“紧急直写模式”:写入 /tmp/sdk_<pid>_emergency.log |
| 恢复路径 | 守护进程重启后启动扫描 | 发现残留日志文件 → 合并入主 .ipynb → 删除临时文件 |
保证:At-least-once(至少一次)的日志可靠性。
7.7 YAML 与 DSL 的分层协作
| 层级 | 载体 | 编写者 | 职责 |
|---|---|---|---|
| 意图注册(选配) | skill.yaml |
技能开发者 | 常态默认契约:声明默认执行器、参数映射 |
| 状态存储 | .workspace.md / 内存 ctx |
Runtime 自动维护 | 参数来源的真相源 |
| 人工干预(DSL) | sessions/*.ipynb Code Cell |
运维/开发(运行时) | 本次执行例外:覆盖默认行为 |
| 执行器 | .skills/ 下脚本 / MCP / API |
技能开发者 | 实际执行原子操作 |
契约仲裁器逻辑:
- 检查
.skills/下是否有skill.yaml→ 若有,加载默认配置 - 若无,使用约定(环境变量名/位置参数)
- 检查
sessions/*.ipynb中是否有未执行的#overrideCell - 若有 → 暂停自动执行,等待人工 Shift+Enter 运行,结果覆盖默认
- 若无 → 按默认配置直接执行
7.8 状态抽象模型(State Abstraction Model)
为了统一治理“状态从哪来、怎么刷、多久有效”,每个状态字段被抽象为带元属性的智能指针(Smart Pointer),而非裸值。
状态属性 Schema:
| 属性维度 | 字段 | 示例值 | 说明 |
|---|---|---|---|
| 值类型 | type |
string / number / git_hash / semver |
定义值的格式,用于自动校验 |
| 来源定位 | source |
file(.workspace.md) / mcp(k8s) / ctx(user) |
决定“去哪里取” |
| 刷新策略 | refresh_policy |
event_driven / ttl(5s) / on_demand |
决定“何时更新” |
| 刷新指令 | refresh_cmd |
git rev-parse HEAD / mcp.read('pod.status') |
决定“怎么取最新值” |
| 验证规则 | validator |
regex('^[a-f0-9]{40}$') / range(1,10) |
决定“值是否合法” |
| 陈旧容忍度 | staleness_tolerance |
3s / 10s / infinite |
决定“多老的值可接受” |
实例化示例(在 YAML 或约定中):.
|
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
{ "git.commit": { "type": "git_hash", "source": "file:.workspace.md", "refresh_policy": "event_driven", "refresh_cmd": "git rev-parse HEAD", "validator": "regex('^[a-f0-9]{40}$')", "staleness_tolerance": "3s" }, "k8s.pod_count": { "type": "number", "source": "mcp:k8s", "refresh_policy": "ttl(5s)", "refresh_cmd": "mcp.query('pods', {namespace: ctx.env})", "staleness_tolerance": "5s" } } |
时效性承诺与 TTL 分级策略:
| 参数类型 | 示例 | 建议 TTL | 理由 |
|---|---|---|---|
| 低频静态配置 | 云厂商 Region、K8s 集群名 | ∞(永不刷新) | 除非人工修改 .sandbox.md,否则不变 |
| Git 元数据(基线) | git.commit_hash、git.branch |
≤ 3 秒 | Hook 触发更新,3 秒内收敛完全可接受 |
| 环境运行时(中频) | deploy_status、当前副本数 |
≤ 10 秒 | 滚动更新通常持续数十秒 |
| 敏感依赖(高频锁) | 共享文件夹哈希指纹 | 0 秒(强一致) | 写操作必须基于绝对最新哈希 |
三种状态访问模式:
| 模式 | 适用场景 | AI 写法示例 | Runtime 处理方式 |
|---|---|---|---|
| 引用式(纯数据) | 获取静态或低频状态值 | const count = await context.get('k8s.pod_count') |
检查缓存 TTL,过期则执行 refresh_cmd |
| 组合式(纯逻辑) | 对已有状态进行逻辑运算 | const should = (await get('pods')) > 3 |
完全在脚本本地内存中运行 |
| 扩展式(瞬态计算) | 检查未预定义的实时值 | const err = await context.eval('grep ERROR log |
wc -l') |
重叠责任与刷新仲裁:
| 组件 | 核心职责 | 处理策略 |
|---|---|---|
| MD 文件(状态存储) | 存储“意图”与“历史锚点”,记录“上次成功时的状态” | 不负责“实时”,负责“确定性” |
| 守护进程(Runtime) | “热缓存代理”,将 MD 指针转换为实时值 | 负责刷新仲裁:判断缓存是否过期,若过期则执行 refresh_cmd |
| 执行器(脚本) | “消费者”,只认 Runtime 提供的 ctx 对象 |
不负责“从哪里取”,只负责“用什么值去执行” |
7.9 客户端访问模式(Client Access Modes)
为了最大化兼容存量脚本并降低新技能开发门槛,提供三种从执行器中访问状态的模式。其中,JS 和 Python SDK 通过复用 skykoma 命令实现,仅需 ~80 行封装代码。
被动模式(Passive Mode)—— 旧脚本零改动
| 注入方式 | 示例 | 适用脚本类型 |
|---|---|---|
| 环境变量注入 | $COMMIT_HASH、$WORKSPACE、$BRANCH |
Shell、Python、任何能读环境变量的语言 |
| 位置参数注入 | $1、$2、$3 |
接受命令行参数的脚本 |
主动模式(Active Mode)—— 新脚本推荐
通过轻量级 SDK 主动查询/刷新状态,底层复用 skykoma agent-runtime 命令。
JS/TS SDK 核心实现(约 80 行):
|
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 |
// @skykoma/runtime-sdk/index.ts import { execSync } from 'child_process'; export class RuntimeClient { constructor(private cmd: string = 'skykoma agent-runtime') {} private exec(subCmd: string, ...args: string[]): any { const fullCmd = `${this.cmd} ${subCmd} ${args.join(' ')}`; try { const stdout = execSync(fullCmd, { encoding: 'utf-8', timeout: 5000 }); return JSON.parse(stdout); } catch (err: any) { throw new Error(`Runtime error: ${err.stderr?.toString() || err.message}`); } } get<T>(key: string): T { return this.exec('resolve', key); } commit(key: string, value: any): void { this.exec('commit', key, JSON.stringify(value)); } eval<T>(code: string): T { return this.exec('eval', code); } getCommit(): string { return this.get<string>('git.commit'); } getPodCount(): number { return this.get<number>('k8s.pod_count'); } } export const runtime = new RuntimeClient(); |
Python SDK 核心实现(约 80 行):
|
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 |
# skykoma_runtime_sdk/__init__.py import subprocess import json from typing import TypeVar, Any T = TypeVar('T') class RuntimeClient: def __init__(self, cmd: str = "skykoma agent-runtime"): self.cmd = cmd def _exec(self, sub_cmd: str, *args: str) -> Any: full_cmd = [self.cmd, sub_cmd] + list(args) try: result = subprocess.run( full_cmd, capture_output=True, text=True, timeout=5, check=True ) return json.loads(result.stdout) except subprocess.CalledProcessError as e: raise RuntimeError(f"Runtime error: {e.stderr}") def get(self, key: str) -> Any: return self._exec("resolve", key) def commit(self, key: str, value: Any) -> None: self._exec("commit", key, json.dumps(value)) def eval(self, code: str) -> Any: return self._exec("eval", code) def get_commit(self) -> str: return self.get("git.commit") def get_pod_count(self) -> int: return self.get("k8s.pod_count") runtime = RuntimeClient() |
使用示例:
|
0 1 2 3 4 5 6 7 8 9 10 |
// .skills/deploy/run.js import { runtime } from '@skykoma/runtime-sdk'; const commit = runtime.getCommit(); const pods = runtime.getPodCount(); if (pods > 3) { console.log(`当前 Pod 数 ${pods},触发扩容`); runtime.commit('deploy_status', 'scaled'); } |
三种模式的适用场景对比:
| 模式 | 接入方式 | 改动成本 | 适用场景 |
|---|---|---|---|
| 被动(环境变量) | 无需修改脚本,Runtime 自动注入 | 零改动 | 存量 Shell/Python 脚本,快速迁移 |
| 主动(CLI) | 脚本内调用 skykoma agent-runtime resolve |
低(改状态获取行) | 需要灵活获取多个状态的脚本 |
| 主动(SDK) | import { runtime } from '@skykoma/runtime-sdk' |
极低(加一行 import) | 新开发的 JS/Python 技能,追求开发体验 |
八、 安全执行隔离边界(Security Isolation Boundary)
这是架构从“功能可用”走向“生产级安全”的关键篇章。 通过限制 AI 进程的执行权限、隔离执行环境,确保即使 AI 被提示词注入,也无法对宿主机造成破坏。
8.1 核心安全模型:从“同进程信任”到“零信任执行边界”
旧模型(隐含风险):
Cursor 进程可直接访问 .skills/ 脚本,拥有执行权限。如果 AI 被提示词注入,理论上可以构造恶意 Shell 命令直接在宿主机运行。
新模型(安全加固后):
引入 “执行隔离平面(Execution Isolation Plane)”,将“意图解析”与“物理执行”彻底拆分。
| 层级 | 组件 | 权限与策略 |
|---|---|---|
| 不可信区(Cursor / IDE) | Cursor 进程、工作区代码 |
挂载为 rw,noexec(可读写,但禁止执行任何二进制或脚本) |
| 可信网关(CLI) | skykoma agent-runtime |
仅作为 Intent RPC 客户端。不执行任何业务代码,仅做序列化转发 |
| 可信控制平面(Runtime) | 守护进程(调度器、锁、状态管理) | 运行在独立的命名空间,仅负责路由和参数装配 |
| 可信执行区(隔离执行器) | 实际的 .skills/ 脚本运行环境 |
物理或虚拟隔离(独立容器 Pod、Firecracker microVM,或物理机) |
8.2 文件系统强制策略
Workspace 目录挂载要求:
| 挂载点 | 权限 | 说明 |
|---|---|---|
/path/to/workspace/ |
rw,noexec,nosuid,nodev |
工作区代码目录:可读写,但禁止执行任何二进制文件或脚本 |
/tmp/runtime-exec/ |
rw,exec |
Runtime 专属临时执行目录,对 Cursor 进程不可见,仅 Runtime 可访问 |
关键实现:
noexec确保 Cursor 进程无法直接执行.skills/下的任何脚本(即使文件有+x权限)。- 执行器脚本由 Runtime 复制到
/tmp/runtime-exec/目录下执行,该目录对 Cursor 进程完全不可见(通过chmod 700+ 非$PATH实现)。
8.3 CLI 最小权限设计:skykoma 作为 Intent Proxy
skykoma agent-runtime 的定位发生本质变化:
- 旧定位:开发人员手动调试用的命令行工具。
- 新定位(安全加固后):Cursor 进程在该
noexec目录下,与外界通信的唯一合法通道(Gatekeeper Client)。
安全约束清单:
| 约束 | 说明 |
|---|---|
| 纯 Intent 代理 | 仅支持 resolve、commit、eval 三个子命令,绝对不支持任意 Shell 命令透传 |
| 静态编译 | skykoma 二进制必须静态编译(Golang/Rust),放置在 /usr/local/bin(系统级 exec 路径),不依赖 项目目录下的任何动态库或脚本 |
| 无本地脚本执行 | skykoma 本身不调用 execve 执行任何用户脚本,仅发起 HTTP/gRPC 请求到 Runtime 守护进程 |
| 超时与限流 | 所有 skykoma 请求强制带 5 秒超时,防止恶意构造的 eval 代码无限循环 |
8.4 执行器位置透明度(Location Transparency)
架构对外暴露统一的 runtime.execute(intent) API,底层屏蔽“本地 Docker”与“远程 K8s Job”的差异。
执行模式切换:
| 执行模式 | 适用场景 | 隔离级别 |
|---|---|---|
| 本地 Docker 模式 | 开发/测试环境 | 进程级隔离(Docker 容器) |
| 远程 K8s Job 模式 | 生产环境(默认) | 物理节点隔离(Job Pod 独立调度) |
| Firecracker microVM 模式 | 高安全级生产环境 | 硬件虚拟化隔离(轻量级 VM) |
任务打包与分发:
- Runtime 将 Intent 和状态快照(
.workspace.md指针)打包成一个 “执行任务(Execution Task)”。 - 通过 gRPC 或消息队列(如 NATS)分发给远端独立的 “沙箱集群”。
- 执行器运行完毕后,仅将结果(
status、logs)回传,执行器所在的磁盘在任务结束后直接销毁。
架构红利:
- 数据不落地:敏感密钥仅在 Runtime 内存中拼接,物理隔离的执行器只拿到临时生成的只读环境变量。
- 资源隔离:即使 AI 写的脚本产生死循环或内存泄露,也只会拖垮那个临时的 Job Pod,Runtime 主进程和 Cursor 界面永远丝滑。
8.5 安全事件响应流程
| 事件类型 | 检测机制 | 响应动作 |
|---|---|---|
恶意 eval 代码执行超时 |
skykoma 5 秒超时 + Runtime eval 沙箱 1 秒超时 |
强制终止,记录审计日志,禁止该 Agent 后续请求 5 分钟 |
| 意图注入(疑似提示词攻击) | GateKeeper 校验 Intent 参数白名单 | 拒绝执行,返回 403 Forbidden,触发告警 |
| 执行器容器逃逸尝试 | 容器运行在非特权模式 + Seccomp 限制 | 自动销毁容器,物理节点隔离,安全团队介入 |
恶意脚本修改 .workspace.md |
状态文件写入校验 + 哈希指纹对比 | 拒绝写入,回滚到上一个合法快照 |
九、 新旧共存与平滑迁移路线图
| 阶段 | 时间线 | 核心动作 | 系统状态 |
|---|---|---|---|
| Phase 1:观察者 | 第 1-2 周 | Runtime 仅做“观察者”,旁路监听旧脚本日志,解析成 Intent 存入 MD | 旧脚本照跑,只记录不接管 |
| Phase 2:自动发现 | 第 3-4 周 | 将旧脚本复制或软链接到 .skills/,零改动接入参数自动注入 |
新旧并存,通过标签切换 |
| Phase 3:安全隔离 | 第 2 月 | 启用 noexec 挂载 + skykoma Intent Proxy 模式 |
所有执行通过隔离平面进行 |
| Phase 4:灰度迁移 | 第 2-3 月 | 高频脚本逐步重写为 JS Native 执行器,调高新版本权重 | 旧脚本降为冷备 |
| Phase 5:远程隔离 | 第 3-4 月 | 启用远程 K8s Job / Firecracker 执行模式 | 物理隔离生产环境 |
| Phase 6:原生主导 | 长期 | 默认所有 Intent 走新执行器 | 旧脚本通过 legacy: true 保留 |
十、 架构综合评价
核心优势
- 零门槛接入:脚本放入
.skills/即完成接入,无需学习新 DSL 或写 YAML - 降本增效:Agent 上下文缩减 70%~90%(长指令变短 Intent)
- 确定性:执行逻辑锁死在本地执行器中,部署版本永远锚定 Git Commit
- 企业级安全:门禁前置 + 作用域环境隔离 + 数据库黑盒 + noexec 物理隔离
- 资产保护:旧脚本软链接即可享受新架构红利
- 高并发治理:三级锁 + 内存队列,多 Agent 并发井然有序
- 可审计:完整审计链,满足 ISO/等保合规
- AI 友好:状态抽象模型让 AI 能写出等价于裸脚本的判断逻辑,同时杜绝底层 API 幻觉
客观代价
- 前期需搭建守护进程(Daemon)、定义状态文件规范
- 相比单脚本增加了架构复杂度
- 安全隔离模式需额外配置 noexec 挂载和远程执行集群
- 团队需理解“Agent 有状态、产物有状态”这一核心前提
十一、 适用边界声明
| 场景类型 | 适用性 | 原因 |
|---|---|---|
| 多云/多环境 + 多 Agent 并行 | ✅ 强适用 | 核心优势充分体现 |
| 强合规审计(金融/医疗) | ✅ 强适用 | 审计日志完整、门禁前置、安全隔离 |
| 混合团队(运维+开发+AI) | ✅ 适用 | 降低沟通成本,IM 入口友好 |
| 单机单 Agent 个人项目 | ❌ 不适用 | 架构复杂度高于收益,Shell 脚本更高效 |
| 低频任务(每周 ≤1 次) | ⚠️ 谨慎评估 | 维护成本可能超过手动操作收益 |
| 无 Git 工作流的纯静态环境 | ⚠️ 谨慎评估 | 状态锚定依赖 Git 版本管理 |
| 安全敏感生产环境 | ✅ 强适用 | 物理隔离 + noexec 提供多重防护 |
十二、 总结与下一步行动建议
这套架构通过 “Agent 有状态、产物有状态” 的第一性原则,结合约定优于配置、上下文感知路由、四层状态文件、状态抽象模型、安全执行隔离边界五位一体的实现,从根本上解决了异构基础设施对 AI 的侵蚀问题,实现了:
入口极轻、路由极稳、执行极活、状态极清、审计极全、AI 极自由、安全极硬
下一步行动建议(按优先级排序):
- 优先实现:Runtime 守护进程的 “自动发现器(Auto-Discoverer)” 与 “状态感知参数注入器(State-Aware Injector)”。一旦跑通,现有脚本即可零改动接入。
- 次优先实现:JS/TS SDK 封装(复用
skykoma命令),让新技能开发者获得import { runtime }的一行代码开发体验。 - 第三优先实现:noexec 挂载 + skykoma Intent Proxy 模式,将安全隔离落地为强制要求。
- 长期规划:远程 K8s Job / Firecracker 执行模式,实现物理级别执行隔离。
附录:总体逻辑分层架构图(Mermaid)
此图对应白皮书第五章“总体逻辑分层架构”的可视化表达,已整合安全隔离边界。
|
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 |
flowchart TB subgraph 入口与身份层 [Entry & Identity Layer] IM[企业IM @机器人<br>群聊上下文] SDK[Cursor/OpenCode SDK] VSCode[VSCode 仪表盘] end subgraph 不可信区 [Untrusted Zone - Cursor 进程空间] WorkspaceDir[工作区目录<br>挂载: rw,noexec] SkillsDir[.skills/ 脚本<br>不可执行] skykomaCLI[skykoma agent-runtime<br>唯一合法 Intent 通道] end subgraph 可信控制平面 [Trusted Control Plane] subgraph 适配与状态注入层 [Adapter & State Injection Layer] Parser[意图解析器<br>提取 Bot/User/群聊 ID] ContextResolver[上下文决议器<br>群聊 → Workspace 映射] StateReader[状态读取器<br>从 .workspace.md 读取状态] EnvInjector[环境注入器<br>状态 → 参数装配] end subgraph 运行时核心层 [Runtime Core - 有状态仲裁者] AutoDiscover[自动发现器<br>扫描 .skills/] Router[意图路由器<br>Intent → 执行器] GateKeeper[门禁调度器<br>Auth Hook 前置校验] LockMgr[并发锁管理器<br>三级锁] StateMgr[状态管理器<br>四层状态文件] ContractArbiter[契约仲裁器<br>YAML vs IPYNB] end end subgraph 可信执行区 [Trusted Execution Zone - 物理/逻辑隔离] direction LR LocalDocker[本地 Docker 容器<br>进程级隔离] K8sJob[远程 K8s Job<br>物理节点隔离] Firecracker[Firecracker microVM<br>硬件虚拟化] ExecutorPool[执行器实例池] end subgraph 状态存储与审计层 [State Storage & Audit Layer] MCP[MCP / CLI / API] Infra[K8s / Jira / Git] Database[(数据库)] subgraph 四层状态文件模型 [四层状态文件模型] SandboxFile[.sandbox.md] SharedFile[.shared_state.md] WorkspaceFile[.workspace.md] Sessions[(sessions/*.md)] Logs[(logs/*.ipynb)] end end IM --> Parser --> ContextResolver --> StateReader --> EnvInjector SDK --> EnvInjector EnvInjector -->|注入 ctx + 状态参数| Router WorkspaceDir -->|只能通过| skykomaCLI skykomaCLI -->|Intent RPC| Router Router --> AutoDiscover AutoDiscover -->|扫描 .skills/ 元数据| Router Router --> ContractArbiter ContractArbiter -->|检查 #override| Logs Router --> GateKeeper GateKeeper -->|强制校验| AuthAPI[执行器自带权限服务] GateKeeper --> LockMgr LockMgr --> StateMgr StateMgr --> WorkspaceFile StateMgr --> SharedFile StateMgr --> SandboxFile StateMgr --> Sessions StateMgr --> Logs Router -->|提交执行任务| ExecutorPool ExecutorPool --> LocalDocker & K8sJob & Firecracker LocalDocker & K8sJob & Firecracker --> MCP & Infra & Database LocalDocker & K8sJob & Firecracker -->|回写状态| StateMgr LocalDocker & K8sJob & Firecracker -->|审计日志| Logs |
白皮书版本:最终完整版 | 涵盖全部 12 章(含新增“安全执行隔离边界”)+ 附录
