SwarmWright

文档 · 构建智能体群

快速启动

SwarmWright 以单一 Docker 容器运行。无需外部基础设施 —— 无需消息代理、无需独立数据库服务器、无需构建流水线。一条命令即可启动运行。

docker run -d \
  --network=host \
  --name swarmwright \
  -v ./data:/data \
  -e LLM_PROVIDER=anthropic \
  -e LLM_MODEL=claude-opus-4-7 \
  -e ANTHROPIC_API_KEY=sk-ant-... \
  ralphbarendse/swarmwright:latest

或使用 Docker Compose —— 从代码仓库获取 docker/docker-compose.yml.env.example

cp .env.example .env
# 配置 LLM_PROVIDER、LLM_MODEL 和你的 API 密钥

docker compose -f docker/docker-compose.yml up -d

GUI 界面访问地址:http://localhost:5001。 API 访问地址:http://localhost:5001/api/v1/health

说明:全新的 docker compose up 无需手动配置密钥即可运行。 加密密钥在首次启动时自动生成并持久化到 data/.encryption_key。 请将此文件与 data/swarm.db 一起备份。

系统要求

环境变量

变量名必填默认值说明
LLM_PROVIDERanthropicanthropic、openai 或 deepseek
LLM_MODELclaude-opus-4-6模型标识符字符串
ANTHROPIC_API_KEY使用 anthropic 时Anthropic API 密钥
OPENAI_API_KEY使用 openai 时OpenAI API 密钥
DEEPSEEK_API_KEY使用 deepseek 时Deepseek API 密钥
SWARM_ENCRYPTION_KEY可选自动生成32 字节 base64 Fernet 密钥。未设置时在首次启动时自动生成。
DATABASE_URLsqlite:////data/swarm.dbSQLAlchemy 数据库 URL
DATA_DIR/data数据卷挂载路径
LOG_LEVELINFODEBUG / INFO / WARNING / ERROR
SCHEDULER_TIMEZONEEurope/AmsterdamAPScheduler 心跳触发器的时区设置

加密密钥

LLM 凭据和机密信息使用 Fernet 对称加密静态加密。 主密钥在每次启动时按以下顺序解析:

  1. SWARM_ENCRYPTION_KEY 环境变量 —— 设置时优先使用
  2. <DATA_DIR>/.encryption_key 文件 —— 由容器自动管理
  3. 如果两者均不存在,则生成新密钥并写入文件

对于高安全要求的部署,建议在外部生成密钥并固定使用:

python -c "from cryptography.fernet import Fernet; print(Fernet.generate_key().decode())"

核心概念

SwarmWright 将工作组织在三个嵌套作用域中:公司(Company)工作区(Workspace)群组(Swarm)。工作区是类似部门的容器(财务、运营、HR)。 群组是一组协作处理某类工作的智能体集合。

每个群组由两个核心文件定义:

运行时严格执行 hierarchy.json。如果某个智能体试图调用 未在拓扑中声明的其他智能体、工具或感知者,该操作将被阻止并记录为 拓扑违规(topology violation)。此执行机制无法被绕过。

核心理念:你在画布上绘制的图表配置本身。不存在需要单独维护同步的规范文件。如果连接存在于画布上,它就在 hierarchy.json 中,并在运行时被强制执行。

智能体层级

共有四个层级,不多不少。每个智能体恰好属于一个层级,在其宪章中声明。

层级颜色职责典型任务
策略层(Policy) 深蓝 #1e3a5f 战略决策、治理、最终权威 制定规则、批准例外、处理上报、单一责任节点
编排者(Orchestrator) 青色 #2a6b6b 协调、路由、工作流管理 接收事件、决定调用哪个执行者、汇总结果、路由到下一步
执行者(Executioner) 石板蓝 #3d4f7c 任务执行、工具使用、外部操作 调用技能、写入数据库、调用 API、处理文件、生成产出物
感知者(Perceptionist) 琥珀色 #c97c2a 只读感知 —— 将现实映射为内部数据 读取传感器、分类输入、提取结构化数据,从不写入或采取行动

层级体系通过约定而非运行时机制来执行。感知者与其他智能体一样 —— 其区别在宪章中声明,并在拓扑图中清晰可见。 UI 通过颜色编码使结构一目了然。

拓扑结构

拓扑结构是 hierarchy.json 中声明的图。它列出了群组可以使用的 每一个智能体、每一条连接边、每一个技能、每一个人工节点和每一个感知者。 运行时强制执行这些声明 —— 智能体不能调用未列出的任何内容。

连接类型

两个智能体之间的每条连接使用以下类型之一:

用途说明是必填项。每条连接都需要一个非空的 purpose(用途)字符串,用通俗语言写成。这在验证时强制执行。这种阻力是故意设计的 —— 如果你无法说明一条连接为何存在,就不应该添加它。

拓扑违规

当运行中的智能体试图调用其声明连接中未列出的其他智能体、工具或感知者时, 运行时将阻止该调用并生成一条 topology_violation 运行步骤记录。 如果可能,运行继续进行;违规情况会在控制室的步骤追踪和画布上的实时流状态栏中上报。

人机协作

SwarmWright 对工作流中任意位置的人工参与提供一等支持。 两种节点类型代表群组拓扑中的人工角色:调用者(Caller)通知者(Informer)。 两者都像智能体一样放置在画布上,并使用相同的拖拽连接机制进行连接。

调用者节点

调用者是一个阻塞式人工门控。当工作流到达调用者时,执行暂停, 并在收件箱中创建一个人工操作请求。运行在 awaiting_human(等待人工) 状态下暂停,直到人工以决策(yesno 或修改后的指令)响应。 之后工作流才继续进行。

适用场景:

在画布上,调用者节点显示举手图标(✋),并以鼠尾草绿色样式与智能体节点区分。 从智能体的连接把手拖拽到调用者节点即可建立连接,连接模态框会要求填写 purpose(用途)。

通知者节点

通知者是一个非阻塞式通知。当工作流到达通知者时, 向收件箱发送消息,工作流立即继续,无需等待。 通知者适用于进度更新、警报和人工应该知晓但无需处理的 FYI 通知。

在画布上,通知者节点显示扩音器图标(📢)。

连接人工节点

人工节点(调用者和通知者)首先放置在画布上,然后使用与智能体间连接相同的 连接绘制机制与智能体进行连接:

  1. 将调用者或通知者从调色板拖拽到画布上
  2. 选择智能体节点打开检查器
  3. 点击连接到…进入连接模式
  4. 点击要连接的人工节点
  5. 在弹出的模态框中填写连接用途
  6. 保存 —— 连接被写入 hierarchy.json

多个智能体可以连接到同一个调用者或通知者。 节点在画布上保持独立 —— 不"归属"于任何单一智能体。

收件箱交互

收件箱标签页显示两类内容:

历史决策显示在已批准已拒绝标签页下, 附带完整上下文,用于审计目的。

资源作用域

知识文档和技能存在于以下四个作用域之一。 引用按最近优先原则解析:群组 → 工作区 → 公司 → 内置。

群组作用域    →  data/workspaces/<wid>/swarms/<sid>/<type>/
工作区作用域  →  data/workspaces/<wid>/<type>/
公司作用域    →  data/company/<type>/
内置作用域    →  app/builtin_skills/  (只读,平台提供)
宪章中的引用解析到
approval-thresholds最近匹配:群组 → 工作区 → 公司
workspace/finance-procedures仅限工作区作用域
company/glossary仅限公司作用域
write_swarm_file未被其他作用域覆盖时解析为内置

公司级策略附加到所有智能体;部门级流程对该工作区的所有智能体可用; 群组特定上下文仅对单一工作流保密。 内置作用域是技能的最终回退 —— 它是只读的,不可编辑, 但任何内置技能都可以通过在其他作用域创建同名技能来覆盖。

宪章

宪章是一个带有 YAML 前置元数据的 .md 文件,定义了智能体 是什么 —— 其身份、价值观、角色以及可访问的知识。 它声明连接。连接保存在 hierarchy.json 中。

宪章在智能体运行时作为系统提示词的一部分逐字传递。 编写一份好的宪章是提升智能体质量最有影响力的单一操作。

---
name: Finance Orchestrator
layer: orchestrator
model: claude-opus-4-6
provider: anthropic
knowledge:
  - approval-thresholds
  - workspace/finance-procedures
---

You coordinate invoice intake for the Finance workspace.
Route incoming invoices to the appropriate Executioner agent
based on value, vendor, and approval requirements.

Never approve invoices directly. Escalate ambiguous cases
to the Policy layer with full context.

When routing, always state which agent you are delegating to
and why, so the decision is traceable.

允许的前置元数据字段:

字段类型说明
name字符串UI 中显示的名称
layer字符串policy / orchestrator / executioner / perceptionist
model字符串模型标识符。设置后覆盖群组默认值。
provider字符串模型服务商(anthropic / openai / deepseek)。设置后覆盖默认服务商。
knowledge列表知识文档引用列表(可带作用域前缀或直接使用名称)

连接字段(skillsedges)属于 hierarchy.json, 而非宪章。将身份与拓扑分离意味着你可以更改智能体知道什么 而无需触及它连接什么,反之亦然。

技能

技能是可由执行者智能体调用的沙箱化 Python 脚本。每个技能由两个同名文件组成:

技能在子进程中运行,永不在 Flask 进程中运行。出错的技能不会导致宿主崩溃。 允许的包在注册时强制执行 —— 如果某个包不在 allowed_packages 中, 导入将在技能启动时失败。

# parse-invoice.yaml
input_schema:
  type: object
  properties:
    text: { type: string }
  required: [text]
output_schema:
  type: object
  properties:
    vendor: { type: string }
    amount: { type: number }
    currency: { type: string }
allowed_packages: [re, json]
timeout_seconds: 10
# parse-invoice.py
import re, json

def run(input: dict, context: dict) -> dict:
    text = input["text"]
    # ... 提取逻辑 ...
    return {"vendor": vendor, "amount": amount, "currency": currency}

技能可以在公司、工作区或群组级别设置作用域。公司作用域的技能对所有群组中的所有智能体可用。 技能在资源库标签页中列出,并通过拓扑画布附加到智能体上。

内置技能

SwarmWright 在内置作用域提供 10 个平台预设技能,随时对任何智能体可用, 无需额外配置,显示在资源库 → 技能 → 内置下的只读卡片中。 无需 allowed_packages —— 它们仅使用 Python 标准库。

要覆盖内置技能,在群组、工作区或公司作用域创建同名技能即可。 解析器会优先找到你的版本。

文件存储

运行时会将 context["files_root"](当前群组 files/ 目录的路径)注入到每次技能调用中。拒绝越过此根目录的路径遍历操作。

技能说明主要输入返回值
write_swarm_file 将文件写入 files/,自动创建父目录。 pathcontentencoding(utf-8 / base64) pathsize_byteschecksum(SHA-256)
read_swarm_file files/ 读取文件。 pathencoding(utf-8 / base64) contentencodingsize_bytes
list_swarm_files 列出 files/ 中的文件,可按路径前缀过滤。 prefix(可选) files[] —— path、filename、size_bytes、modified_at
delete_swarm_file 删除文件。文件不存在时静默成功。 path deleted(bool)、path

HTTP

技能说明主要输入返回值
http_get 执行 HTTP GET 请求,超时 30 秒。 urlheaders(可选)、as_json(bool) statusheadersbodyjson(当 as_json=true 时)
http_post 执行带 JSON 正文的 HTTP POST,自动设置 Content-Type: application/json urlbody(对象)、headers(可选)、as_json(bool) statusheadersbodyjson(当 as_json=true 时)

键值存储

基于群组 files/ 目录中 _kv_store.json 的持久化存储。值在运行间持久保存,可存储任何 JSON 可序列化类型。

技能说明主要输入返回值
kv_get 按键检索值。 keydefault(可选回退值) keyvaluefound(bool)
kv_set 按键存储值,原子写入 —— 在并发运行下安全。 keyvalue(任意 JSON 类型) keyvalue

工具类

技能说明主要输入返回值
get_datetime 返回当前 UTC 日期和时间,适用于调度逻辑或给输出加时间戳。 utc_isounix_timestampdatetimeweekdayyearmonthdayhourminute

通知

技能说明主要输入返回值
send_webhook 向任意 Webhook URL POST JSON 负载,兼容 Slack、Discord、Teams 或自定义端点。 urlpayload(对象)、headers(可选) statusbodyok(2xx 时为 true)

触发器

触发器是确定性脚本 —— 不是智能体。它们产生进入群组的事件。 触发器内不进行 LLM 调用。使用正则表达式、JSON Schema、JSONPath 和标准 Python 库。保持简单。它们的职责是检测和路由,而不是思考。

四种触发器类型:

类型触发时机配置
心跳(Heartbeat) 通过 APScheduler 按 cron 调度触发 cron 表达式、payload 模板
监听器(Listener) 外部 Webhook / 传入消息到达监听器端点 path、可选 filter JSONPath 表达式
调用(Invocation) 通过 POST /api/v1/triggers/invocations/<id> 或控制室的触发按钮手动触发 用于验证的 payload_schema
文件监视器(File Watcher) 群组 files/ 目录中匹配 glob 模式的文件被创建或修改 glob 模式(如 reports/*.csv)、可选 events 列表(createdmodified

触发器在群组画布检查器中创建和管理。每个触发器可以单独启用或禁用而无需删除。 控制室的触发按钮可以直接向群组发送原始事件,绕过触发器 —— 适用于测试。

群组文件

每个群组在磁盘上都有一个持久化的 files/ 目录。智能体和人类都可以对其进行读写。 文件在数据库中建立索引,记录完整的来源信息 —— 每个文件的创建者(智能体、人类或未知)、 产生它的运行和步骤,以及最后修改时间。

这个共享文件系统充当运行之间的持久化交接层:一个智能体可以在某次运行中向 files/reports/ 写入 CSV,而人类可以从画布下载它, 同时另一次运行正在处理下一批数据。

智能体如何写入文件

智能体使用内置的 write_swarm_file 技能。运行时将 files_root 路径注入到每次技能调用的 context 字典中, 使技能知道写入位置而无需访问数据库。支持无限深度的子目录嵌套 —— 智能体可以将文件组织到任意所需的文件夹结构中。

# write_swarm_file 输入
{
  "path": "reports/2024-06/summary.md",
  "content": "# June Summary\n...",
  "encoding": "utf-8"
}

每次技能调用后,运行时会对文件索引进行协调:新文件以 origin=agent 插入; 已删除的文件从索引中移除。

人类如何管理文件

群组画布在检查器下方有一个文件面板。在此可以:

人工上传的文件以 origin=human 建立索引。每行上的彩色圆点 指示来源:强调色表示智能体写入,灰色表示人工上传。

文件监视器触发器

文件监视器触发器使用 glob 模式监视群组的 files/ 目录。 当匹配的文件被创建或修改时 —— 无论是智能体、人工上传还是写入挂载卷的外部进程 —— 触发器都会向群组发送一个调用事件。 这使基于文件到达的工作流成为可能:将 PDF 放入 files/inbox/, 群组即自动开始处理。

索引协调

每次群组加载时,SwarmWright 会将磁盘上 files/ 的内容与数据库索引进行协调。 磁盘上存在但索引中缺失的文件以 origin=unknown 插入。 索引中指向磁盘上不再存在的文件的行被移除。 这意味着即使在手动文件系统操作(备份恢复、外部写入、直接卷挂载)之后, 索引也能保持准确。

跨群组委托

任何智能体都可以将另一个群组作为同步阻塞式子调用来调用 —— 类似于调用不同部门的函数。调用智能体发送输入负载, 目标群组运行完成,然后将结果内联返回。父群组中的执行暂停,直到子群组完成。

这与向另一个群组发送事件不同。群组调用具有以下特点:

配置群组调用

  1. 打开调用方群组的画布
  2. 点击左侧调色板中的外部群组 —— 弹出模态框列出所有工作区的所有群组
  3. 选择目标群组并点击添加到画布 —— 出现一个青色 ⬡ 节点
  4. 选择智能体节点并点击连接到…,然后点击 ⬡ 群组节点
  5. 在模态框中:输入别名(智能体在操作中使用的简短标识符)和用途
  6. 保存 —— 连接以 swarm_calls 条目形式写入 hierarchy.json

别名命名:使用简短有意义的标识符 —— hr_lookupcredit_checkcompliance_scan。别名是智能体在 invoke_swarm 操作中写入的内容。不能包含空格。

智能体如何调用群组

当智能体声明了群组调用时,运行时会自动将其添加到系统提示词中。 智能体使用 invoke_swarm 操作调用目标:

{
  "action": "invoke_swarm",
  "alias": "hr_lookup",
  "input": {
    "employee_id": "EMP-4821",
    "query": "Is this employee currently active?"
  }
}

运行时将别名解析为目标群组的入口点,创建一个与父运行共享运行 ID 和步骤序列的子执行上下文, 运行目标群组,并将最终输出作为操作结果返回给调用智能体。 子群组的步骤显示在控制室的同一运行追踪中。

跨工作区委托

群组调用可以针对任意工作区的群组,而不仅限于当前工作区。 这使跨部门工作流成为可能 —— 财务群组可以查询 HR 群组,运营群组可以触发合规群组,等等。 目标群组无需知道自己被另一个工作区的群组调用。

在画布上,跨工作区群组节点以琥珀色(而非青色)样式显示, 并带有↗ 跨工作区标签。这是一个刻意的视觉警告: 跨工作区调用会在部门之间引入依赖关系。如果目标群组被禁用、重命名或删除, 调用方群组将在运行时失败。

设计建议:跨工作区调用功能强大,但应谨慎使用。每一个调用都会创建部门间耦合。如果某个调用只需要单向进行,优先考虑通过共享知识或共享技能提供数据,而非实时群组调用。

移除群组节点

点击 ⬡ 群组节点打开其检查器。检查器显示群组名称、工作区以及连接到它的所有智能体。按钮:

点击群组调用连接边可检查它:查看别名、连接智能体和用途。点击移除 仅删除该连接边,不移除群组节点。

组织设计

组织标签页是你的公司组织架构图,显示所有工作区(部门)及其中的群组。

工作区

为每个部门或职能领域创建一个工作区:财务、运营、HR、客户成功。 工作区是一个容器 —— 它本身没有运行时行为。它为群组提供命名空间, 并为共享资源(知识、技能、感知者)提供作用域。

群组

每个群组处理一类工作。在工作区内创建群组。群组有一个启用标志 —— 禁用的群组无法接收事件,也不会启动运行。 可从组织视图或控制室激活或暂停群组,无需删除它们。

删除群组会永久移除数据库记录和文件系统目录 (data/workspaces/<ws>/swarms/<swarm>/)。

群组画布

群组画布是你设计群组拓扑的地方。它是一个 Cytoscape.js 图表, 每次更改都直接写入 hierarchy.json —— 没有单独的保存步骤。

添加节点

从左侧调色板拖拽项目到画布:

绘制连接

  1. 点击节点打开检查器
  2. 在检查器中点击连接到…
  3. 出现提示横幅:"点击目标节点以建立连接"
  4. 点击任何兼容目标(智能体、人工节点)
  5. 在模态框中输入 purpose(用途)—— 此项为必填
  6. 保存 —— 连接边出现并被写入 hierarchy.json

删除元素

点击任意节点或连接边打开检查器,然后点击删除。 对于智能体,这会从拓扑中移除智能体及其宪章文件。 对于人工节点,这会断开所有连接并从画布移除节点。 对于连接边,只移除连接 —— 两个端点保留。

检查器

右侧检查器面板为所选元素显示上下文相关操作。 智能体:编辑宪章、发送测试事件、查看连接。连接边:查看用途、删除。 画布背景:查看群组信息、发送事件、删除群组。

文件面板

检查器下方是群组的文件面板。它显示群组 files/ 目录中的每个文件, 用彩色圆点指示每个文件是由智能体写入还是人工上传的。 从面板标题可以上传文件、创建文件夹、下载单个文件和删除文件。 也支持拖拽到面板。详细架构请参阅群组文件

收件箱

收件箱是人机协作系统面向人类的一侧。顶部导航栏中的通知圆点显示需要处理的项目数量。

标签页

标签页内容
待处理 挂起的调用者请求。每条显示触发运行、提出请求的智能体和完整上下文。可选择批准、拒绝或修改。
通知 未读的通知者消息。这些是 FYI 信息 —— 工作流已经继续。标记为已读可关闭。
已批准 历史批准记录(决策:yes),附有时间戳和原因。
已拒绝 历史拒绝记录(决策:no),附有时间戳和原因。

处理调用者请求

选择一条待处理项目。详情面板显示运行上下文、请求智能体的问题或提议以及完整事件负载。 提供三种操作:

可以为任何决策选择性添加原因说明。此原因会附加到运行步骤记录,用于审计目的。

控制室

控制室是你智能体群舰队的运营仪表盘,将实时组织架构图与过滤后的运行日志相结合。

组织架构面板

左侧面板将所有工作区及其群组显示为可折叠树形结构。对于每个群组:

点击工作区行将运行日志过滤为该工作区的群组。点击群组行仅过滤该群组。 再次点击取消选择并显示所有运行。

运行日志

右侧面板按时间倒序显示运行记录。过滤条件:

实时更新通过 SSE 推送 —— 运行日志在运行开始、完成或失败时自动刷新,无需手动刷新。

运行详情

点击运行查看其步骤追踪:按序列排列的每次智能体调用、技能调用、人工交互和拓扑违规。 每个步骤显示智能体名称、连接用途、输入/输出、持续时间和任何错误。 重放按钮可重新发送原始事件负载。

资源库

资源库标签页管理可复用资源:知识(文档)和技能(Python 脚本)。 两者都可以存在于公司、工作区或群组作用域。使用左侧作用域侧边栏切换作用域。 两个标签页都有实时过滤栏,可按名称或描述搜索。

技能作用域侧边栏顶部还包含一个内置条目。内置技能由平台提供,只读, 始终可用。它们显示为信息卡片 —— 可点击查看源码,但无法编辑或删除。 通过在任何其他作用域创建同名技能来覆盖任何内置技能。

知识文档

知识文档是在运行时注入智能体上下文的 Markdown 文件。 通过在宪章的 knowledge 数组中引用文档名称将其附加到智能体。 公司作用域的文档对所有智能体可用,无需显式引用。

点击+ 新建文档或任何现有卡片,打开内联全屏编辑器,包含:

文档卡片显示内容预览片段和相对的最后修改时间戳。

技能

技能直接在浏览器中使用分屏代码编辑器编写: 左侧面板是 skill.py(Python,CodeMirror),右侧面板是 config.yaml。两者原子保存。

AI 起草按钮根据通俗语言描述生成可运行的 .py + .yaml 组合。 可折叠的可用 Python 库面板显示沙箱中安装的内容, 以及哪些包需要在 YAML 中添加 allowed_packages 条目。

保存后,技能出现在画布调色板中,可以连接到执行者智能体。 技能卡片显示描述、超时时间、包标签和最后修改时间戳。

API 端点

所有端点均返回 JSON。基础路径:/api/v1

健康检查

方法路径说明
GET/health健康检查 —— 返回 {"status":"ok"}

工作区与群组

方法路径说明
GET/workspaces列出所有工作区
POST/workspaces创建工作区。请求体:display_namedescription
GET/workspaces/<id>获取工作区及嵌套群组列表
PUT/workspaces/<id>更新工作区显示名称/描述
DELETE/workspaces/<id>删除工作区(必须没有群组)
GET/workspaces/<id>/swarms列出工作区中的群组
POST/workspaces/<id>/swarms创建群组。请求体:display_namedescription
GET/swarms/<id>获取群组及完整元数据
PUT/swarms/<id>更新群组。支持 enabled(布尔值)激活/暂停
DELETE/swarms/<id>删除群组 —— 移除数据库记录和文件系统目录

智能体

方法路径说明
GET/swarms/<id>/agents列出群组中的智能体
GET/agents/<id>获取单个智能体及宪章文本
PUT/agents/<id>/constitution更新智能体宪章文本

拓扑

方法路径说明
GET/swarms/<id>/topology获取完整的 hierarchy.json 内容
PATCH/swarms/<id>/topology对拓扑应用命名操作。参见 hierarchy.json

拓扑 PATCH 操作:

操作参数效果
add_agentidlayer创建智能体,添加到拓扑
remove_agentid移除智能体及其所有连接边
add_edgefromtokindpurpose添加智能体间连接边
remove_edgefromto移除连接边
add_callagentcallerpurpose将智能体连接到调用者节点
remove_callagentcaller移除智能体→调用者连接
add_informagentinformerpurpose将智能体连接到通知者节点
remove_informagentinformer移除智能体→通知者连接
add_canvas_callercaller在画布上放置调用者节点(未连接)
remove_canvas_callercaller移除调用者节点及其所有连接
add_canvas_informerinformer在画布上放置通知者节点(未连接)
remove_canvas_informerinformer移除通知者节点及其所有连接
add_canvas_swarmswarm_id在画布上放置外部群组 ⬡ 节点(未连接)
remove_canvas_swarmswarm_id从拓扑移除群组节点及其所有 swarm_call 连接边
add_swarm_callagentaliasswarm_idpurpose将智能体连接到带命名别名的外部群组;群组必须已在画布上
remove_swarm_callagentalias按智能体和别名移除单条智能体→群组委托边

事件与触发器

方法路径说明
POST/swarms/<id>/events向群组发送事件。请求体为事件负载(任意 JSON)。
GET/events列出最近事件。参数:swarm_idlimit
GET/swarms/<id>/triggers列出群组的触发器
POST/swarms/<id>/triggers创建触发器。请求体:namekindconfig
PUT/triggers/<id>更新触发器(配置、启用标志)
DELETE/triggers/<id>删除触发器
POST/triggers/invocations/<id>手动调用触发器

运行记录

方法路径说明
GET/runs列出运行记录。参数:statusswarm_idworkspace_idlimitoffset
GET/runs/<id>获取单条运行及完整步骤追踪
POST/runs/<id>/replay重新发送原始事件 —— 创建新运行

人工操作(调用者收件箱)

方法路径说明
GET/inbox列出调用者请求。参数:status(pending / yes / no)、swarm_id
GET/inbox/<id>获取单条操作及完整上下文
POST/inbox/<id>/decide响应调用者请求。请求体:decision(yes/no)、reasonamend

人工通知(通知者收件箱)

方法路径说明
GET/informs列出通知者通知。参数:status(unread / read)、swarm_id
GET/informs/<id>获取单条通知及完整上下文
POST/informs/<id>/read将通知标记为已读
POST/informs/<id>/dismiss关闭通知

知识

方法路径说明
GET/knowledge列出知识文档。参数:scopeworkspace_idswarm_id
POST/knowledge创建知识文档。请求体:scopenametitlecontent
GET/knowledge/<id>获取单篇文档及完整内容
PUT/knowledge/<id>更新文档。请求体:titlecontent
DELETE/knowledge/<id>删除文档及其 .md 文件
POST/knowledge/<id>/draftAI 生成文档内容。请求体:prompt(可选描述)

技能

方法路径说明
GET/skills列出技能。参数:scopeworkspace_idswarm_id
POST/skills创建技能。请求体:scopenamepy_contentyaml_content
GET/skills/<name>获取单个技能及完整 .py.yaml 内容。参数:scope
PUT/skills/<name>更新技能文件。请求体:py_contentyaml_content
DELETE/skills/<name>删除技能 —— 移除 .py.yaml 文件。参数:scope
POST/skills/_meta/draftAI 生成技能文件。请求体:nameprompt
GET/skills/_meta/runtime返回 Python 版本、标准库概要及沙箱中可用的第三方包

群组文件

方法路径说明
GET/swarms/<id>/files列出群组 files/ 目录中的文件。参数:prefix 按路径前缀过滤
POST/swarms/<id>/files上传文件。带 file 字段和可选 path 字段的 multipart 表单。添加 overwrite=true 可替换已有文件。最大 50 MB。
GET/swarms/<id>/files/download下载文件。参数:path(相对于 files/)。返回正确 MIME 类型的原始字节。
DELETE/swarms/<id>/files删除文件。参数:path。同时移除索引行并清理空的父目录。

设置

方法路径说明
GET/settings列出所有设置键值对
GET/settings/<key>按键获取单个设置
PUT/settings/<key>设置单个配置项
PUT/settings批量设置多个配置项
POST/settings/llm/test使用当前凭据测试 LLM 连接

hierarchy.json

群组的完整拓扑。由画布写入,由运行时读取并强制执行。

键名类型说明
swarm字符串群组标识符(文件夹名称)
entry_point字符串接收传入事件的智能体 ID
agents数组所有智能体节点:idlayer
edges数组智能体间连接:fromtokindpurpose
skills数组技能附加:agentskill
calls数组智能体→调用者连接:agentcallerpurpose
informs数组智能体→通知者连接:agentinformerpurpose
canvas_callers数组画布上存在的调用者节点名称(可能未连接)
canvas_informers数组画布上存在的通知者节点名称(可能未连接)
canvas_swarms数组画布上存在的外部群组节点 ID(可能未连接)
swarm_calls数组声明的跨群组委托:agentaliasswarm_idpurpose
consultations数组预留给未来的横向对等咨询连接边
{
  "swarm": "invoice-intake",
  "entry_point": "policy-agent",
  "agents": [
    { "id": "policy-agent",          "layer": "policy"       },
    { "id": "finance-orchestrator",  "layer": "orchestrator" },
    { "id": "invoice-executor",      "layer": "executioner"  }
  ],
  "edges": [
    {
      "from": "policy-agent",
      "to": "finance-orchestrator",
      "kind": "delegate",
      "purpose": "route invoice work to finance orchestrator"
    },
    {
      "from": "finance-orchestrator",
      "to": "invoice-executor",
      "kind": "delegate",
      "purpose": "execute invoice parsing and classification"
    }
  ],
  "skills": [
    { "agent": "invoice-executor", "skill": "parse-invoice" }
  ],
  "calls": [
    {
      "agent": "policy-agent",
      "caller": "finance-approval",
      "purpose": "request human approval for invoices above 10000"
    }
  ],
  "informs": [
    {
      "agent": "invoice-executor",
      "informer": "ops-notifications",
      "purpose": "notify ops team when an invoice is successfully processed"
    }
  ],
  "canvas_callers":  ["finance-approval"],
  "canvas_informers": ["ops-notifications"],
  "canvas_swarms": ["hr-onboarding"],
  "swarm_calls": [
    {
      "agent": "finance-orchestrator",
      "alias": "hr_lookup",
      "swarm_id": "hr-onboarding",
      "purpose": "look up employee onboarding status for invoice vendor verification"
    }
  ],
  "consultations": []
}

目录结构

swarmwright/
├── app/
│   ├── models/           — SQLAlchemy ORM(9 张表,含 swarm_files)
│   ├── api/              — /api/v1 下的 Flask 蓝图
│   │   ├── workspaces.py
│   │   ├── swarms.py
│   │   ├── agents.py
│   │   ├── topology.py
│   │   ├── events.py
│   │   ├── triggers.py
│   │   ├── runs.py
│   │   ├── callers.py     — 调用者/通知者节点 + 收件箱 + 通知
│   │   ├── knowledge.py
│   │   ├── skills_api.py
│   │   ├── files.py       — 群组文件存储端点
│   │   ├── stream.py      — SSE 事件流
│   │   └── settings.py
│   ├── core/             — 业务逻辑(不导入 Flask)
│   │   ├── registry.py       — 文件系统扫描器、层级缓存
│   │   ├── runtime.py        — 拓扑强制执行的智能体运行
│   │   ├── file_store.py     — 群组文件索引管理
│   │   └── executor.py       — 技能沙箱化
│   ├── builtin_skills/   — 平台预设技能(只读)
│   │   ├── write_swarm_file.py / .yaml
│   │   ├── read_swarm_file.py / .yaml
│   │   ├── list_swarm_files.py / .yaml
│   │   └── delete_swarm_file.py / .yaml
│   └── static/           — 原生 JS 前端(无构建步骤)
│       ├── index.html
│       ├── js/
│       │   ├── app.js          — 路由
│       │   ├── api.js          — fetch 封装
│       │   ├── sse.js          — SSE 客户端
│       │   └── views/          — 每个标签页对应一个文件
│       └── css/
├── docker/               — Dockerfile、docker-compose.yml、entrypoint.sh
├── migrations/           — Alembic schema 迁移
├── tests/                — pytest 测试套件
└── data/                 — 挂载卷(不提交到 git)
    ├── swarm.db
    ├── .encryption_key
    ├── company/
    │   ├── knowledge/
    │   └── skills/
    └── workspaces/
        └── <workspace-slug>/
            ├── meta.yaml
            ├── knowledge/
            ├── skills/
            └── swarms/
                └── <swarm-slug>/
                    ├── meta.yaml
                    ├── hierarchy.json
                    ├── agents/
                    │   └── <agent-id>.md
                    ├── skills/
                    ├── knowledge/
                    ├── triggers/
                    └── files/           — 群组文件存储(无限嵌套)

术语表

术语定义
智能体(Agent)具有宪章和层级的 LLM 驱动组件
调用者(Caller)阻塞式人机协作节点 —— 暂停运行等待决策
宪章(Constitution)定义智能体身份、角色和知识引用的 Markdown 文件
控制室(Control Room)运营仪表盘 —— 组织架构图 + 运行日志 + 触发控制
连接边(Edge)hierarchy.json 中声明的连接,包含类型(escalate/delegate/report)和用途
入口点(Entry point)接收传入事件的智能体,执行的第一个节点
人工操作(Human Action)等待人工决策的挂起调用者请求
人工通知(Human Inform)来自通知者节点的非阻塞通知
通知者(Informer)非阻塞式人机协作节点 —— 发送通知后继续运行
层级(Layer)四种智能体角色之一:策略层 / 编排者 / 执行者 / 感知者
感知者(Perceptionist)只读感知智能体 —— 将外部现实映射为内部数据结构
用途(Purpose)解释连接存在原因的必填通俗语言字符串
运行(Run)响应单个事件的群组的一次执行
运行步骤(Run step)运行中记录的一个操作(智能体调用、技能调用、人工交互、违规)
作用域(Scope)company / workspace / swarm —— 可复用资源的三个层级
技能(Skill)可由执行者智能体调用的沙箱化 Python 脚本
群组(Swarm)处理一类工作的智能体集合,具有声明的拓扑结构
拓扑(Topology)hierarchy.json 中声明的图 —— 在运行时无例外地强制执行
拓扑违规(Topology violation)被阻止的对未声明目标的调用 —— 记录为运行步骤,在 UI 中上报
内置技能(Built-in skill)SwarmWright 预装的平台技能,在资源库 → 技能 → 内置中可见;只读但可在任意作用域覆盖
文件监视器(File Watcher)当匹配 glob 模式的文件出现或在群组 files/ 目录中发生变化时触发的触发器
群组文件(Swarm Files)每个群组的 files/ 目录 —— 智能体和人类均可访问的共享持久化文件系统,在数据库中建立索引
触发器(Trigger)产生事件的确定性脚本(心跳、监听器、调用或文件监视器)
工作区(Workspace)类似部门的群组容器,提供资源作用域
别名(Alias,群组调用)在群组调用连接边上声明的简短标识符,调用方智能体在 invoke_swarm 操作中使用它来寻址目标群组
群组调用(Swarm call)对另一个群组入口点的拓扑声明式同步调用 —— 调用方阻塞等待目标返回结果
群组节点(Swarm node)代表可委托的外部群组的 ⬡ 画布元素;同工作区目标为青色,跨工作区为琥珀色
跨工作区委托(Cross-workspace delegation)目标群组位于不同工作区的群组调用;以琥珀色显示并带有 ↗ 标签,作为刻意的部门间耦合警告