Agent 平台
Agent 平台
Agent 平台 是 Bolt 拥有的循环与 UI,用于 Agentic 工作负载。它执行 Agent 循环——多步推理、工具调用与子 Agent——工作区在 Agents 下编写这些配置。Colony 把每次循环调用准入一个一次性工作线程;模型与工具等待在同一次调用内恢复,等待期间槽位保持分配,但只计量实际使用的工作线程 CPU。Colony 还提供工作区选择加入的可信宿主工具。
@norbital-ai/bolt 交付。Colony 是托管宿主:它绑定 ai ,准入每次循环迭代、计量用量,并提供可信宿主工具。一个循环,两道门
每次交互式对话——网页聊天或一条 envoy 消息——都经过同一个 Agent 循环,其共享系统提示是工作区的 `src/+agents.md`。不同的是它从哪道门进来:Agent 充当谁,以及适用哪些指令与工具。自动化是另一回事:确定性 handler,需要模型判断时调用 `api.infer`;不会派生 Agent 会话。
web chat (signed-in user) Telegram / WhatsApp
│ │
▼ ▼
persist + admit persist + admit
│ │
└──────────────┬───────────────┘
▼
┌──────────────────────── Bolt agent loop ────────────────────────┐
│ each invocation uses one one-shot worker and capacity slot │
│ await infer yields; host I/O is not worker CPU, then the same │
│ invocation resumes; the worker and slot remain assigned │
│ │
│ tools: read_collection · write_collection · workspace tools │
│ skills (list_skills · read_skill) · host tools (opt-in) │
└───────────────┬───────────────────────┬───────────────────────────┘
│ │
▼ ▼
tenant database host AI binding
(chat_session (inference between
aggregate) worker yields) 谁可以使用 Agent
- Pro ——Agent 加工作区工作室编写
- 标准 ——无 Agent 或沙箱访问
AI 用量与工作区基础费用分开按量计费。参见 定价 。
权限模型
核心规则: 权限界定了 Agent,而不是它的工具列表。
Agent 进行的每次数据读取与写入——通过 read_collection 与 write_collection ——都非提权运行:与应用操作者亲自点击界面时相同的策略、钩子与审批门适用。Agent 是同一套控件上更快的手,从来不是更宽的权限集。
| 入口 | Agent 充当 | 受什么约束 |
|---|---|---|
| 网页聊天 | 登录用户 | 该用户的权限 |
| Enovy 消息 | Envoy 自己的 Agent 身份 | Envoy 声明的策略 |
配置 Agent:src/+agents.md
工作区的共享系统提示就是工作区根目录的 src/+agents.md 。它是每一轮 Agent 对话的系统消息,网页与 envoy 一视同仁:集合意味着什么、公司做什么、语气与升级的规则。Envoy 的 `task` 是叠加在其上的各自常驻指令。
# src/+agents.md
You are the agent of the operations workspace. Ground every answer in
the data. Report figures in MYR. Never guess — say so when data is
missing.
编写界面——envoy、技能与工具——属于工作区源码;本页讲循环、漏斗与宿主工具。
Envoy:别人线路上的 Agent
Envoy 是经由 Telegram 或 WhatsApp 触及的 Agent——与一个工作区可能没有用户行的人的对话。传输本身保持由宿主提供:工作区在源码中声明 envoy,Colony 拥有凭据与 socket。完整声明约定见 Envoy 。
// src/envoys/+sales_desk.ts
export default {
transport: 'telegram',
audience: 'public',
policies: ['sales_rep'],
groupMessages: 'disabled',
task: 'Answer order and quotation questions for the sales desk.'
} satisfies Envoy;
transport——触及它的线路(telegram或whatsapp),运行时按传输的身份规范化处理。policies——Envoy 行事所用的策略。Envoy 可能面向群聊,所以没有单一的个人可继承权限;运行以 envoy 自己的主体行事。其策略没有任何授权的 envoy 什么也做不了。task——Envoy 的常驻指令,叠加在工作区的 `src/+agents.md` 之上。
sandbox_bash 以彻底拒绝委派。Envoy 所能触及的一切就是其点名策略所授予的——从不多。Agent 工具
Agent 始终拥有 Bolt 的内置工具:
describe_workspace——工作区包含什么read_collection——读取应用主体的策略grantswrite_collection——仅在策略授予 create/update/delete、以及create/update/deletelist_skills/read_skill——文档的渐进式披露(参见 技能 )spawn_subagent——不能再派生子对话的子对话
工作区编写自己的工具——一个 Agent 可以调用的类型化函数,经由与钩子相同的作用域 API 运行,因此策略与字段掩码仍然生效:
// src/capabilities/tools/+product_lookup.ts
import { defineAgentTool } from '@norbital-ai/bolt/authoring';
import { Effect, Schema } from 'effect';
export default defineAgentTool({
description: 'Returns one product by id, with its current stock level.',
input: Schema.Struct({ productId: Schema.String }),
run: (api, { productId }) =>
Effect.gen(function* () {
const product = yield* api.db.query.products.findFirst({
where: { id: { eq: productId } }
});
return product ?? null;
})
});
工具文件按名称发现—— +<lower_snake_case>.ts ——位于 src/capabilities/tools/ 下。内置名称是保留的:一个叫 read_collection 的工作区工具是编译错误。
更多工具
工具面不断扩展。共分三层:
- 内置工具 ——每个 bolt 随附,始终可用
- 自定义工具 ——用 defineAgentTool 声明的工作区工具
- 宿主工具 ——带宿主凭据的可信操作。需要沙箱的工具在绑定沙箱时由漏斗提供;其余选择加入
工具漏斗
每个能调用工具的模型都经过同一条装配路径。两条表面进入它:
agent——交互式聊天、envoy、子 Agent。拥有 chat_session 转录。infer——钩子、自动化、远程中的 api.infer。仅短暂消息;从无转录。只读:没有 write_collection、编写、沙箱、MCP 或 spawn_subagent。
一轮对话可调用的内容,按顺序:
- 平台只读内置——describe_workspace、read_collection、list_skills、read_skill。read_collection 逐行应用主体持有的读授权。
- 平台写入——write_collection,仅当主体对该集合持有 create/update/delete 授权时提供;审批门与字段掩码与应用里完全一致。
- 平台协调——spawn_subagent,每个回合对根会话提供一次;子 Agent 不能再派生。
- 工作区工具与 MCP 服务器——来自主体所持策略的 `capabilities.tools` 与 `capabilities.mcp`,从不来自单独的允许列表。
- 技能——来自 `capabilities.skills`,与工具一样授予;其下才是回合绑定沙箱时的沙箱宿主工具,然后是宿主提供的其余宿主工具。
`api.infer` 不提供任何工具——没有 write_collection、没有编写、没有沙箱、没有 MCP、没有 spawn_subagent。
宿主工具
宿主工具是在宿主进程中以宿主凭据运行的可信操作——绝不在租户代码中运行。在 Colony 上它们是沙箱编码与部署工具,充当租户的构建者主体。需要沙箱的工具由漏斗在绑定沙箱时提供,而不是把它们写进 hostTools 。其余宿主工具仍须显式点名;该列表在启动时对照宿主的清单检查,列出但未提供的工具会拒绝工作区启动。
WhatsApp、网页以及每一个其他 Agent 配置在绑定沙箱时都会获得沙箱工具。denyTools 对工作区工具与平台内置工具是类型安全的;在那里点名 sandbox_* 工具是错误。
技能:Agent 按需阅读的文档
技能是 Agent 在需要时才加载的 markdown 文档,而不是在每次提示中携带全部说明。一个技能是 `src/capabilities/skills/` 下的一个目录,其中带 SKILL.md (名称与描述 frontmatter)加可选参考文件:
src/capabilities/skills/
└── approvals/
├── +skill.md # what the agent needs to know about approvals
└── references/
└── policy-matrix.md
Agent 调用 list_skills 查看存在什么,然后调用 read_skill 加载正文或一个参考文件。Bolt 随附 norbital-platform 与 authoring-tenant-workspace ;遮蔽随附名称的工作区技能在编译时被拒绝,因此平台自己对审批如何工作的叙述永远无法被替换。
起草,绝不发布
当 Agent 帮助做结构性变更时,工作停留在 编辑源码区 。构建者仍然手动同步预览并上线——Agent 永远无法发布到生产,工作区工作室的发布控件仅限构建者。Agent 遵守同样的边界。
对话即数据
每次 Agent 对话都是租户数据库中的一个聚合( chat_session ),其中包含顺序消息、嵌套轮次、标题、状态和用量。一个普通同步订阅将每次变更送到 Agent UI;聚合由请求人拥有并按策略界定。Agent 无法绕过审批门、记录锁或脱敏,每轮对话后用量都会上报给计费。
示例提示
- “显示本周创建并标记为紧急的所有项目。”
- “Suppliers 集合上有哪些字段?”
- “带我去薪资审批设置。”
- “总结分配给我团队的未完成任务。”
最佳实践
- 在提示中使用精确的集合、团队与应用名称。
- 编写工作区根目录的
task——共享系统消息,Agent 的世界观所在。src/+agent.ts - 为 Agent 必须遵循的领域规则添加工作区技能;Agent 在它们重要时阅读它们。
- 即使源码是 Agent 编写的,也要在同步与上线前审查草稿源码。
- Agent 访问已包含在工作区基础费用中;使用的 AI 按量计费。