这是本节的多页打印视图。 .
文档
最近更新:
- 1: 快速开始
- 1.1: AGW 是什么
- 1.2: 核心概念
- 1.3: 安装与配置 Server
- 1.4: 开始第一次对话
- 2: AGW 特点
- 2.1: 自定义 Agent
- 2.2: Agentflow
- 2.3: 多 Agent 上下文复用
- 2.4: 图片输入
- 2.5: 记忆:个人偏好与项目知识
- 2.6: Plan 与 Execute 模式
- 2.7: JSON Schema 结构化响应
- 2.8: 工具审批
- 2.9: 文件浏览与 Git 变更审查
- 2.10: 多端客户端
- 2.11: 第三方账号登录
- 3: 使用指南
- 3.1: 模型提供商
- 3.2: 创建自定义 Agent
- 3.3: 接入外部 Agent
- 3.4: Chat 与执行记录
- 3.5: Projects、文件与工作目录
- 3.6: Agentflow
- 3.7: Jobs 定时任务
- 3.8: Tools 与 Skills
- 3.9: MCP 服务
- 3.10: 配置 Integrations
- 3.11: Web、Desktop 与 Mobile
- 4: 部署运维
- 4.1: 单机与 Docker 部署
- 4.2: Control/Data Plane 分离部署
- 4.3: 配置与认证
- 4.4: 数据目录、备份与升级
- 4.5: 日志与常见问题
- 5: 开发指南
- 5.1: 开发环境与运行
- 5.2: 架构与模块边界
- 5.3: API 与执行协议
- 5.4: 扩展 Tools 与 Integrations
- 5.5: 测试与贡献约定
1 - 快速开始
最近更新:
第一次使用 AGW,可以按下面的顺序完成安装和对话。只想先了解用途,阅读“AGW 是什么”即可;已经连接 Server,则直接进入“开始第一次对话”。
- AGW 是什么:了解能完成哪些工作,以及任务在哪里运行。
- 安装与配置 Server:选择安装包,完成初始化和客户端连接。
- 开始第一次对话:配置模型和 Agent,验证一次连续对话。
遇到不熟悉的名词时,查阅核心概念。
1.1 - AGW 是什么
最近更新:
AGW 是面向个人和小型研发团队的自托管 Agent 工作平台,也可作为 Agent 网关提供服务。它将自定义 Agent、Claude Code、Codex 和 Pi 等外部 Agent 放在统一界面中,围绕项目保留对话与执行记录。

核心概念
| 概念 | 用途 |
|---|---|
| Model Provider | 连接提供商与模型,指定实际使用的模型配置 |
| Agent | 配置指令、模型和能力,或接入已有外部 Agent |
| Project | 保存工作目录、上下文与会话的任务空间 |
| Chat | 发起交互式执行,查看消息、工具活动并处理人工输入 |
| Agentflow | 将多个节点连接成可执行流程 |
| Job | 按一次性、间隔或 Cron 触发 Agent 或 Agentflow |
各概念的区别及配合方式见核心概念。
可以用 AGW 做什么
假设正在维护一个代码项目:可以先让 Agent 解释陌生代码,再让另一个 Agent 审查修改;讨论和结果保存在项目的会话中。需要重复完成的工作,例如每周整理进展,可以在手动验证后设为定时任务。
| 需求 | 从哪里开始 |
|---|---|
| 问问题、整理一段文字 | 创建 Agent,在 Chat 中发送任务 |
| 阅读或修改项目文件 | 设置 Project 工作目录,再为 Agent 配置相应工具 |
| 让不同 Agent 接着讨论 | 在同一会话中切换 Agent,说明下一步任务 |
| 按固定步骤协作 | 用 Agentflow 连接各个步骤,按需加入人工确认 |
| 定期重复一项工作 | 用 Job 设置时间,并查看每次执行结果 |
任务在哪里运行
**Server(服务端)**是实际运行 AGW 的程序。Web、Desktop 和 Mobile 是操作它的客户端。使用远程 Server 时,Agent 访问的是远程主机上的文件、命令和工具;在手机中打开会话,不会让任务改在手机上运行。
首次在自己的电脑上使用,可以选择包含 Server 的 Desktop Full。希望通过浏览器使用,可以部署 Docker 或 Portable Server。模型服务需要另外配置;选择远程模型时,发送给模型的内容会离开 AGW 所在主机。
选择部署方式
**Standalone(单机)**把管理页面、对话执行和定时任务放在一个 Server 中,默认使用 SQLite 数据库,适合本机使用和单台主机部署。
Control/Data Plane 分离部署把管理与调度交给控制面,把实际执行交给数据面。它适合需要分别部署管理服务、增加执行节点的场景,但也需要共享 PostgreSQL、密钥和工作目录,并配置请求转发。
通常可以先从 Standalone 开始。安装选项见安装与配置 Server;需要分离部署时,再阅读部署步骤与路由配置。
从一个小任务开始
- 安装与配置 Server并初始化服务。
- 配置一个可用模型,创建一个 Agent。
- 在 Chat 发送简单问题,确认模型和执行链路正常。
- 有文件需求时创建 Project;有固定步骤时再使用 Agentflow;有周期需求时再配置 Job。
执行记录保存在你的服务数据库中。自托管不代表所有推理都发生在本机:选择远程模型提供商时,请求仍会发送到该提供商。
当前边界
AGW 尚未达到 1.0。它适合清晰、可拆分的任务与人机协作;复杂任务仍需要清楚的输入、完成标准和人工检查。当前使用管理员登录、第三方账号登录及 API Key,尚不提供角色管理或按 API Key 分配权限范围。
实现与参考
1.2 - 核心概念
最近更新:
在 AGW 中,模型负责推理,Agent 组织指令和能力,Project 提供工作空间。你可以通过 Chat 与 Agent 交互,也可以用 Agentflow 编排步骤、用 Job 安排执行时间。
模型与 Model Provider
模型相关配置分为三层:
| 概念 | 描述什么 |
|---|---|
| Provider | 模型服务的协议、地址和认证信息 |
| Model | 模型标识、上下文窗口和最大输出等规格 |
| Model Provider | 将一个模型与提供它的服务关联,供 Agent 选择 |
例如,你可以将同一个模型关联到不同的 Provider,再为 Agent 选择实际使用的连接。配置方法见模型提供商。
Agent:执行任务的角色
Agent 定义任务由谁完成、遵循什么指令,以及可以使用哪些能力。
- 自定义 Agent:在 AGW 中配置模型、指令、工具和 Skills,由 AGW 运行。
- 外部 Agent:接入 Claude Code、Codex、Pi 等 CLI,使用执行节点上已安装并配置好的工具环境。
Agent 定义可以用于多次任务;一次执行则是它处理某次输入的过程。例如,“代码解释助手”是 Agent,“解释这个函数”是一次输入。参见创建自定义 Agent与接入外部 Agent。
Project:工作空间
Project 围绕一项工作组织目录、上下文与会话。例如,一个代码仓库可以对应一个 Project,其中分别保存代码阅读、问题排查等会话。
主工作目录 Workspace 是 Agent 默认的工作目录。附加目录允许访问更多服务端路径;在文件浏览器中切换目录,不会改变 Agent 的默认工作目录。
这些路径必须对 Server 或执行节点可见。详细说明见Projects、文件与工作目录。
Chat、会话与执行
Chat 是交互入口;会话保存连续交流的上下文与记录;执行是 Agent 或 Agentflow 处理输入的过程。
在一次会话中,你可以连续发送多条消息。执行过程中可以查看回复和工具活动,处理审批或补充信息请求。页面断开连接不等于执行已经停止,重新连接后应查看实际状态:会话列表中的图标会显示 Running(运行中)、Last turn failed(上一轮失败)或 Last turn interrupted(上一轮被中断)。
使用方法见Chat 与执行记录。
Agent Capability(Agent 能力)
Capability 是 Agent 完成任务时可以使用的能力。以下概念分别描述具体操作、工具组合、任务说明,以及外部服务的接入方式。
Tools
Tool 是一项可调用的具体操作,例如读取文件或查询任务。Agent 根据任务需要调用工具,并使用返回的结果继续处理问题。
ToolBlocks
ToolBlock 是需要整体选择和管理的一组关联 Tool,用来保持行为与状态一致。它按整组选用,模型仍逐个调用其中的 Tool。
例如,todo 组合了添加、列出和完成待办事项等工具。选择它后,模型可以调用 todos_add、todos_get_all、todos_complete 等成员;这些成员不能作为独立工具单独选用或移除。
Skills
Skill 围绕任务提供使用说明、资源和可选工具,指导 Agent 如何完成工作。例如,agw-job 提供任务管理说明及工具。
Skill 分为 Built-in(内置)、**Local(本地)**和 **Remote(远程)**三类。Built-in 由 AGW 模块提供,例如上面的 agw-job;用户可以添加 Local 或 Remote Skill:Local 上传到 AGW 服务端,Remote 从指定网址读取。根据内容由谁维护、是否需要随包提供资源来选择,具体格式和更新规则见 Tools 与 Skills。
MCP
MCP 是连接工具服务的协议。配置 MCP Server 后,AGW 可以从服务中发现并调用工具,让 Agent 使用该服务提供的能力。配置方法见 MCP 服务。
Plugins
Plugin 定义一个集成提供哪些能力,以及如何接入服务,包括连接方式、认证方式、工具来源和内置 Skills。例如,GitHub Plugin 定义 GitHub 的认证与工具能力。
Integrations
Integrations 是用户选择和配置外部服务的入口,分为两部分:
- Available integrations(可用集成):可供选择和配置的集成目录,例如 GitHub。目录展示 Plugin 定义的能力。
- Configured integrations(已配置的集成):用户配置好的具体账号或服务端点。同一种集成可以配置多个账号,例如个人和工作 GitHub 账号。
Agent 选择具体的已配置集成,只有归属匹配且处于 Ready 状态的账号或端点才能提供能力。已配置集成在代码中对应 Connection 类型。
配置方法见 Integrations。

Agentflow 与 Job
Agentflow 决定步骤如何协作。它可以组合多个 Agent,以及分支、并行、人工审批等节点。例如,让一个 Agent 收集材料,另一个 Agent 整理摘要,再由人确认输出。
Job 决定什么时候运行。它按一次性、间隔或 Cron 触发一个 Agent 或 Agentflow,并记录每次尝试的结果。一个简单的定时问答任务可以直接选择 Agent;需要多个步骤时再选择 Agentflow。
二者可以独立使用:Agentflow 可以在 Chat 中手动运行,Job 也可以只执行一个 Agent。参见Agentflows与Jobs。
把概念串起来
以定期整理项目进展为例:
- 创建 Project,设置项目的工作目录。
- 配置 Model Provider,创建负责整理进展的 Agent。
- 为 Agent 绑定读取资料需要的工具或已配置的集成。
- 在 Chat 中运行一次,确认结果符合要求。
- 如需分工或审批,用 Agentflow 组织步骤;如需定期执行,用 Job 设置时间。
第一次使用时,先完成一次简单对话,再按任务需要增加其他能力。
1.3 - 安装与配置 Server
最近更新:
AGW 需要一个持续运行的 Server,以及用来操作它的客户端。首次在本机使用可选 Desktop Full;已有 Server 则选 Desktop Client,或直接使用浏览器。安装后再配置模型服务或外部 Agent,即可开始对话。
安装方式
| 方式 | 适合场景 | 主要区别 |
|---|---|---|
| Desktop Full | 在本机使用图形界面 | 同时安装桌面客户端和 Server,Server 作为当前用户的后台服务运行 |
| Desktop Client | 连接已运行的 Server | 只安装桌面客户端,不包含 Server,可连接本机或远程 Server |
| Docker | 容器化部署、自托管 | 在容器中运行 Server,包含 Web 界面,通过挂载保存数据和访问工作目录 |
| Portable Server | 直接在主机上部署服务 | 直接运行 Server 可执行程序,包含 Web 界面,无需 Docker 或桌面客户端 |
| 源码运行 | 开发与调试 | 自行构建和运行后端及所需客户端,可修改代码并调试各模块 |
Desktop
- 打开 GitHub Releases。
- 按平台选择 Full 或 Client。Windows、Ubuntu 当前提供 x64;macOS 提供 x64 和 arm64。
- Full 首次启动时完成 Server 的初始化;Client 连接现有 Server。
Full 和 Client 使用相同的应用标识,只能安装其中一种。Full 安装包含 Desktop Client 以及当前用户级 Server 后台服务;关闭 Desktop 不会自动停止 Server。安装包当前未签名或公证。

Docker 与 Portable Server
Docker 镜像随版本发布到 ghcr.io/zxyao145/agw。Portable Server 不随 Release 提供,需要在仓库根目录自行构建,例如 PUBLISH_MODE=portable APP_VERSION=0.1.0 RIDS=linux-x64 ./publish.sh,再按单机部署文档启动 agw-server serve。
根据部署需求选择以下方式:
- 单机与 Docker 部署:在一个 Server 中运行完整服务,适合本地试用和单机自托管。
- Control/Data Plane 分离部署:将管理与调度、任务执行分开运行,适合需要独立部署或扩展执行节点的场景,包含共享数据库、目录及 Nginx 路由配置说明。
需要团队共享或远程访问时,配置域名、HTTPS 和反向代理。
Docker 镜像不包含 Claude Code、Codex、Pi 等任何外部 Agent;如需使用,请自行在容器中安装并完成相关配置。
源码
参考开发环境,先启动 Standalone Host,再运行 Web。后端默认端口为 30816,Web 开发端口为 3001。
配置 Server
前提:Server 已启动,数据库配置有效,数据目录可写。默认单机模式使用 SQLite 和 InProcess 执行。
首次初始化
- 打开 Server 的
/setup页面,例如本机的http://localhost:30816/setup。Docker 或 Portable Server 包含 Web;源码模式也可先完成服务端初始化。 - 设置管理员密码。只有在 Server 所在主机上直接用
localhost或回环地址访问时,才不需要 Setup Code。通过域名、反向代理或其他主机访问,以及访问 Docker 容器映射的端口时,还需要填写启动日志中的一次性 Setup Code。 - 提交后等待数据库初始化完成,页面会进入应用,无需再次重启。
初始化成功后,密码和登录设置会保存在数据库中,后续启动无需重复设置。需要备份或迁移时,请一并保存数据库和加密密钥,参见备份与升级。

连接客户端
- 远程 Web 使用管理员密码登录,获得会话 Cookie。Server 配置了身份提供商时,Web 登录页还会显示第三方账号按钮;Desktop 在 Settings → Connections & app 中每个 Server 下方显示 Sign in with … 按钮,通过系统浏览器登录后自动获得 API Key,见配置与认证。
- Desktop、Mobile 和自动化使用 API Key,通过
Authorization: Bearer agw_...请求头发送。API Key 明文只在创建时显示一次。 - Desktop Full 的本地初始化由 Server 页面完成,主进程随后配置自己的 API Key,并使用操作系统凭据存储保护它。
API Key(访问密钥)相当于客户端连接 Server 的钥匙。给 Desktop Client 或 Mobile 配置远程连接时,先登录 Web,在 Settings 的 Server access 页面中,于 API tokens 填写 Token name 并创建一个 API Key,再将 Server 地址和完整的 API Key 填入客户端。Desktop Client 在 Settings → Connections & app 中点击 +(Add remote Server),填写 Name、Server URL 和 API token。手机上的 localhost 指手机本身,不能用它访问电脑上的 Server。
无人值守初始化
可以通过环境变量 Setup__AdminPassword 注入初始密码。分离部署仅在 Control Plane 初始化;Data Plane 不提供 Setup。不要将实际密码写进代码或站点文档。
已经初始化的服务不会被 Setup 参数覆盖。数据库与执行方式应在启动前使用标准配置设置,不能通过 Setup 表单切换。
完成后进入第一次对话。登录失败时先确认请求连接的是预期 Server。
实现与参考
1.4 - 开始第一次对话
最近更新:
前提:已完成初始化,可以进入管理界面,并有可用模型提供商的凭据。此流程先创建自定义 Agent,不需要外部 CLI。
1. 准备模型连接
打开模型管理页面,配置下面三项。不同客户端的表单布局可能不同,但需要的信息相同。
| 配置 | 要准备什么 | 用途 |
|---|---|---|
| Provider | 服务商要求的协议、API 地址和 API Key | 告诉 AGW 去哪里调用模型、如何认证 |
| Model | 服务商提供的模型 ID、上下文窗口和最大输出长度 | 告诉 AGW 使用哪个模型及其内容长度限制 |
| Model Provider | 将模型与提供商关联 | 作为 Agent 实际选择的模型连接 |
模型 ID 应使用服务商给出的准确值。自动发现时出现的 256,000 / 64,000 只是上下文窗口和最大输出的默认值,需要按实际规格调整。字段说明见模型提供商。
2. 创建一个简单的 Agent
在 Agents 中点击 Create。Agent Type 保持默认的 System(自定义 Agent),Display Name 填写“问答助手”,在 Model Provider 中选择刚配置的连接,并在 Instructions 中填写:
点击 Create 保存,并在 Agents 列表中确认 Enabled 开关已打开;新建的 Agent 默认启用。这次只验证文字对话,工具、Skills 和工作流可以稍后再配置。
3. 发送第一条消息
打开 Chat,确认当前 Server,并选择一个可用 Project:Desktop 在窗口顶部的项目标签页中选择,Web 在左侧栏顶部的下拉框中选择。然后在输入框左上方的选择器中选择“问答助手”,发送:
应能看到回复逐步出现,随后本次执行结束。再发送“把刚才的解释说得更简单一些”,检查 Agent 能否接着上一条消息回答。这可以同时验证模型连接和连续对话。

下一步
先验证纯文本对话,再按任务添加工具与 Skills。文件任务需要配置 Project 的工作目录;已有 Codex 或 Claude Code 环境可以使用外部 Agent。
没有收到回复
检查所选 Model Provider 是否可用、模型 ID 是否正确、凭据与地址是否匹配,并查看 Server 日志。会话列表中的图标显示会话状态:Running 表示仍在运行,Last turn failed 表示上一轮失败,Last turn interrupted 表示上一轮被中断。对话也可能在等待审批或用户输入;这种状态需要在 Chat 中处理。不要在未验证模型前同时加入大量工具或复杂流程。
实现与参考
2 - AGW 特点
最近更新:
从以下十一个方面了解 AGW 如何帮助你组织日常工作。每项特点都包含使用场景、操作入口和适用范围。
2.1 - 自定义 Agent
最近更新:
为任务定义自己的 Agent
在 AGW 中,你可以把模型、指令和工具组合成一个可复用的 Agent。它根据任务和上下文作出判断,选择可用工具执行操作,再根据结果继续处理。
例如,创建一个“文档审查助手”,让它阅读材料、判断哪些地方难懂,并给出修改建议。需要直接修改文件时,再为它配置相应工具和权限。
可以自定义什么
| 配置 | 决定什么 |
|---|---|
| Model Provider(模型提供商) | 使用哪个模型理解任务和生成回复 |
| 指令 | 职责、任务范围、处理要求与输出格式 |
| Tools 与 Skills | 可调用的操作,以及任务所需的指导与能力 |
| 配置好的集成连接 | 可访问的外部服务或账号 |
| Response Schema | 回复是否按 JSON Schema 返回结构化数据,详见 JSON Schema 结构化响应 |
你可以为材料整理、代码解释和结果审查分别创建 Agent,在 Chat 中按任务选择,也可以把它们放进 Agentflow,作为流程中的执行步骤。
开始使用
- 准备可用的 Model Provider,在 Agents 中创建自定义 Agent。
- 选择模型,写清职责和输出要求,例如“审查文档,按原文、问题、建议改写列出结果”。
- 按需添加工具、Skills 或配置好的集成连接;读写文件时,确认 Project 工作目录。
- 保存并启用 Agent,在 Chat 中用一小段材料验证回复,检查工具调用与实际结果。
从单个 Agent 到固定流程
单个 Agent 可以在职责范围内判断如何完成任务。当任务要求每次都经过明确的步骤,例如“整理后必须审查,审查后必须人工确认”,可以用 Agentflow 编排这些步骤。
Agent 的操作范围取决于实际配置的工具与权限。指令本身不会授予文件或外部服务的访问权;模型的判断和执行结果也需要验证。
2.2 - Agentflow
最近更新:
把确定的步骤编排成流程
Agentflow 是 Agent Workflow(Agent 工作流)。Agent 负责判断与执行,Agentflow 负责编排路由、执行预先确定的步骤。 你在画布上连接节点,定义先做什么、结果交给谁,以及何时需要人工确认。
例如,材料整理 Agent 判断哪些信息值得保留,审查 Agent 检查遗漏和表述问题;Agentflow 则安排“先整理、再审查、最后人工确认”的执行顺序。
flowchart LR
I["Input:输入材料"] --> A["Agent:整理材料"]
A --> B["Agent:审查结果"]
B --> H["Human Gate:人工确认"]
H --> O["Output:输出结果"]管理步骤之间的路由
| 任务需要 | Agentflow 如何编排 |
|---|---|
| 按固定顺序处理 | Direct 把上一步结果交给下一步 |
| 按条件选择路径 | If / Else If 按顺序检查条件,只把消息交给第一个匹配的分支;都不匹配时走 Else |
| 同时开展独立任务 | Fan Out 分发到多个分支,或用 Concurrent 编排块并行调用成员 |
| 等待分支结果 | Fan-in Barrier 等待同组来源到齐,再继续下游步骤 |
| 让人确认或补充信息 | Human Gate 暂停流程,等待人工回应 |
需要判断内容含义、生成文字或调用工具的工作交给 Agent;步骤之间的连接和分支规则在 Agentflow 中配置。这样可以直接查看流程是否包含必要的审查与确认环节。
示例 1:Coding,从实施到审查与提交
代码任务通常有一条明确的处理顺序:先实施,再检查;发现问题就返工,确认完成后再提交。把这些步骤放进 Agentflow,可以让不同 Agent 在同一个 Project 工作区中接力,由人决定是否进入下一阶段。

这条流程中的职责分配是:
- Coding:使用 Codex 完成实现,修改当前工作区中的代码。
- Checkpoint 与 Clear Messages:标记恢复边界,并清除传给下游的上游消息,让审查节点按自己的指令检查工作区中的 diff。
- Code Review:使用 Claude Code 审查改动,给出问题与建议,再经过一个 Checkpoint。
- Human Gate:由人判断是否还需要修改。需要返工时返回 Coding,完成后进入 Commit Agent。
- Commit Agent:按已确认的要求执行 Git 提交。
开始前,需要在运行环境中配置好 Codex、Claude Code 和 Git,并确认各节点访问同一个 Project 工作区。为实施、审查和提交节点分别写清职责,先用一项小改动验证完整路径,再测试返工路径。
返工应通过 Human Gate 的人工回复和 If / Else If 条件表达:把 Human Step Mode 设为 Input,由人在 Response 中回复,例如约定“继续修改”返回 Coding、“完成”进入提交。Approval 模式只提供 Reject 和 Approve 两个按钮,不收集文字回复,条件分支读不到人工反馈。Input 模式的 Interrupt 和 Approval 模式的 Reject 都会停止流程,不会自动进入返工分支。 循环必须有明确的退出路径。
Agentflow 固定职责、顺序和人工决定的位置;测试是否通过、审查问题是否解决、最终 diff 是否符合预期,仍需要逐项核对。Checkpoint 的恢复条件见 Agentflow 使用指南。
示例 2:从小红书笔记中提取地点位置
旅游规划应用可以把“导入一篇笔记,在地图上展示地点”拆成三个数据处理步骤。Agentflow 串起处理过程,最后把地点数据交给业务系统,由前端负责地图展示。

| 步骤 | 处理方式 | 交给下一步的结果 |
|---|---|---|
| 获取笔记详情 | Agent 使用 xiaohongshu-skills 中的 xhs-explore,根据小红书地址读取笔记 | 笔记内容 |
| 提取候选地点 | 模型理解内容,提取地点名称和地址信息 | 候选地点与地址 |
| 匹配地理位置 | Agent 调用高德地图 MCP 搜索 POI(兴趣点,如景点、餐厅),匹配对应地点 | 可供业务系统使用的地点与经纬度 |
开始前,需自行准备并配置示例使用的 Skill、高德地图 MCP 及其所需账号或凭据,确认执行节点可以调用它们。这些是示例依赖,不能仅凭创建 Agentflow 就获得相应服务能力。
先用一篇地点明确的笔记验证:是否成功读取内容,提取的地点是否来自原文,POI 是否匹配到正确城市和地址。同名地点、地址不完整或搜索无结果时,需要补充信息或人工核对,不能把候选坐标直接当作确定结果。
这里的分工很直接:工具负责获取笔记和查询位置,模型负责理解文本并提取地点,Agentflow 负责按顺序传递结果;地图展示仍由业务 UI 完成。
开始使用
- 先准备并单独验证需要的 Agent,例如材料整理和文档审查。
- 打开 Agentflows 编辑器,连接 Input、两个 Agent 节点、Human Gate 和 Output。
- 为每个 Agent 节点写清任务,在 Human Gate 的 Human Step Mode 中选择 Approval,并填写确认提示。
- 保存后在 Chat 中选择该 Agentflow,输入一段材料。Chat 会在当前回合中实时显示每个节点收到的输入,据此检查节点执行顺序、人工确认和最终输出。
- 基础路径通过后,再添加条件分支或并行处理,并验证各条路径。
确定的是流程规则
预先确定步骤,不意味着模型每次都会给出相同答案。Agent 仍会根据输入作出判断;条件分支也会根据运行时结果选择路径。在 Human Gate 中选择 Reject 或 Interrupt 时,流程会停止。
Agentflow 还支持 Handoff 和 Magentic 等动态协作编排。若每一步都必须执行,应使用明确的顺序连线;若任务需要动态交接或规划,再选择相应编排块。
2.3 - 多 Agent 上下文复用
最近更新:
让不同 Agent 接力
分析需求、编写代码和审查结果可以交给不同 Agent。在同一个 Project 的同一个会话中切换目标时,AGW 会把其他目标新增的公开文字提供给接手的 Agent,减少反复复制背景和解释进度的工作。
例如,先让 Coding 完成修改,再切换到 Review,让它结合已有讨论审查结果;发现问题后,还可以切回 Coding 继续处理。
flowchart LR
A["Coding:完成修改并说明结果"] --> B["同一会话的公开文字"]
B --> C["Review:结合背景审查"]
C --> D["切回 Coding:继续处理反馈"]开始使用
- 准备两个可运行的 Agent,例如 Coding 和 Review。
- 在 Chat 中选择 Project,使用 Coding 开始会话。
- 等待当前回合结束,在同一会话中切换到 Review,说明接下来要做什么。
- 检查回复是否接上之前的讨论;重要约束可以在新消息中再次强调。
交接时说明下一步
切换 Agent 后,可以发送:“请根据上面的修改说明检查遗漏,只列出需要修正的问题。”接手的 Agent 会得到可复用的公开文字,但仍需要知道这一次的任务是什么。
重要的文件路径、验收条件和结论可以在交接消息中简要重述。若需要长期跨会话保留项目约定,可使用项目记忆。
复用范围
复用的是会话中的公开文字,不包括私有推理、工具调用协议或外部工具的全部内部状态;被中断或失败的回合中未完成的消息也不会交接。交接内容最多 32,000 个字符,较早内容可能不在本次交接范围内;需要处理的文件仍须在接手 Agent 的工作环境中可访问。新建会话不会自动继承另一个会话的讨论。
2.4 - 图片输入
最近更新:
用图片补充文字
遇到界面问题、设计稿或图表时,可以直接把图片附在消息中,让 Agent 结合图片和文字理解任务。例如,附上错误截图并说明操作步骤,或让支持视觉的模型检查页面布局。
把问题说具体
例如,附上页面截图后可以问:“这张图中保存按钮被遮住了,请指出可能的布局问题,并说明还需要哪些信息。”比较两张图时,注明哪张是预期效果、哪张是当前页面。这样 Agent 更容易围绕同一个问题回答。
如果希望修改代码,还需要提供对应项目及文件访问能力;一张截图本身只提供视觉信息。
开始使用
- 选择支持图片理解的模型和执行目标。
- 在 Chat 中添加图片:Web 和 Desktop 把图片粘贴到输入框,Mobile 从相册选择。然后写明希望 Agent 关注的部分。
- 确认附件后发送,检查回复是否正确理解了图片内容。
| 项目 | 支持范围 |
|---|---|
| 图片格式 | JPEG、PNG、GIF、WebP |
| 每条消息 | 最多 5 张图片 |
| 单张大小 | 最多 5 MB |
| 附件总大小 | 每条消息最多 10 MB |
flowchart LR
A["图片 + 文字问题"] --> B["Chat 消息"]
B --> C["支持图片的模型 / 外部运行时"]
C --> D["结合图片作答"]图片能否被理解,取决于所选模型及外部运行时的支持情况;成功添加附件不代表所有模型都能识别图片。截图中的文字过小或内容不清晰时,补充关键文字和具体问题通常更有效。
2.5 - 记忆:个人偏好与项目知识
最近更新:
保留值得长期使用的信息
对话可以结束,但工作习惯和项目知识往往需要继续保留。AGW 提供两类 Memory,让 Agent 在后续工作中使用已保存的信息。
| 记忆 | 适合保存 | 使用范围 |
|---|---|---|
| User Memory | 个人偏好、常用表达方式、长期背景 | 当前用户,可跨 Project 使用 |
| Project Memory | 项目约定、关键决策、工作说明 | 当前项目的工作上下文 |
为 Agent 或 Project 配置相应的 Memory 能力后,可以让 Agent 保存需要复用的信息,并在后续会话中检查或更新。记忆需要明确维护,不等于自动永久保存和注入全部聊天记录。User Memory 按用户隔离;Project Memory 的范围还取决于项目及所选存储方式,共用工作目录的文件型记忆也会共用。External Agent(Claude Code、Codex、Pi)只会读到已有的 User Memory(最多 50 条)作为上下文,没有记忆工具,不能保存或更新记忆;在 Agent 或 Project 上配置的 Project Memory 对它们不生效。

Project Memory 的两种存储模式
Project Memory 提供 Database 和 Project Workspace (Primary directory: .agw/memory) 两种存储方式,默认使用 Project Workspace。两者都让 Agent 使用同一组记忆工具来保存、查找、读取和更新项目知识,区别在于内容保存在哪里、如何共享及备份。
| 对比项 | Database(数据库) | Project Workspace(文件系统,默认) |
|---|---|---|
| 保存位置 | AGW 使用的数据库 | 主工作目录下的 .agw/memory/ |
| 记忆归属 | 按 Project ID 区分 | 按实际工作目录区分 |
| 同一 Project 的不同 Agent / 会话 | 使用相同数据库模式时共享记忆 | 使用相同工作目录和文件系统模式时共享记忆 |
| 两个 Project 使用同一工作目录 | 仍分别保存各自的数据库记忆 | 会读写同一个记忆目录 |
| 备份方式 | 随 AGW 数据库备份 | 随项目文件备份,包含隐藏目录 .agw/memory/ |
| 适合场景 | 希望由 AGW 集中管理,不在项目目录生成记忆文件 | 希望直接查看文件,或让记忆随工作目录一起迁移 |
Database:由 AGW 集中保存
选择 Database 后,记忆内容保存在 AGW 当前配置的数据库中。它仍以文件名组织内容,但不会在项目工作目录中生成对应的记忆文件;Agent 通过 Project Memory 工具读取这些记录。
记忆按 Project ID 区分。同一个 Project 中使用数据库模式的 Agent 可以复用已有记忆;即使另一个 Project 指向同一个工作目录,也不会因此共用这份数据库记忆。修改主工作目录不会改变数据库记忆所属的 Project。
这种方式适合希望统一备份和管理数据的部署。备份时应按 AGW 数据备份流程保留数据库及所需的加密密钥;只复制代码目录不会带走数据库记忆。在多执行节点部署中,共享数据库也意味着这些节点可以访问同一份项目记忆,仍须通过项目访问权限检查。
Project Workspace:保存为项目目录中的文件
选择 Project Workspace (Primary directory: .agw/memory) 后,记忆保存在实际执行主机的主工作目录中。例如,Project 的 Workspace 为 /work/demo,记忆目录就是:
上例中,coding-conventions.md 是记忆正文,coding-conventions_description.md 是保存时提供的可选说明,memories.md 是 AGW 维护的记忆索引。目录固定在主工作目录下,不会随 Files 界面选择的附加目录而改变。
这种方式方便直接查看文件,也可以自行决定是否将记忆纳入 Git 或项目文件备份。AGW 不会自动提交这些文件;备份和迁移时要确认没有遗漏隐藏目录。通过记忆工具写入或删除内容会同步维护索引;直接修改文件后,索引不一定随之更新,因此日常维护优先使用记忆工具。
两个 Project 如果指向同一个实际工作目录,会共用其中的 .agw/memory/,即使它们的 Project ID 不同。修改 Workspace 后,Agent 会使用新位置下的记忆,原目录里的文件不会自动搬过去。在 Docker 中,应持久化挂载工作目录;在多节点部署中,各执行节点需要看到同一份目录内容,仅有相同的路径字符串并不足够。
flowchart TD
A["Project Memory 工具"] --> B{"Storage"}
B -->|"Database"| C["AGW 数据库:按 Project ID 保存"]
B -->|"Project Workspace"| D["主工作目录/.agw/memory"]如何配置与验证
前提:已有可运行的自定义 Agent 和 Project;文件系统模式还需要执行主机能够读写主工作目录。
- 打开 Agent 或 Project 的 Tools 配置,选中 Project Memory ToolBlock。
- 在卡片展开后的 Storage 中选择 Database 或 Project Workspace (Primary directory: .agw/memory),保存配置。希望项目内统一使用时,优先在 Project 中配置。
- 在该 Project 的新回合中,让 Agent 保存一条明确的项目约定,例如:“将项目统一使用 UTC 的约定保存到
time-conventions.md,并添加简短说明。”写入操作仍受模式与审批设置约束。 - 新建同一 Project 下的会话,使用具有相应记忆能力且存储模式一致的 Agent,让它列出并读取这条记忆。应能读到之前保存的内容。
- 文件系统模式可同时检查
.agw/memory/中的文件;数据库模式不会在那里生成文件,应通过记忆工具验证。
两种模式是独立的数据来源,切换 Storage 不会自动复制、合并或删除另一种模式中的记忆。需要迁移时,先备份原存储,读取要保留的正文和说明,再切换模式并通过记忆工具重新写入,最后核对内容。修改配置后使用新回合验证,已经运行的回合仍使用开始时的配置。
Agent 如何使用已保存的记忆
Project Memory 会向模型提供记忆索引,再由 Agent 按需读取相关正文。当前自动生成的索引最多包含 50 条,更多记忆仍可通过列表和搜索工具查找;并不是每次请求都会发送全部记忆正文。
建议每份记忆围绕一个主题,使用清楚的文件名和简短说明。约定变化后更新原条目,过期信息及时删除,避免多份互相矛盾的说明影响后续任务。User Memory 则始终保存在数据库中,按用户隔离,不受这里的 Storage 选项影响。
实现与参考
2.6 - Plan 与 Execute 模式
最近更新:
先想清楚,再动手
准备修改代码或执行复杂任务时,可以先让 Agent 分析现状和提出方案,再决定是否进入执行阶段。在自定义 Agent 或 Project 上配置 Mode ToolBlock 后,自定义 Agent 支持 Plan 与 Execute 两种工作模式;配置在 Project 上时,该 Project 中运行的自定义 Agent 都会获得这项能力。
| 模式 | 适合做什么 | 工具行为 |
|---|---|---|
| Plan | 了解现状、分析问题、整理方案 | 只允许声明可在 Plan 中使用的工具 |
| Execute | 按确认的方案完成工作 | 可使用已配置的工具,仍需遵守权限与审批规则 |
一个文档修改的例子
先在 Plan 中要求:“阅读文档,指出术语不清和缺少示例的地方,先给修改建议。”查看方案并确认范围后,再进入 Execute,让 Agent 按方案修改文件。完成后检查差异,确认原有事实和限制被保留。
能否读取或修改文件仍取决于配置的工具。只切换模式,不会自动添加缺少的文件能力。
开始使用
- 在自定义 Agent 或 Project 的 Tools 中配置 Mode ToolBlock 和任务所需工具。
- 新回合默认处于 Execute。在 Chat 输入框点击 +,选择 Plan mode,输入框中出现 Plan 标记后,再要求 Agent 分析问题。
- Agent 提出的方案显示为 Plan 卡片,可以复制。确认方案后点击 Plan 标记上的 × 回到 Execute;Agent 请求切换模式时,在界面中回应确认。
- 检查实际改动和执行结果,必要时回到 Plan 继续讨论。
flowchart LR
A["Plan:分析与方案"] --> B["用户确认切换"]
B --> C["Execute:执行任务"]
C --> D["检查结果"]
D --> APlan 限制由工具的声明和执行检查决定,不能仅靠提示词保证。Execute 也不等于自动批准所有操作:工作模式决定哪些工具能用,审批设置决定调用时是否需要你确认。外部 Agent 使用各自支持的模式与权限能力,不能直接假设与自定义 Agent 完全一致。
2.7 - JSON Schema 结构化响应
最近更新:
让回复可以被程序读取
Agent 默认返回 Markdown 文本,适合阅读,却不便于程序提取字段。在 Agent 上配置 Response Schema 后,最终回复会按你提供的 JSON Schema 返回一个 JSON 对象,Job、Agentflow 和调用 API 的程序可以直接读取其中的字段。
例如,审查文档的 Agent 可以返回 issues 数组,每一项包含 original、problem 和 suggestion;定时运行时把结果写入工单系统,无需再从整段文字里查找内容。
配置内容
Response Schema 是 Agent 创建和编辑对话框中的一个 Tab,内容为一个 JSON Schema 对象:
保存时的校验规则:
| 输入 | 结果 |
|---|---|
| 留空 | 关闭结构化响应,保持文本回复 |
| 合法的 JSON 对象 | 保存并在下一回合生效 |
| 非法 JSON、数组或单个值 | 显示错误,保存按钮不可用 |
推荐使用 JSON Schema draft-07。Anthropic 模型要求 Schema 写明 type 为 object、properties 为对象、required 为数组;全部字段都可选时写成 "required": []。使用 Anthropic Provider 的自定义 Agent 缺少这三项时,会在发出模型请求前报错。
支持范围
| 执行目标 | 传递方式 |
|---|---|
| 自定义 Agent(System) | 模型请求的响应格式 |
| Claude Code | CLI 的 --json-schema 参数 |
| Codex | Turn 的输出 Schema |
| Pi | 暂不支持 |
AGW 把 Schema 交给模型或 CLI,由它们按 Schema 生成结果;AGW 本身不逐项校验字段是否符合 Schema。自定义 Agent 开启 Generate Turn Summary 时,AGW 要求本轮最后一条完整回复中恰好有一个有效的 JSON 对象或数组,否则该回合报错结束,保留原有的执行记录。标记为 JSON 的 Result 内容无法解析时,Chat 显示 “Invalid structured result: expected one JSON object or array.”。
开始使用
- 打开 Agents,编辑一个 Agent,切换到 Response Schema。
- 粘贴 JSON Schema 对象,确认没有出现校验错误后保存。
- 在 Chat 中运行一个小任务,检查最终结果是否为预期的 JSON。
- 确认结构稳定后,把该 Agent 用于 Job 或 Agentflow 步骤。
flowchart LR
A["Agent 配置 Response Schema"] --> B["回合执行"]
B --> C["模型或 CLI 按 Schema 产生结果"]
C --> D["Chat 按 JSON 显示 Result"]
C --> E["Job、Agentflow 与 API 读取字段"]自定义 Agent 同时开启“Generate Turn Summary”时,AGW 从本轮最后一条完整回复中提取这份 JSON,作为本轮的 Result,不再调用 Summary Model Provider;Chat 把这条 Result 按 JSON 原样显示,不经过 Markdown 渲染。没有开启时,模型仍按 Schema 返回 JSON 文本,但它只是一条普通回复,按 Markdown 显示,也不产生 Result,因此 Conversation Settings 中的 Only Stream Turn Result 对它不生效。Claude Code 和 Codex 每个回合都会产生 Result。已选择的 Summary Model Provider 会保留,关闭 Schema 后继续生效。
Schema 只用于描述结果结构,不会被当作代码执行,也不会自动请求 $ref 指向的远程地址。字段能否被正确填写取决于所选模型的能力和指令写法,结构正确的 JSON 仍需要核对内容。
2.8 - 工具审批
最近更新:
在操作前确认
Agent 调用工具时,AGW 可以根据权限设置请求你的确认。你可以先查看工具名称和参数,再决定是否继续,适合需要检查文件修改或命令执行的任务。
| 权限模式 | 普通写入与执行工具的行为 |
|---|---|
| Always ask | 每次调用都请求确认 |
| Allow same arguments | 首次确认后,在当前会话中复用匹配参数的授权 |
| Full access | 自动批准普通工具调用 |
普通只读工具通常不需要执行审批。工具的权限声明决定是否需要审批,不是根据名称或命令看起来是否安全来判断。
怎样选择权限模式
第一次使用某项写入工具时,可以选择 Always ask,逐次查看它实际提交的参数。需要在同一会话重复相同操作时,Allow same arguments 可以复用已经确认且参数匹配的授权;参数改变后不能沿用这份授权。
选择 Full access 前,应先确认 Agent 的工具范围和工作目录。它减少普通工具调用的确认步骤,但任务结果仍需要核对。
开始使用
- 选择支持审批的 Agent,并在 Chat 中选择合适的权限模式。
- 发起任务;出现审批请求时,检查工具、参数与目标路径。
- 同意后继续执行,或拒绝该调用并补充你的要求。
- 检查工具结果,确认实际操作符合预期。
flowchart TD
A["Agent 请求调用工具"] --> B["检查模式与权限"]
B --> C["需要人工确认"]
C --> D["同意:继续调用"]
C --> E["拒绝:把结果交回 Agent"]Full access 不会跳过 Plan 的工具限制,也不会替你回答用户输入问题或工作流中的 HumanGate。Claude Code 支持原生工具审批桥接;当前 Codex 和 Pi 接入仅支持 Full access。权限下拉框始终列出三种模式,目标不支持的模式显示为不可选,并在下方说明原因。
在 Conversation Settings 中打开 Only Stream Turn Result 后,External Agent 和开启 Generate Turn Summary 的自定义 Agent 遇到需要人工确认的工具审批或提问时会被直接拒绝,界面不显示这些请求。Full access 以及已有授权的自动批准不受影响。需要逐次审批时,应关闭这个开关。
2.9 - 文件浏览与 Git 变更审查
最近更新:
在对话旁边检查 Agent 的修改
Agent 修改代码后,需要确认它改了哪些文件、每处改动是否符合预期。在 Chat 工作区切换到 Files,可以浏览 Project 工作目录中的文件、查看 Git 变更,并把需要调整的地方写成行评论交给 Agent,整个过程无需另开编辑器或终端。

查看变更
打开文件树顶部的 Diff 开关后,文件树只显示有 Git 变更的文件,并分为 Staged 和 Unstaged 两组。一个文件同时包含已暂存和未暂存的改动时,会在两组中各出现一次。文件名旁的字母表示变更类型:A 新增、M 修改、D 删除、U 未跟踪。
选中文件后,右侧左右对照显示改动前后的内容。Staged 分组对比 HEAD → Staged,Unstaged 分组对比 Staged → Working Tree。关闭 Diff 开关后,文件树显示完整目录,右侧显示文件的当前内容。
| 操作 | 入口 | 效果 |
|---|---|---|
| Stage / Unstage | Diff 模式下,鼠标移到文件或目录上,点击 + 或 - | 暂存或取消暂存该文件、该目录下的全部变更 |
| Reset to HEAD | 文件的右键菜单 | 把该文件的暂存区和工作区内容都恢复为 HEAD 版本 |
| Delete | 文件或目录的右键菜单,确认后执行 | 删除文件,或递归删除整个目录 |
Reset to HEAD 和 Delete 直接修改磁盘上的文件,界面中无法撤销,执行前应确认没有需要保留的改动。
用行评论交给 Agent 修改
在文件内容或 diff 中,把鼠标移到某一行,点击行号右侧出现的 + 按钮即可写评论,按 Ctrl/Shift+Enter 提交,按 Esc 取消。已有评论的行不再显示这个按钮;双击评论可以修改,点击评论旁的删除按钮可以删除。Diff 视图的左右两侧可以分别评论改动前和改动后的内容。
写好的评论会暂时保存,Chat 输入框上方显示待发送的评论数量,例如 “2 code comments”。切回 Chat 写下总体要求并发送后,每条评论的文件路径、行号、评论所在一侧(改动前或改动后)和所在分组会随这条消息一起交给 Agent。Server 接受这次执行后,已发送的评论会从待发送列表中移除;点击数量旁的 × 可以放弃全部待发送评论。
例如,Agent 完成一次重构后,打开 Diff 查看 Unstaged 分组:在新增的重试逻辑处评论“重试次数改为读取配置项”,在另一处评论“这个分支缺少错误日志”,然后在 Chat 中发送“请按评论修改,完成后说明每处改动”。审查通过的文件可以先 Stage,Agent 下一次修改这些文件时,新改动会出现在 Unstaged 分组中,便于区分已审查和待审查的内容。
flowchart LR
A["Agent 修改文件"] --> B["Files:打开 Diff 审查"]
B --> C["为需要调整的行添加评论"]
C --> D["Chat:随消息发送评论"]
D --> A
B --> E["审查通过的文件:Stage"]开始使用
- 选择一个工作目录位于 Git 仓库中的 Project。不在 Git 仓库中的目录也能浏览文件,但没有变更视图和 Git 操作。
- 在 Chat 工作区点击 Files。Project 配置了附加目录时,用文件树顶部的下拉框选择要浏览的目录。
- 打开 Diff 开关,在 Staged 或 Unstaged 分组中选择文件,检查改动。
- 为需要调整的行添加评论,切回 Chat 发送消息,再回到 Files 检查 Agent 的新改动。
适用范围
- 文件树、diff 和 Git 操作只作用于当前选择的目录。切换浏览目录不会改变 Agent 的默认工作目录,Agent 仍从主工作目录开始工作。
- Files 页面不创建提交,也不切换分支;需要这些操作时,可以交给 Agent,或在终端中完成。
- 待发送的评论只保存在当前页面中,切换 Project 或刷新页面后会清空。
- Mobile 可以浏览文件、查看 diff,并重置或删除文件;Stage、Unstage 以及把行评论发送给 Agent 在 Web 和 Desktop 中使用。
2.10 - 多端客户端
最近更新:
在合适的设备上继续工作
AGW 提供 Web、Desktop 和 Mobile 客户端。连接同一个 Server 并使用相应身份后,可以访问自己有权限的项目和服务端保存的会话记录,按场景选择设备。
| 客户端 | 适合的场景 |
|---|---|
| Web | 无需安装桌面客户端,在浏览器中管理和对话 |
| Desktop | 日常工作空间、多个 Server 配置、本机或远程使用 |
| Mobile | 在移动设备上查看对话、访问项目并继续交流 |

同一服务与不同服务的区别
在另一台设备上继续查看工作时,先连接同一个 Server,再选择同一个 Project 和会话。服务端保存的历史可以继续查看;尚未保存的实时输出可能需要等待写入或重新连接后确认。
不同 Server 分别保存自己的配置和记录。切换 Server 后看不到原项目时,先确认地址和身份,而不要立即重新创建项目。
开始使用
- 完成 Server 初始化,确保设备能够访问服务地址。
- Web 使用管理员密码或第三方账号登录。Desktop 使用 API Key 连接;Server 配置了身份提供商时,也可以点击 Sign in with … 用第三方账号登录,由 Server 签发 API Key。Mobile 手动填写 API Key,或用 Import Web configuration 粘贴 Web Settings 中 Copy config 复制的连接配置。
- 确认 Server 和 Project,打开已有会话或创建新会话。
- 检查历史记录和执行状态,避免因设备切换重复发起同一任务。会话列表中的图标显示 Running、Last turn failed 或 Last turn interrupted。
任务在实际执行主机上运行,手机或浏览器连接不会把执行环境搬到当前设备。Desktop Full 包含 Server,Desktop Client 连接已有 Server;Mobile 当前提供源码运行方式。不同客户端的布局与管理入口有所差异。
2.11 - 第三方账号登录
最近更新:
用已有账号进入自己的工作区
部署者在 Server 上启用身份提供商后,登录页会出现“Continue with …”按钮。你用组织账号(例如 Keycloak、Microsoft Entra ID、Google)或 OAuth2 服务(例如 GitHub)完成验证,就能进入 AGW,不需要再记一个管理员密码。
第一次用某个账号登录时,AGW 会为它创建一个独立的本地用户,并准备好默认 Project。此后 Agent、Project、对话记录、集成连接和 API Key 都归这个用户所有,其他用户看不到。管理员账号保持不变。
登录方式对照
| 方式 | 客户端 | 得到的凭据 |
|---|---|---|
| 第三方账号 | Web | 浏览器会话 Cookie |
| 第三方账号 | Desktop | 由 Server 签发的 API Key |
| 管理员密码 | Web | 浏览器会话 Cookie |
| API Key | Desktop、Mobile、自动化程序 | 手动配置的 API Key |
身份提供商未配置时,管理员密码和 API Key 继续可用。Mobile 目前使用 API Key 连接。
开始使用
- 请部署者在 Server 上启用身份提供商,并在提供商侧登记 AGW 的回调地址。
- Web:打开 Server 地址,在登录页选择对应的账号按钮,完成验证后回到原来要访问的页面。
- Desktop:在 Server 配置中选择“Sign in with …”,系统浏览器打开后完成验证,再回到 Desktop 窗口。
- 检查 Project 列表是否为该账号的数据;Desktop 的 Server 配置中会出现“Sign out”按钮。
flowchart LR
A["登录页选择账号"] --> B["身份提供商验证"]
B --> C["Server 校验并确定本地用户"]
C --> D["Web:写入会话 Cookie"]
C --> E["Desktop:一次性代码换取 API Key"]Desktop 使用系统浏览器完成验证,Server 通过 agw-desktop://auth/complete 把一次性代码交回 Desktop,Desktop 再用自己保存的校验值向 Server 换取 API Key。该代码两分钟内有效且只能使用一次,API Key 保存在系统凭据存储中。在 Desktop 中退出登录会撤销这个 API Key。
适用范围
同一个人在不同提供商下的账号是两个独立用户,AGW 按提供商签发者和账号标识判断身份,不按邮箱合并。当前不提供角色、管理员授权范围和 API Key 权限范围的设置;第三方账号登录得到的是普通用户身份。
停用某个提供商会阻止新的登录和尚未完成的 Desktop 换取,已经签发的 Cookie 和 API Key 需要单独处理。远程部署需要 HTTPS 地址。
3 - 使用指南
最近更新:
本章说明如何配置和使用 AGW 的各项功能。每篇指南都可以单独阅读;若还没有可用的 Agent,先配置模型提供商,再创建 Agent。
3.1 - 模型提供商
最近更新:
让自定义 Agent 回答问题之前,需要告诉 AGW 使用哪个模型、请求发往哪里,以及如何认证。模型服务商通常会提供 API 地址、模型 ID 和 API Key;请先准备好这些信息。
本页介绍 AGW 中的模型配置。已有命令行工具配置的用户,也可以按外部 Agent 指南接入。
三类配置
Provider 描述服务端点和认证;Model 描述模型及其限制;Model Provider 将两者关联,供 Agent 选择。仅创建 Model 不等于已经连通服务。
- 在 Providers 中打开 Create provider,选择匹配的协议类型并填写地址,在 Auth Configs 中添加并启用凭据。
- 切换到 Models 标签,勾选这个 Provider 提供的模型。协议为 OpenAI Chat Completions 或 OpenAI Responses,且 Auth Configs 中已有启用的 ApiKey 时,可以点击 Fetch Models 从服务端获取模型列表;Anthropic Provider 需要先在 Models 页面用 Create model 手动创建模型,再回到 Provider 中勾选。
- 保存 Provider。勾选的模型由此与 Provider 建立 Model Provider 关联,新获取的模型也会在这时创建。
- 在 Models 页面用 Edit model 核对模型标识,按服务商公布的限制填写 Context window 和 Maximum output。
- 在 Agent 中选择该关联,用短问题验证回复。
当前协议类型包括 OpenAI Chat Completions、OpenAI Responses 和 Anthropic。兼容服务也需要匹配具体协议,不能仅凭名称包含 OpenAI 判断可用性。

上下文限制
每个模型都有内容长度限制,填写时需要区分两个值:
- 上下文窗口:一次请求能容纳的内容总量,包括历史对话、当前问题、工具结果以及模型的回复。
- 最大输出 token:模型一次最多能生成多长的回复。token 是模型计算内容长度的单位,不等同于字数。
两个值都必须是正整数,且最大输出必须小于上下文窗口;表单会显示两者之差,即 Effective input budget(有效输入预算)。自定义 Agent 每次调用模型前按这个预算检查要发送的内容:超过 50% 时,较早工具调用的结果正文会从请求中移除;超过 80% 时,较早的消息组会被截断。两个阶段都保留最近 2 组消息,数据库中保存的会话历史不受影响。External Agent 的上下文由外部工具自行管理。
自动发现模型时,AGW 可能填入 256,000(上下文窗口)和 64,000(最大输出 token)作为默认值。这不代表所选模型实际支持这么长的内容,请按模型服务商公布的限制填写。数值设得过大,可能导致请求被拒绝;如果短对话正常、聊久后报错,先核对这两个值,再查看 Server 日志中的具体错误。
成功标志是 Agent 能完成一次对话。凭据无效、地址错误或模型不可用时,先修复连接,再添加工具。不要把真实 API Key 放入共享提示词或 Git 文件。
实现与参考
3.2 - 创建自定义 Agent
最近更新:
Agent 是一份可重复使用的助手配置:模型决定它如何理解问题,指令说明它要做什么,工具决定它能执行哪些操作。例如,可以分别创建“代码解释助手”和“文档审查助手”,在 Chat 中按任务选择。
开始前,先按模型提供商指南准备可用的 Model Provider。本页介绍由 AGW 运行的自定义 Agent;Claude Code、Codex 和 Pi 请参阅外部 Agent。
创建步骤
- 打开 Agents,点击 Create。Agent Type 保持
System(自定义 Agent),在 Display Name 中填写能表达职责的名称。 - 选择 Model Provider,在 Instructions 中写明任务、输入以及预期输出。填写 Display Name 并选择 Model Provider 之前,Create 按钮不可用。
- 按需在 Tools、Skills、MCP Tool Server、Integrations 和 Environment Variables 标签中配置能力;文件相关能力需要正确的 Project 工作目录。
- 保存并确认 Agent 已启用,在 Chat 选择它运行一个小任务。
例如,先创建只回答问题的“代码解释助手”,确认模型可用后再加入只读文件能力。提示词不能授予超出实际运行权限的工具访问。

写清 Agent 的职责
指令最好包含任务范围和输出要求。例如,文档审查助手可以使用:
先粘贴一小段文字验证输出。需要它直接读取项目文档时,再添加文件读取工具,并在对应 Project 中运行。能力是否可用取决于实际工具配置和权限,写在指令里的要求本身不会授予访问权。
让回复按 JSON 结构返回
需要由程序读取结果时,在创建或编辑对话框的 Response Schema 中粘贴一个 JSON Schema 对象:
保存要求内容是合法 JSON,且根节点为对象;留空表示关闭结构化响应。Anthropic 模型还要求写明 type 为 object、properties 为对象、required 为数组。Schema 会作为响应格式交给模型。自定义 Agent 同时开启“Generate Turn Summary”时,AGW 要求最后一条完整回复中恰好有一个 JSON 对象或数组,否则该回合报错结束;这份 JSON 直接作为本轮 Result,不再调用 Summary Model Provider。
外部 Agent 中,Claude Code 和 Codex 支持该配置;Pi 的 Response Schema 标签显示为不可用,Server 也会拒绝为 Pi 保存 Schema。完整说明见 JSON Schema 结构化响应。
每轮总结
自定义 Agent 可以打开 Generate Turn Summary:每个成功的回合结束后,AGW 用 Summary Model Provider 追加一段 Markdown 总结,作为本轮的 Result。未选择 Summary Model Provider 时使用 Agent 自己的 Model Provider。总结的输入只包含本轮用户文字和 Agent 的回复文字,不加载历史、工具或 Skills。External Agent 不提供这个开关。
开启后,这个 Agent 的回合会产生 Result,Conversation Settings 中的 Only Stream Turn Result 也会对它生效。
修改与复用
Agent 定义修改在下一回合生效,同时保留现有会话身份。活跃回合使用开始时的配置快照,不会在执行中途切换权限或目录。
Agents 列表中的 Copy agent 可以复制任何 Agent。复制 External Agent 时保留 Engine 类型、Model Provider、环境变量、Extra Settings 和 Response Schema,Instructions、Tools、Skills、MCP Tool Server 与 Integrations 不会复制。复制后应检查模型、能力与项目环境再运行。
验证
用一条与职责相符的问题验证输出,并检查工具活动是否只包含预期能力。若没有工具,检查绑定、工具目录以及 Connection 的 Ready 状态;不要用提高权限代替修复缺失配置。
实现与参考
3.3 - 接入外部 Agent
最近更新:
接入外部 Agent 后,任务由 Claude Code、Codex 或 Pi 等外部工具实际执行,AGW 提供统一的配置、对话和工作流入口。你可以继续使用熟悉的外部工具,同时在 AGW 中管理它们的使用方式。
前提:对应 CLI 已安装在实际执行节点,并能在 Server 使用的账号与环境下工作。浏览器里安装 CLI 无效;容器执行需要容器内可用。
同一种外部 Agent,多份独立配置
同一种外部 Agent 可以在 AGW 中创建多份 Agent 定义,每份分别选择模型和配置。例如,都使用 Claude Code 执行任务,但根据用途建立两个 Agent:
| AGW 中的 Agent | 实际运行的外部工具 | 使用的模型 | 用途 |
|---|---|---|---|
| Coding | Claude Code | model1 | 编写和修改代码 |
| Review | Claude Code | model2 | 审查代码并提出改进建议 |
创建这两个 Agent 时,都选择 External → Claude Code,再分别选择指向 model1 和 model2 的 Model Provider。这里的模型名称仅为示例,需要替换为服务商实际提供、且兼容 Anthropic 协议的模型。
这样,在 Chat 中选择 Coding 或 Review,就会使用各自配置的模型;也可以在 Agentflow 的不同节点中使用它们。无需为了切换用途反复修改同一份 Agent 配置。
这里的隔离是指 AGW 中各份 Agent 定义的配置独立,不会自动创建独立的操作系统账号或文件环境。如果未选择 Model Provider,模型来自该 Agent 的 Extra Settings 或外部工具自身的模型配置。
配置步骤
- 先在执行节点验证 CLI 可用,并完成它所需的认证或模型配置。
- 在 Agents 中点击 Create,Agent Type 选择
External,再选择外部 Agent 类型。类型创建后不能修改。 - 选择 Project,并确认主工作目录对执行进程可见。
- 按需选择兼容的 Model Provider;留空时使用 Extra Settings 或外部工具自身配置。需要传给外部工具的其他选项,填写在 Extra Settings 标签的 JSON 对象中。
- 发送一个简短任务,核对工作目录、输出和权限模式。
Claude Code 和 Codex 通过各自 SDK 的目录选项获得 Project 的附加目录,Pi 通过每一回合的上下文获得目录清单;三者的默认工作目录都是主目录。
| 外部 Agent | 可选 Model Provider | 权限说明 |
|---|---|---|
| Claude Code | Anthropic | 使用该目标声明的权限能力 |
| Codex | OpenAI Responses | 当前仅支持 FullAccess |
| Pi | 三种提供商协议均可 | 当前仅支持 FullAccess |

配置生效与限制
Chat 的权限下拉框始终列出三种模式,目标不支持的模式显示为不可选并说明原因;服务端也会验证能力。修改权限或 Agent 配置影响下一回合,当前回合保留开始时的配置快照。
在 Chat 中直接运行 External Agent 需要 InProcess 执行模式。Distributed 模式(包括 Control/Data Plane 分离部署)下,这类回合会报错 “Distributed execution currently supports System Agents only.”。
AGW 中的 Instructions、Tools、Skills、MCP Tool Server 和 Integrations 配置都不会交给任何 External Agent(包括 Pi),表单中的这些标签不可编辑;External Agent 只会读到已有的 User Memory 作为上下文。外部工具自身支持什么能力,需要在其环境中配置和验证。
CLI 不可用时检查可执行文件、运行账号、环境变量及服务日志。例如,终端中可运行而 AGW 中无法启动时,先检查 Server 账号的程序搜索路径(PATH)是否包含该 CLI。
实现与参考
3.4 - Chat 与执行记录
最近更新:
Chat 是向 Agent 或 Agentflow 提交任务、查看结果的地方。同一会话可以连续讨论一个问题,并保留回复和工具活动;不同主题可以新建会话,方便以后查找。
开始前,确认已连接预期的 Server,并有一个可运行的 Agent 或 Agentflow。第一次使用可先完成简单对话。
一次交互
- 打开 Chat,选择 Project:Desktop 在窗口顶部的项目标签页中选择,Web 在左侧栏顶部的下拉框中选择。然后在输入框左上方的选择器中选择执行目标。
- 输入任务,按需附加图片,按 Ctrl/Shift+Enter 或点击发送按钮发送;单独按 Enter 换行。
- 查看流式回复与工具活动;如果出现审批或用户输入请求,在当前会话中处理。
- 回看会话记录,确认结果与执行状态。
Web、Desktop、Mobile 支持文本和 JPEG、PNG、GIF、WebP 图片。Web 和 Desktop 通过粘贴添加图片,Mobile 从相册选择。每条消息最多 5 张,单张最多 5 MB,总计最多 10 MB。模型是否理解图片还取决于所选模型能力。

输入框中的辅助功能
| 操作 | 作用 |
|---|---|
在行首或空格后输入 / | 显示命令建议:自定义 Agent 列出可用的 Skills 和 Tools,Claude Code 列出它的斜杠命令 |
输入 @ | 搜索当前 Project 中的文件,最多显示 8 条 |
| 上下方向键与 Enter | 在建议列表中切换并选中 |
| + 按钮 | 开启 Plan mode(配置了 Mode ToolBlock 的自定义 Agent),或插入 Skills 和 Tools |
| 闪电按钮 | 打开 Quick Text Insert,插入在 Quick prompts 页面维护的常用文字 |
| 权限下拉框 | 选择工具权限模式,修改在下一回合生效 |
| Go to latest message / Go to first message | 跳转到最新消息,或加载完整历史并跳转到第一条消息 |
Quick prompts 页面分为 My prompts(当前用户自己的条目)和 System prompts(所有用户可见,只有管理员可以编辑)。Web 在导航中打开这个页面,Desktop 在 Settings 中打开。
怎样判断任务进行到哪一步
| 看到的情况 | 接下来做什么 |
|---|---|
| 回复或工具活动持续增加 | 等待执行完成,留意是否有错误 |
| 出现工具审批 | 查看操作名称、参数和路径,再决定是否同意 |
| 出现补充信息请求 | 在当前会话回答问题,让任务继续 |
| 执行结束 | 核对回复;涉及文件时检查实际文件或差异 |
| 报错或断线 | 先检查执行状态,再决定是否重试,避免重复操作 |
会话列表中的图标显示每个会话的状态:Running 表示仍在运行,Last turn failed 表示上一轮失败,Last turn interrupted 表示上一轮被中断。
回合结束并产生 Result 后,这一回合的工具活动和中间消息会收起为一行 “Worked for …”,点击可以展开查看。模型的推理内容默认收起,点击 Expand reasoning 展开。鼠标移到用户消息或 Result 上时,会显示发送时间和 Copy message 按钮。
“执行成功”表示处理过程成功结束,结果是否满足要求仍需检查。例如,要求修改文档时,应查看实际改动,而不只看 Agent 的完成说明。
会话列表与会话设置
会话列表顶部可以刷新列表、删除全部历史(Delete All History),并通过 Info 按钮打开 Conversation Settings;每个会话可以重命名或删除。
Conversation Settings 显示当前会话的 ID、消息数、创建时间和更新时间,还提供两项设置:
- Only Stream Turn Result:只推送每一回合的 Result,并自动拒绝需要人工处理的提问和工具审批;会话历史仍完整保存。它只对 External Agent 和开启 Generate Turn Summary 的自定义 Agent 生效,从下一回合开始生效。
- Environment Variables:随执行发送的环境变量。
这些设置按 Project 保存在当前客户端中,换一台设备或浏览器需要重新设置。
状态与连接
关闭页面或断开连接通常不会取消执行。InProcess 模式下,如果断线时本轮正在等待审批、用户输入或 HumanGate,Server 会中断本轮;Distributed 模式下断线不会中断执行。需要停止任务时使用界面提供的中断操作。
连接中断时,界面显示 “Reconnecting to Server…” 并自动重试,也可以点击 Retry now 立即重试。重新连接后客户端恢复执行状态;检查任务是否仍在运行、等待输入或已经结束。
Desktop 的每个 Server、Project、Conversation 组合有独立执行连接。切换 Project 页签会改变当前显示的会话,不会自动停止后台任务;项目标签页上的状态点显示后台任务状态,关闭仍有任务运行的标签页前会先确认。
历史
会话与工具活动由服务端持久化,历史采用批量写入。Host 模板将刷新间隔设为 10 秒,省略配置时的代码回退为 5 秒;不要把尚未刷新的实时输出当成已完成持久化。
打开会话时先显示最近的消息,向上滚动时每次加载 50 条较早的消息。Desktop 还提供用户输入导航,列出会话中的每一条用户输入,包括尚未加载的早期输入;点击后跳转到该输入,并按需加载更早的历史。
回合被中断或失败时,未完成的消息和带致命错误的消息仍显示在会话中,但不会进入后续回合的模型上下文,也不会交给切换后的 Agent。
如界面与预期不符,先确认 Server 和会话选择,检查等待输入状态,再看服务日志。工作目录与权限调整会在下一回合生效。
实现与参考
3.5 - Projects、文件与工作目录
最近更新:
Project 把一项工作的文件目录、背景资料和会话放在一起。例如,为一个代码仓库创建 Project 后,可以分别建立“阅读代码”和“排查问题”的会话,同时使用同一份工作目录。
运行 AGW Server 的账号必须能够访问这些目录。主工作目录不存在时,保存 Project 会自动创建;附加目录必须是已经存在的绝对路径或 ~ 路径,且不能与其他目录重复。连接远程 Server 时应填写远程主机上的路径;使用 Docker 时应填写容器内的路径。
配置工作空间
- 创建 Project,填写 Primary directory(主工作目录,必填)。在 Settings 的 Projects 表单中输入名称时,会自动填入
~/.agw/<项目文件夹名>;Desktop 标题栏新建 Project 时,Workspace (optional) 留空也使用这个路径。 - 如需同时浏览其他路径,添加 Additional directories。每个关联有稳定 ID;修改路径会生成新 ID。
- 在 Chat 工作区的 Files 中用目录下拉框切换浏览根,检查文件与 Git 访问,详见文件浏览与 Git 变更审查。
- 在该 Project 中运行 Agent,验证任务使用预期的主工作目录。
Project 表单还提供 Tools、Skills、MCP Tool Server、Integrations 和 Environment Variables 标签。这里的配置在运行时与自定义 Agent 自身的配置合并,适合放置整个 Project 共用的能力。
切换文件浏览目录不会改变 Agent 的默认工作目录。移除附加目录关联不会删除磁盘文件。网络存储应先通过操作系统或容器挂载,再将挂载后的路径配置为工作目录。

一个主目录与附加目录的例子
假设代码位于 /work/app,参考资料位于 /work/reference:将前者设为 Workspace,将后者添加为附加目录。Files 中可以切换到参考资料目录浏览,但 Agent 默认仍从 /work/app 开始工作。任务需要参考资料时,应说明资料位于哪个目录,并确保 Agent 具备读取能力。
Docker 中需要先把两个目录挂入容器。例如,主机的 /home/me/app 挂载为容器内的 /work/app 后,Workspace 应填写 /work/app。只在表单填写路径不会创建容器挂载。
自定义 Agent 的指令中会列出主目录和每个附加目录,并以目录名作为别名;对话时可以用别名指代某个目录,用 default 指代主目录。
通过 API 创建 Project 时如果不提供工作目录,Server 使用 ~/.agw/projects/{projectId:N},其中 {projectId:N} 是项目 ID 去掉连字符后的值。
修改何时生效
Project 更新会使本机文件系统缓存失效,文件浏览立即刷新。Agent 在每回合开始时捕获不可变目录快照;目录变更会在下一回合重建运行时并保留会话身份。当前回合、子执行与持久化恢复继续使用已经捕获的路径。
分布式执行的每个节点都必须能看到快照中的相同主机路径。不可用或不属于该 Project 的附加目录会失败,不会自动退回主目录。
排查
文件不存在时,核对当前浏览根、实际挂载、执行账号和 Server 路径。不要只在本地终端验证与 Server 不同的目录。非内置 Project 可以复制。副本会复制 Tools、Skills、MCP Tool Server、Integrations 和环境变量,但主目录改为 ~/.agw/projects/{新 ID:N},也不带任何附加目录;复制后需要重新设置目录。
实现与参考
3.6 - Agentflow
最近更新:
Agentflow 指 Agent Workflow(Agent 工作流),把多个处理步骤连接起来。例如,先由一个 Agent 整理材料,再由另一个 Agent 审查,最后请人确认结果。各步骤的输入、输出和先后关系都可以在画布中查看。
先单独验证每个 Agent 能完成自己的任务,再把它们接成流程。第一版建议只保留一条从输入到输出的路径,验证后再添加分支和审批。
创建第一个流程
- 打开 Agentflows 编辑器,从唯一的 Input 节点开始。
- 添加一个 Agent 节点,选择已验证的 Agent,连接 Input 与 Agent。
- 添加 Output 并连接输出,保存后在 Chat 中选择该 Agentflow 运行。
- 基础路径通过后,再加入 HumanGate、分支或并行节点。
编辑器画布右上角有 Undo 和 Redo 按钮,也可以使用 Cmd/Ctrl+Z、Cmd/Ctrl+Shift+Z 或 Ctrl+Y;节点面板和 Inspector 可以拖动分隔条调整宽度。存在未保存的修改时,对话框显示 Unsaved changes,关闭前会询问 Discard unsaved changes?;关闭对话框后,未保存的草稿不会保留。
Agentflows 列表中每个流程都有 Enabled 开关,以及 Run、Edit、Copy、View Mermaid chart 和 Delete 操作。Run 在右侧抽屉中打开一个使用内置默认 Project 的 Chat,适合快速试运行;需要在其他 Project 中运行时,在 Chat 中选择该 Agentflow。停用的 Agent 和 Agentflow 不会出现在编辑器的选择列表中。
flowchart LR
I[Input] --> A[Agent]
A --> H[HumanGate]
H --> O[Output]HumanGate 暂停并等待人工处理。Input 模式显示 Response 输入框和 Submit、Interrupt 按钮,提交的回复可用于下游条件判断;Approval 模式只有 Approve 和 Reject 两个按钮。Interrupt 和 Reject 都会停止流程。

Primitive Nodes(基础节点)
基础节点负责一个明确步骤:接收输入、调用 Agent、调整消息、等待人工处理或输出结果。在画布中选中节点后,在右侧 Inspector 配置其属性,再用连线确定前后关系。
Input:流程入口
Input 将本次用户输入传入流程。例如,在 Chat 中发送“审查这次修改”,这条请求会从 Input 进入下游节点。
每个流程只有一个 Input,ID 固定为 input,不能接收入边。可以从它连向一个节点,也可以通过 Fan Out 将输入分发给多个分支。
Agent:执行一项任务
选择一个已配置的 Agent,并按需填写节点名称和指令,说明它如何处理上游结果。例如,让“代码审查”节点检查上游提交的代码,并列出问题与修改建议。
节点接收上游内容,调用所选 Agent,再把执行结果传给下游。同一个 Agent 定义可以出现在多个节点中,各节点的模型会话历史分别保存;连线会传递任务内容,不会把另一个节点的完整模型会话合并过来。
先单独验证所选 Agent 的模型、工具和工作目录,再接入流程。节点指令也应符合该 Agent 类型支持的配置方式。
Workflow as Agent:复用子流程
通过 Select workflow 选择已有 Agentflow,将它作为一个步骤使用。上游消息成为子流程输入,子流程输出返回主流程,适合复用“收集资料 → 整理摘要”这样的固定过程。
先确认子流程可以独立运行,再将它放入主流程或编排块。流程之间不能形成递归引用,例如 A 调用 B、B 又调用 A;同一个子流程可以在不同分支中复用。
Prompt Adapter:补充处理指令
在 System Prompt / Instructions 中填写下游需要遵循的说明,例如“根据以下材料,按背景、问题、建议三个部分回答”。节点会把这段指令加到当前消息前面,再传给下游。
Prompt Adapter 本身不调用模型,也不会直接完成翻译、摘要或数据转换。要实际生成新内容,需要在后面连接 Agent。
Clear Messages:清除上游消息
Clear Messages 丢弃到达该节点的消息,以空消息继续下游流程,无需配置模型。例如,前一步已经把结果写入项目文件,下一步只需从文件重新读取,就可以用它避免继续携带前一步的大段文本。
它不会删除 Chat 记录,也不会清空下游 Agent 已有的会话历史。下游需要明确的任务指令或可读取的资料,不能再依赖已被丢弃的上游内容。
Human Gate:人工输入或审批
在需要人确认或补充信息的位置插入 Human Gate,并配置:
| 字段 | 如何使用 |
|---|---|
| Human Step Mode | 选择 Input 收集补充信息,或选择 Approval 请求审批 |
| Human Prompt | 写清需要人提供什么或批准什么,例如“请确认发布范围,并填写需要排除的模块” |
流程到达这里会暂停,在交互界面等待处理。Input 模式下,人在 Response 中填写回复并点击 Submit 后继续执行,这段回复可以用于下游连线的条件判断;Approval 模式下点击 Approve 继续执行,但不会带上文字回复。Interrupt 和 Reject 都会停止流程。因此,“需要修改”若应返回上游继续处理,应使用 Input 模式,通过人工回复和条件分支表达。
例如:Agent → Human Gate → Output 用于确认结果;也可以根据人工回复中的约定文字选择“修改”或“完成”分支。使用人工节点时,需要能够接收和回应请求的交互通道。
Checkpoint:保存恢复边界
Checkpoint 节点在代码中称为 CheckpointMarker。在 Checkpoint Name 中填写易于辨认的名称,例如“资料收集完成”,并将它放在希望保留执行进度的位置。
经过该节点后,系统在对应执行阶段结束时保存完整工作流检查点。Chat 中每个已保存的检查点显示为一张带 Checkpoint 标记的卡片,点击卡片上的 Resume 从这次保存恢复;检查点不可用时按钮禁用,并提示 “This checkpoint is unavailable”。恢复时选择的是一次具体保存记录,会从该状态创建新的执行分支,并移除当前会话中保存边界之后的记录。
恢复要求仍是同一用户、Project、会话和 Agentflow,流程定义未改变,且没有冲突的执行。单机 InProcess 检查点只在原运行时仍持有该记录时可恢复;Distributed 模式将检查点持久化到 PostgreSQL,可以跨断线或 Server 重启恢复。它不等于数据库备份,也不是任意节点的重新运行按钮。
Output:输出结果与可选总结
Output 将到达它的消息作为流程结果输出。简单流程可直接连接 Agent → Output。
新建的 Output 节点默认打开 Generate Summary,需要在 Summary Model Provider 中选择模型后才能保存;不需要总结时关闭这个开关。启用后会额外调用模型,把流入 Output 的多个结果整理成一份结论,追加在原有结果后;未启用时直接输出收到的消息。
Orchestration Blocks(编排块)
编排块把多个参与者组织成一个步骤,参与者可以是 Agent 或子 Agentflow。四种编排块在节点面板中分别显示为 Concurrent Block、Handoff Group、GroupChat Room 和 Magentic Team。添加编排块后,通过成员选择控件加入参与者;点击 Open 查看块内成员,分别配置名称和职责。主流程的连线连接到编排块,由块内部安排成员执行。
| 编排块 | 协作方式 | 适合场景 |
|---|---|---|
| Concurrent | 多个参与者同时处理相同输入,等待全部结果 | 多角度审查、独立分析 |
| Handoff | 从首个参与者开始,根据任务需要交接 | 分诊、专家转交 |
| Group Chat | 参与者按顺序轮流发言 | 多轮讨论、交替改进 |
| Magentic | Manager 制订计划并协调团队 | 需要动态拆解和调度的任务 |
Concurrent:并行处理
加入多个能够独立完成工作的参与者,例如安全审查 Agent 和性能审查 Agent。块会把相同输入交给所有成员并发执行,等待全部完成后,将各自的响应消息合在一起传给下游。
这种合并不会自动消除重复意见或生成统一结论。如需汇总,可以再连接一个 Agent,或启用 Output 的总结。成员之间有先后依赖时,应使用顺序连线;多个成员操作同一批文件时,还需避免互相覆盖。
flowchart LR
I[Input] --> C
subgraph C[Concurrent]
A[Security review]
B[Performance review]
end
C --> S[Summary Agent] --> O[Output]图中两个审查成员接收相同输入,汇总 Agent 在它们全部完成后处理结果。
Handoff:按需交接
第一个参与者是入口,负责先接收任务,再根据职责交给其他成员。例如,分诊 Agent 判断用户问题属于账单还是技术问题,然后转交对应专家。块完成后,结果继续传给主流程下游。
| 字段 | 作用 |
|---|---|
| Handoff Instructions | 说明何时交接,以及应交给哪类参与者 |
| Return To Previous | 允许交接后返回上一个参与者 |
| Autonomous Mode | 启用自动继续执行的模式 |
| Autonomous Turn Limit | 限制自治模式继续执行的轮次 |
| Continuation Prompt | 自动继续时使用的提示词 |
应为成员写清职责和交接条件,并为自治模式设置合理上限。Handoff 不保证每个成员都会被调用;如果每一步都必须执行,使用主流程的顺序连线更直接。
Group Chat:轮流讨论
加入参与者并确认成员顺序。当前实现按 Round Robin(轮询)顺序安排发言,成员围绕传入的任务轮流贡献结果,达到 Max Rounds 限制后结束。
例如,作者提出方案,审查者指出问题,再由作者修订。Max Rounds 限制调度迭代次数,不要理解成“每个成员都发言这么多次”;未配置时当前实现使用 10。
Group Chat 适合有明确讨论规则的有限轮协作。它不会自动等到所有成员达成共识;需要统一结论时,可以在块后增加总结 Agent。
Magentic:Manager 协调团队
加入参与者,并选择 Manager。未指定时使用第一个参与者,其余成员组成执行团队。Manager 根据输入任务安排计划和成员工作,适合需要在执行过程中调整分工的任务,例如调研后再决定需要哪些补充分析。
| 字段 | 作用 |
|---|---|
| Manager | 负责计划与协调的参与者 |
| Max Rounds | 整体调度轮次上限 |
| Max Stalls | 控制无进展状态的容忍次数 |
| Max Resets | 限制重新规划或重置的次数 |
| Require Plan Signoff | 要求对计划进行确认 |
为 Manager 写清目标、完成标准及成员职责,并根据任务设置轮次、停滞和重置上限。启用计划确认时,需要可交互的执行入口。Manager 完成协调后,块的输出继续交给主流程下游;任务不保证按固定成员顺序执行,也不保证每个成员都会被调用。
与固定顺序或并行执行相比,这种模式通常需要额外的模型调用来规划和协调。若步骤已经明确,先采用普通节点连线或 Concurrent 更容易检查结果。
Advanced Config JSON:高级配置
Advanced Config JSON 是节点附加设置的 JSON 表示,与右侧的表单控件编辑的是同一份配置。通常先用表单选择成员、填写参数;需要检查或调整完整配置时,再编辑 JSON。
使用双引号,开关写成 true 或 false,数字不加引号;不要添加注释或末尾多余的逗号。这里填写一个对象,例如 {},而不是整份工作流。名称、Agent 或子流程选择、System Prompt / Instructions 都有独立字段,不放进这个 JSON。
基础节点支持哪些字段
| 节点 | JSON 配置 | 填写方式 |
|---|---|---|
| Input | 无 | 固定入口,不显示高级配置框 |
| Agent | 当前没有专用字段 | 留空或 {};通过 Agent 选择器和指令框配置 |
| Workflow as Agent | 当前没有专用字段 | 留空或 {};通过工作流选择器引用子流程 |
| Prompt Adapter | 当前没有专用字段 | 留空或 {};在指令框填写要补充的说明 |
| Clear Messages | 无 | 不显示高级配置框 |
| Human Gate | humanMode、humanPrompt | 模式和给用户的提示语,示例见下方 |
| Checkpoint | checkpointName | 通过 Checkpoint Name 输入框填写;不显示高级配置框 |
| Output | 无(由 Generate Summary UI 配置) | 使用 Generate Summary 开关和 Summary Model Provider;不显示高级 JSON 编辑框 |
Human Gate 示例:
humanMode 使用 input(补充信息)或 approval(审批);未填写时,编辑器显示和运行时都按 approval 处理。humanPrompt 是用户看到的提示文字。
Checkpoint Name 在保存的数据中对应:
Output 的底层配置当前只有一个运行时字段 enableSummary,但 Output 节点不显示 Advanced Config JSON 编辑框,直接使用 Inspector 中的 Generate Summary UI 配置:
enableSummary: true(新建 Output 节点的默认值):Output 在主流程成功后,使用所选的 Model Provider 生成一段 Markdown 总结,并追加到最终输出末尾。enableSummary: false:Output 原样传递流入的消息,不额外调用模型。字段缺失时,Server 也按false处理。
启用总结后,必须同时满足以下条件,否则编辑器中的保存按钮不可用:
- 在 Output 节点的 Summary Model Provider 中选择有效的模型。
- 整个流程只能有一个 Output 节点,否则提示 “Summary requires exactly one Output node”。
总结模型接收的是流入该 Output 的消息。编辑器不为 Output 提供 Instructions 输入框。模型选择属于工作流配置,不能通过在节点 JSON 中添加 modelProviderId 或 summaryModelProviderId 来替代;任意其他字段不会增加 Output 能力。
编排块的成员配置
四种编排块都使用 participantNodeIds,值是成员的画布节点 ID,不是 Agent 定义 ID,也不是显示名称。编辑器已提供 Members、Max Rounds、Manager 等控件,编排块不显示 Advanced Config JSON;以下 JSON 说明这些控件保存的格式,不需要手动填写。
下面的 node-a、node-b 是占位示例,使用时必须替换为当前画布中真实的 Agent 或 Workflow as Agent 节点 ID。Concurrent 至少需要一个成员;Handoff、Group Chat 和 Magentic 至少需要两个成员。
Concurrent
只需指定并行成员,没有轮次或 Manager 配置:
Handoff
数组中的第一个成员先接收任务。handoffInstructions 描述交接规则;enableReturnToPrevious 允许返回上一成员;autonomous 开启自动继续。后两个字段仅在 autonomous 为 true 时使用,分别指定继续轮次上限和继续时的提示词。两个开关省略时均不开启;数字示例不是默认值。
Group Chat
按成员顺序轮流执行。maxRounds 是调度迭代上限,填写正整数;省略时 AGW 使用 10。它不是每个成员分别发言的次数。
Magentic
managerNodeId 必须是成员列表中的节点 ID,省略时由第一个成员担任 Manager。maxRounds 限制调度轮次,maxStalls 控制无进展状态的容忍次数,maxResets 限制重新规划或重置次数;在编辑器中填写正整数。requirePlanSignoff 控制是否要求确认计划。示例值用于说明格式;省略这些可选限制或确认开关时,采用底层工作流框架的默认行为。
保存前检查
确认成员 ID 存在、字段类型正确,并且参数属于当前节点。高级配置框不是脚本入口,添加任意键也不会自动获得新功能。修改 JSON 后检查 Inspector 中的表单显示是否符合预期,再保存并用小任务验证。
分支条件填写在连线的 Predicate JSON 中;If / Else If 连线不显示 Advanced Config JSON,分支顺序用 Move branch up 和 Move branch down 调整。它们都不放在节点的 Advanced Config JSON 中。
路由与约束
必须恰好有一个 ID 为 input 的 Input,且无入边;可运行节点必须从它可达。节点、边 ID 必须唯一,引用必须有效。
连线决定一个节点结束后,哪些步骤继续执行。在连线的 Edge Type 中选择:
| 连线方式 | 含义 | 设计时注意 |
|---|---|---|
| Direct | 直接交给下一步 | 适合固定顺序 |
| Fan Out | 同时分发给多个分支,条件匹配的分支都会执行 | 各分支应能独立处理输入 |
| If / Else If | 按顺序检查条件,只把消息交给第一个匹配的分支 | 可以再添加一条 Else,在条件都不匹配时使用 |
| Fan-in Barrier | 等待同组的各个来源到齐,再继续 | 每个被等待的分支都必须有机会到达 |
同一来源节点不要混用 Direct、Fan Out 和 If / Else If。例如,If / Else If 只会选择一条分支,却让后续汇合点等待所有分支,就可能一直等不到结果。
工作流允许符合安全规则的受控循环。需要重复处理时,先验证退出条件,再增加嵌套流程、编排块或检查点,避免一次加入太多分支而难以定位问题。
验证与历史
分别测试正常路径、条件不匹配、人工拒绝及需要等待的路径。运行时,Chat 会在当前回合中把每个节点收到的输入显示为单独的输入气泡,并保留上游节点归属,可以据此检查执行顺序。CheckpointMarker 标记完整 MAF 检查点的边界;恢复不是随意从某个节点重新开始。修改流程前保留可工作的版本,查看执行记录确认节点归属。
实现与参考
3.7 - Jobs 定时任务
最近更新:
Job 用于在指定时间自动运行 Agent 或 Agentflow,适合例行检查和定期整理资料。任务要求、所属 Project 和执行时间保存后,Server 会按计划发起执行,并记录每次结果。
先在 Chat 中手动验证同样的任务,确认模型、工具和目录都可用。定时执行期间 Server 必须保持运行;分离部署时,控制面负责调度,数据面负责执行。
配置步骤
- 在 Jobs 创建任务,在 Project ID 中选择 Project,在 Agent ID 中选择要运行的 Agent 或 Agentflow。没有选择执行目标的任务也能保存,但运行时会失败并进入重试。
- 写明提示词,选择 Trigger Type 并填写执行时间或触发值。
- 需要修改任务名称、失败重试次数或启用状态时,点击对话框底部的 Advanced,在 Job Name、Max Retry Count 和 Enabled 中设置。Max Retry Count 默认为 3,任务默认启用;Job Name 留空时自动生成。
- 首先使用未来的一次性任务验证,确认 Job 日志和项目执行记录符合预期后,再新建一个周期任务。一次性任务成功后会暂停并禁用,之后把它改为周期触发或重新启用,它都不会再次运行。
| 触发方式 | 示例 | 时间语义 |
|---|---|---|
| Once | 未来的 RFC 3339 时间,如带 Z 的 UTC 值 | 必须是未来时间 |
| Interval | 00:15:00 | 使用正数时长,格式为小时:分钟:秒。第一次在创建后 15 分钟执行,之后从上一次成功执行结束时再计算 15 分钟 |
| Cron | 0 1 * * * | 标准五段,按 UTC 计算,每天 01:00 UTC |
客户端显示本地时间,但 Cron 按 UTC 计算。不要把过去的 Once 时间当作“立即执行”。Interval 不是正数的“小时:分钟:秒”时长,或 Cron 不是五段时,输入框下方会显示错误,保存按钮不可用;五段但字段取值无效的 Cron 在保存时由 Server 返回 “Invalid cron trigger value”。保存后在任务列表的 Next Run 中核对下一次执行时间。

写一条能独立执行的任务要求
定时任务开始时未必有人补充说明,提示词应交代资料位置、时间范围和输出要求。例如:“读取项目中的本周进展记录,列出已完成事项、未解决问题和下一步建议;缺少记录时明确说明,不要推测。”使用前要为目标 Agent 配好读取能力。
0 1 * * * 表示每天 UTC 01:00,对新加坡或中国标准时间是当天 09:00。保存后在任务列表或详情的 Next Run 中核对下一次执行时间。若设置最多重试 2 次,则本轮最多尝试 3 次:首次执行加两次重试。
执行、重试与暂停
同一 Project 的定时任务串行,不同 Project 可以并行。每次执行都会在该 Project 中新建一个会话,以 Full access 权限运行,并自动拒绝需要人工回答的提问和审批。一次性任务成功后暂停并禁用;周期任务成功后安排下一次执行。失败后在 30 秒后重试,MaxRetryCount 不含首次尝试。重试耗尽后任务暂停并禁用,周期任务也不再安排下一次执行;需要继续运行时,应修正问题后新建任务。
每次执行尝试都会记录时间、结果和错误。禁用任务只阻止后续调度,不会中断正在运行的任务;执行期间编辑或删除可能被拒绝,需要等本次执行结束。调度器会提前读取即将到期的任务,改期后应再次核对任务状态和执行记录。
没有执行时检查初始化、启用状态、下一次运行时间和有效目标。对于写入外部系统的任务,应让操作可重复执行,不能把项目锁视为 exactly-once 保证。
Job Logs:查看每次执行结果
Job Logs 记录一个 Job 的每次执行尝试,用来确认任务是否运行成功、是否发生重试,以及失败原因。它记录执行结果;模型的完整回复和工具活动需要进入 Chat 查看。
打开执行日志
- 在 Jobs 列表找到任务,点击该行的日志入口,进入 Job Logs。
- 根据执行时间找到要检查的记录,查看状态、尝试次数和错误信息。
- 点击该行的 Go to Chat 打开这次执行对应的会话,查看对话和执行内容;这次执行还没有会话记录时,只打开该 Job 所属的 Project。
任务详情中的 Execution Logs 也可以查看尝试记录和错误,Back to Jobs 则返回任务列表。
如何理解字段
| 字段 | 含义 |
|---|---|
| Status | Succeeded 表示该次尝试成功结束,Failed 表示失败 |
| Attempt | 本轮执行的尝试序号:#1 是首次尝试,#2 是第一次重试,不是任务累计运行次数 |
| Job ID | 这些记录所属的任务标识,同一个 Job 的多条记录使用相同 ID |
| Time | 本次尝试的开始时间,以及已有的结束时间;按客户端本地时间显示 |
| Error | 失败原因;没有错误信息时显示 - |
| Actions | 通过 Go to Chat 查看对话内容 |
例如,同一轮执行先出现 Failed / #1,随后出现 Succeeded / #2,表示首次失败、重试成功。周期任务成功后会重置重试计数,因此后续记录再次出现 #1 是正常现象;应结合时间区分不同轮次。
用日志排查问题
- 没有记录:先检查任务是否启用、是否到达执行时间,以及当前是否仍在运行。日志在尝试结束并记录结果时写入,空列表不一定表示调度没有启动。
- 执行失败:先看 Error,再通过 Go to Chat 检查模型回复和工具活动。连接不到模型、工具执行失败或工作目录不可用时,结合 Server 日志定位原因。
- 日志成功但结果不符合预期:Succeeded 表示执行成功结束,仍需检查实际输出、生成文件或外部操作是否符合任务要求。
- 有失败记录但任务已恢复正常:保留的失败记录不会因后续重试成功而消失,按时间检查后续尝试和任务当前状态。
定时与后台执行
Jobs 可以在指定时间、固定间隔或 Cron 计划下运行 Agent 或 Agentflow,适合周期汇总、例行检查等工作。后台 Agent 能力则用于把子任务交给其他 Agent,并在后续获取结果。
- 先确认 Project、执行目标和所需工具可以正常工作。
- 为周期任务创建 Job,填写任务要求和触发时间;需要委派子任务时配置 Background Agents 能力。
- 在任务记录中查看状态、结果与错误,按实际需要调整计划。
关闭 Chat 页面不会自动取消执行;但 Server 和实际执行节点必须保持运行。后台 Agent 不能停下来等待新的人工审批;无人值守 Job 遇到必须由人回答的问题或 HumanGate 时也无法自动完成。持续运行不代表所有任务都能在服务重启后无缝恢复,恢复能力取决于部署与执行方式。
配置工具与 Skills · 了解记忆能力 · 查看执行状态
实现与参考
3.8 - Tools 与 Skills
最近更新:
工具(Tool)负责具体操作,例如读取文件;Skill 提供完成某类任务的说明、资源和可选工具。为 Agent 选择能力时,先确定任务需要读什么、改什么,再配置相应工具和说明。
以下步骤面向已有自定义 Agent 和 Project 的用户。外部 Agent 的能力需要按其自身支持的方式配置。
添加能力
- 在 Agent 或 Project 的 Tools 标签中查看可选工具:ToolBlock 卡片显示用途说明、包含的成员工具,可能需要审批时还会显示 Approval 标记;单个工具在下拉列表中显示名称、说明和分类。
- 在 Skills 管理可用 Skill,阅读其说明与前提。
- 在 Agent 中绑定本次任务需要的工具和 Skills。
- 在正确的 Project 中开始新回合,先验证读取类任务,再验证确实需要的写操作。
每个工具显式声明 AgwToolPermission。运行权限由执行管线检查;提示词写“允许”不会跳过权限或资源归属验证。
内置 ToolBlock
| ToolBlock | 用途 | 可配置在 |
|---|---|---|
| Todo | 用持久保存的待办清单跟踪多步骤工作 | Agent、Project |
| Mode | 在 Plan 与 Execute 之间切换,见 Plan 与 Execute 模式 | Agent、Project |
| File Access | 读取和修改 Project 工作目录中的文件 | Agent、Project |
| User Memory | 当前用户跨 Project 使用的记忆 | Agent、Project |
| Project Memory | 当前 Project 共享的记忆,保存在数据库或主目录中,见记忆 | Agent、Project |
| Background Agents | 把工作委派给明确允许的 Agent,需要在 Allowed delegation targets 中选择目标 | 仅 Agent |
File Access 中的 file_access_read、file_access_read_lines、file_access_ls 和 file_access_grep 是只读工具,可以在 Plan 模式中使用;file_access_write、file_access_delete、file_access_replace 和 file_access_replace_lines 需要写入权限。

Local 与 Remote Skill
创建 Skill 时,可以按内容的维护方式选择模式:
| 模式 | 内容来源 | 更新方式 |
|---|---|---|
| Local(本地) | 上传包含 SKILL.md 的 ZIP 包,文件保存在 AGW 服务端 | 编辑 Skill 并上传新版 ZIP 包 |
| Remote(远程) | 填写可通过 HTTP 或 HTTPS 下载 Skill ZIP 包的网址 | 在远程更新内容,AGW 按缓存规则重新获取;编辑并保存 Remote Skill 也会重新获取内容 |
Local 中的“本地”指 AGW 服务端,不是浏览器所在的电脑。Remote 表示说明内容来自远程地址,任务仍由 Agent 执行。
- 在 Skills 中创建 Skill,选择 Local 或 Remote。
- Local 填写名称和描述,上传含
SKILL.md的 ZIP 包;Remote 填写 ZIP 下载地址,无需上传文件。AGW 以不带认证信息的 GET 请求下载 Remote 地址,需要登录或 Token 才能访问的地址无法使用。 - Remote 包中必须恰好有一个
SKILL.md,其中的 YAML 元信息需包含name、description,正文需包含使用说明。名称和描述由远程文件提供。 - 保存成功后,在 Agent 或 Project 中选择该 Skill,再用一个相关的小任务验证说明是否可用。
Remote Skill 当前读取包内的说明,不会下载并运行包中的脚本,也不会提供包内其他资源文件。需要这些文件时应选择 Local 模式,并准备好执行环境。
Remote Skill 缓存
AGW 在创建或保存 Remote Skill 时获取内容,并将其缓存到数据库中,缓存有效期为 1 小时。
- 有效期内读取同一个 Skill 时,直接使用缓存,减少重复下载。
- 缓存过期后,在下一次需要读取该 Skill 时重新获取;不是每小时定时下载。
- 远程内容更新后,可以等待缓存过期,或编辑并保存该 Remote Skill 来重新获取内容。
- 刷新失败时会报错,不会延长旧缓存的有效期或继续使用过期内容。先检查服务端能否访问下载地址,以及 ZIP 和
SKILL.md格式是否正确。
自动刷新时,远程 name 必须与已保存的 Skill 名称一致。若远程改了名称,需要编辑并保存 Skill 以更新定义。缓存刷新也不会改写已经加载到当前对话中的内容,验证新版说明时应让 Agent 重新读取 Skill。
Skill 专属工具
Skill 拥有的工具只通过该 Skill 注册,在运行时绑定 Project,不是全局工具目录条目。没有在全局列表看到它,不代表它不可用。
例如 agw-job 提供 agw_job_list、agw_job_get、agw_job_create、agw_job_update、agw_job_delete。读取在 Plan 模式可用,写入在 Plan 模式禁止。

检查结果
查看工具活动的名称、参数及返回值,确认使用了预期的 Project。能力缺失时检查 Skill 绑定和运行模式;实际需要外部服务时,继续配置 MCP 或 Integrations。
实现与参考
3.9 - MCP 服务
最近更新:
MCP(Model Context Protocol)是一种让 Agent 使用外部工具的协议。MCP 服务会列出自己提供的操作,AGW 连接后可将这些工具交给自定义 Agent 使用。具体能做什么取决于所连接的服务。
配置前,准备服务提供的启动命令或地址、连接方式,以及所需凭据。模型本身仍在 Model Provider 中配置。
连接路径
- 在 MCP Tool Servers 页面点击 Add Server,在 Transport Type 中选择
stdio或http,按服务要求填写命令或端点与凭据。 - 本地进程服务需要执行节点能启动对应命令;远程服务需要从执行节点访问。
- 在列表中点击 Connect and list tools 检查连通性,成功时显示 “N tools available”。确认 Enabled 已打开,停用的服务不会被使用。
- 在自定义 Agent 或 Project 的 MCP Tool Server 标签中绑定该服务,开启新回合;运行时使用 Agent 和 Project 绑定的全部服务。
- 检查可发现的工具,使用一个只读操作验证返回内容。
目录、命令和网络都以实际 Server/执行节点为准。远程 Desktop 连接不会使本机安装的 MCP 服务自动出现在 Server 上。

选择连接方式
| 方式 | 如何连接 | 配置前检查 |
|---|---|---|
| stdio | AGW 启动一个进程,通过它的输入输出通信 | 执行主机上有对应程序,命令、参数和工作目录正确 |
| http | AGW 访问正在运行的工具服务。连接 SSE 服务时也选择 http,AGW 会自动识别服务使用的 HTTP 传输方式 | 服务地址和认证方式正确,执行主机能够访问 |
例如,stdio 命令在个人终端能运行,但 Server 使用另一个账号或运行在容器中时,可能找不到同一个程序。应在 Server 所用环境中检查命令和环境变量。远程地址则需要从执行主机测试连通性。
与 Integrations 的区别
MCP 是工具协议。Integration 是带目录定义、用户配置、凭据和 Connection 生命周期的能力接入方式;Integration 自身也可以通过 MCP 暴露工具。
Plugin MCP 支持 stdio、HTTP 和 SSE 源。向 HTTP/SSE 注入凭据的 Plugin MCP 源必须使用 HTTPS;凭据在调用作用域中解析,不应放进公开 URL 或提示词。
故障排查
运行时无法连接的 MCP 服务会被跳过,Server 日志中记录警告,本回合继续执行;工具名称无效或与其他工具重名时,本回合会报错。stdio 服务启动时,执行时传入的环境变量会覆盖服务配置中的同名变量。
工具未出现时检查绑定、启动命令、可执行文件、网络可达性与凭据。先在相同执行环境确认服务可用,再重试新的 Agent 回合。外部 CLI 的 MCP 配置按其自身机制处理,不等同于 AGW Connection 注入。
实现与参考
3.10 - 配置 Integrations
最近更新:
集成让自定义 Agent 使用已授权的外部服务账号,例如读取 GitHub 中的资料。同一种服务可以配置多个账号,Agent 选择其中一个使用。当前内建目录提供 GitHub。
开始前,准备服务要求的认证资料,并确认该账号可以访问任务需要的资源。
选择服务并配置账号
- Available integrations:可供配置的全局目录定义。
- Configured integrations:当前用户配置好的账号或服务端点。
- Connection:实际选择和绑定的连接实例;同一集成可配置多个账号。
- 在 Available integrations 的 GitHub 卡片上点击 Configure,完成所选认证方式要求的 setup。GitHub 的 OAuth 需要填写 OAuth App 的 Client ID 和 Client Secret;对话框中显示的 OAuth callback URL 需要登记到 GitHub 的 OAuth App 中。
- 在目录卡片中对应认证方式的那一行点击 New integration 创建 Connection,填写 Display name 和清晰的 Alias。保存新的 OAuth Connection 后,AGW 会自动打开授权页面。
- 确认连接状态为 Ready,再将具体连接绑定到 Agent 或 Project。连接卡片上的 Authorize 可以重新授权,Validate 可以重新检查连接。
- 在自定义 Agent 的新回合执行一个读取操作,核对访问的是预期账号。
Alias 创建后不可修改,并在当前用户内唯一;只能使用小写字母、数字和单个连字符,最多 128 个字符,输入的大写字母会转为小写。Connection 工具名称使用 {alias}__{operation},便于区分账号。GitHub 连接提供 {alias}__current_user、{alias}__list_repositories 和 {alias}__clone_repository 三个工具,分别用于读取当前账号、列出可访问的仓库,以及把仓库克隆到当前 Project 工作目录。


所有权与凭据
安装设置和 Connection 都属于当前用户。修改接入设置后,当前用户的相关连接需要重新检查;其他用户的连接不受影响。Agent 只能使用属于当前用户且处于 Ready 状态的连接。凭据读取、OAuth 和工具调用都验证所有权。
当前限制
没有远程 Plugin Marketplace 的下载、签名或升级机制;不执行第三方 Plugin Skill 自带脚本;Connection 不注入任何 External Agent(Claude Code、Codex、Pi)。连接变化不应被理解为实时改写已创建的工具列表,修改后使用新回合验证。
实现与参考
3.11 - Web、Desktop 与 Mobile
最近更新:
前提:Server 已完成初始化。客户端不会替代服务端的模型、文件或执行环境。
| 客户端 | 连接方式 | 适用场景 |
|---|---|---|
| Web | 管理员密码或第三方账号登录得到的会话 Cookie;同源 API 访问 | 浏览器管理与对话 |
| Desktop | API Key,可手动填写或由第三方账号登录签发,支持多个 Server profile | 本机或远程的日常工作空间 |
| Mobile | API Key,可手动填写或导入 Web 生成的连接配置,支持多个 Server profile | 移动设备上的对话与项目访问 |
使用步骤
- Web 打开 Server 地址;源码开发时打开端口
3001。 - Desktop Full 可使用内置 Server。Client 在 Settings → Connections & app 中点击 +(Add remote Server),填写 Name、Server URL 和 API token。远程 Server 使用
http://地址时,需要勾选风险确认,说明 API token 和通信内容会在网络上以明文传输。 - Mobile 配置可从设备访问的 Server 地址与 API Key;设备上的 localhost 通常不是开发电脑。也可以在 Web 的 Settings → Server access 创建 API Key 后点击 Copy config,再在 Mobile 的 Import Web configuration 中粘贴。删除 Mobile 上的 profile 不会撤销 Server 端的 API Key,需要在 Web 中撤销。
- 创建一个短会话,确认连接目标、Project 与历史记录。
Desktop 以 Chat 为主界面,Projects 和其他管理入口在 Settings 中。Server profile 切换使用独立缓存,修改地址或 API Key 后,会清除旧连接使用的缓存,避免混入其他 Server 的数据。

第三方账号登录
Server 启用身份提供商后,Web 登录页会显示对应的账号按钮,选择后完成验证即可回到原来要访问的页面。Desktop 在 Server 配置中显示“Sign in with …”,系统浏览器完成验证后自动获得 API Key,无需手动粘贴;同一处提供“Sign out”撤销该 API Key。内置的本机 Server profile 处于第三方账号登录模式、且没有可用 API Key 时(例如退出登录或 API Key 过期后),还会显示“Use local administrator”。
Mobile 不支持第三方账号登录,使用手动填写或导入的 API Key。每个第三方账号是一个独立用户,数据与管理员账号分开。配置方法见配置与认证,行为说明见第三方账号登录。
运行差异
Desktop renderer 自用端口 3000,不依赖 Web 开发服务器。Full 的 Server 守护进程在关闭桌面窗口后仍继续运行;默认关闭窗口会缩到托盘。
Mobile 使用 Expo,原生工程由 CNG 生成。当前文档提供源码运行入口,不假设存在应用商店安装包。远程访问建议使用 HTTPS,确保代理允许执行所需的 WebSocket。
实现与参考
4 - 部署运维
最近更新:
本章面向负责安装和维护 Server 的用户。首次部署可从单机开始;只有需要拆开管理与执行服务时,才需要阅读分离部署。
- 单机与 Docker 部署:启动服务、保存数据并挂载项目目录。
- 分离部署:准备共享服务,配置控制面、数据面和代理路由。
- 配置与认证:按用途查找配置项、默认值和生效方式。
- 备份与升级:保留数据库、密钥和文件,验证能否恢复。
- 日志与常见问题:按故障现象逐步排查。
4.1 - 单机与 Docker 部署
最近更新:
Standalone 在一个 Server 中提供管理页面、对话执行和定时任务,适合本机试用或单台主机部署。默认使用 SQLite 保存数据,由当前进程运行任务,无需另行部署数据库服务。
可以使用 Docker 镜像,或自行构建与操作系统及处理器架构匹配的 Portable Server。两种方式都包含 Web 界面;下面先完成本机访问,再说明目录挂载和远程访问。
Docker 本机试用
打开 http://localhost:30816/setup 完成初始化。通过 Docker 端口映射访问时,容器看到的请求来源不是回环地址,Setup 页面会要求填写一次性 Setup Code;用 docker logs agw 在启动日志中查找 “Agw remote setup code”。镜像包含静态 Web,浏览器直接访问 Server 即可。示例的 latest 适用于试用;持续运行的部署应换成 Releases 对应的固定版本标签。
要让 Agent 访问主机项目,额外添加显式 bind mount,再将容器内路径配置为 Project Workspace。不要将主机路径误填成容器可见路径。
Portable Server
Portable Server 不随 Release 提供,需要在仓库根目录构建,例如:
产物位于 artifacts/publish/portable/agw-server-<版本>-<RID>/,同时生成对应的压缩包。在产物目录中启动:
Windows 使用 agw-server.exe serve。默认监听 http://127.0.0.1:30816,需要调整时使用 ASPNETCORE_URLS。未设置 ASPNETCORE_URLS 且 30816 端口已被占用时,Server 会改用一个随机的本机空闲端口,并把实际地址记录在 <AgwDataDir>/runtime/server.json 中。先验证本机 Setup、Web 和一次对话,再配置远程访问。
持久化与网络
Docker 数据目录为 /data,日志默认独立写入工作目录下的 logs;持久化文件日志需要另外挂载配置的日志路径。Project Workspace 也独立于数据卷。
远程部署需要正确配置 AllowedHosts、受信代理、HTTPS 和 WebSocket 转发。仓库 Compose 是带域名与代理配置的示例,使用前替换成真实环境值。完整持久化范围见备份与升级。
实现与参考
4.2 - Control/Data Plane 分离部署
最近更新:
分离部署把管理和调度放在 Control Plane(控制面),把任务执行放在 Data Plane(数据面)。需要单独维护执行环境或增加执行节点时,可以采用这种方式;只在一台主机试用时,Standalone更容易配置。
本页面向熟悉容器、数据库和反向代理的部署者。开始前,准备共享 PostgreSQL、用于解密凭据的 Data Protection 密钥,以及各执行节点都能访问的工作目录。入口代理还需要支持 WebSocket,以便持续传输对话事件。
角色
| Host | 职责 |
|---|---|
| Control Plane | Setup、Web、管理 API、Jobs 调度 |
| Data Plane | SignalR Execution、A2A、持久化执行 workers |
| Standalone | 合并两种职责,适合单机 |
分离部署使用 Distributed 执行模式。在这种模式下,Chat 中直接运行 External Agent(Claude Code、Codex、Pi)的回合会报错 “Distributed execution currently supports System Agents only.”;需要直接使用这些外部 Agent 时,应选择 InProcess 执行的 Standalone。
分离部署要求两端使用 PostgreSQL 数据库、Distributed 执行和 PostgreSQL 锁。不能使用 SQLite 或内存锁替代跨节点协调。
这是注入两端的环境配置片段。连接字符串为空的锁配置复用数据库连接;实际数据库连接字符串通过 Secrets 提供。
启动与路由
- 按仓库 cluster Compose 配置数据库、两个 Host、共享密钥和目录。
- 先启动 Control Plane,完成初始化并确认就绪:
GET /api/health/ready在未初始化或数据库无法连接时返回 503,就绪后返回 200;GET /api/health/live只表示进程在运行。这两个地址不需要登录。 - 再启动 Data Plane,最后按需要增加副本。
- 将
/api/hubs/exec、/a2a/*和/.well-known/agents.json路由到 Data Plane,其余应用路径到 Control Plane。
保留 Host、认证头/Cookie 和 WebSocket Upgrade;执行 Hub 查询字符串不应写入代理访问日志。Control Plane 不提供 A2A。
如何阅读下面的示例
Docker Compose 部署从文末的 cluster Compose 文件开始,并按上一节验证启动顺序和路由。Kubernetes 部署可参考下面的本地 kind 示例;其中 kind 是在容器中运行本地 Kubernetes 集群的工具,Pod 是运行应用的单元,Service 提供访问地址,PV/PVC 用于声明和申请存储。
两种部署都需要统一的客户端入口。Nginx 一节说明哪些请求发送到控制面、哪些发送到数据面。先确保两个服务和数据库可用,再检查入口转发,便于区分服务自身与代理的问题。
Kubernetes YAML 示例
仓库的 deploy/k8s 提供一套本地单节点 kind 示例。它将 Control Plane 和 Data Plane 分成独立 Deployment,使用外部 PostgreSQL,并通过 NodePort 接入后文的 Nginx 配置。以下内容对应这些文件,不会额外创建 PostgreSQL 或 Ingress Controller。
| 文件 | 用途 |
|---|---|
| kind-agw-cluster.yaml | 创建本地 kind 集群,映射端口与宿主目录 |
| agw-data-pv-pvc.yaml | 提供共享给同一节点上各 Pod 的数据卷 |
| agw-control-plane-deployment.yaml | 1 个 Control Plane 副本和 NodePort Service |
| agw-data-plane-deployment.yaml | 2 个 Data Plane 副本和 NodePort Service |
集群入口与共享目录
kind-agw-cluster.yaml 将两个 NodePort 映射到宿主机的回环地址,同时将 /opt/agw 挂入 kind 节点:
创建集群前,在容器运行时所在主机准备 /opt/agw/agw-data。使用 Docker/Podman 虚拟机时,还需通过文件共享配置使该路径在虚拟机中可用。role: control-plane 指 Kubernetes 节点角色,与 AGW 的 Control Plane 服务不是同一概念。
数据的实际路径为:
下面是对应的 PV/PVC。Retain 保留回收后的卷数据,但不代替备份;PVC 的 1Gi 是请求容量,PV 声明的容量为 5Gi。
ReadWriteOnce 允许同一节点上的多个 Pod 挂载,因此本例两个角色及 Data Plane 副本可以共用该卷。hostPath 不提供跨节点共享存储;多节点部署需要替换成集群支持的共享存储,并保证密钥、凭据和 Project 工作目录在各执行节点一致。若项目目录位于 /data 之外,还需为这些目录添加相应挂载。
Data Plane Deployment 与 Service
以下是仓库中的完整 Data Plane 示例。它运行两个副本,监听容器端口 8080,读取 agw-database Secret,并将 Service 暴露为 30820。Control Plane 的对应文件使用同样的数据卷和数据库配置,副本数为 1、NodePort 为 30816,并额外读取 agw-admin 的 password 作为 Setup__AdminPassword。
使用前需要确认以下配置:
- 镜像:示例使用
localhost/agw-…:local和imagePullPolicy: Never,需要先构建镜像并加载到 kind 节点。使用镜像仓库时,替换为可拉取的地址和版本,并调整拉取策略及必要的凭据。 - 数据库:两个角色的 Secret 必须指向同一个可从 Pod 访问的 PostgreSQL。连接字符串中的
localhost指 Pod 自身,通常不是宿主机数据库。 - 权限:示例为了适配本地目录权限使用 root 身份运行。其他环境应按存储权限配置合适的 UID/GID,不应直接照搬这个本地设置。
- 连接保持:Service 使用
ClientIP会话亲和性,帮助 SignalR 请求落到同一 Pod。如果 Nginx 位于集群外,多个客户端可能都表现为同一个代理 IP,因此不能据此保证负载均匀。
部署顺序
先准备本地镜像、数据目录和两个 Secret 的内容文件,再从仓库根目录执行。Secret 文件只包含对应值,不要将真实凭据提交到仓库。以下命令使用当前 kubectl 上下文的默认 namespace;若选择其他 namespace,Deployment、Service、PVC 和 Secret 必须保持一致。
rollout status 表示 Deployment 已完成滚动更新,不能单独证明 AGW 已完成初始化。本例由 Control Plane 的 Setup__AdminPassword 触发首次初始化;应结合日志和登录页面确认成功后再启动 Data Plane。已有数据库的认证配置不会被该初始密码覆盖。
按上述 kind 端口映射运行时,后文 Nginx 示例中的 upstream 可直接使用 127.0.0.1:30816 和 127.0.0.1:30820。如果 Nginx 在集群内部,则使用相同 namespace 下的 Service 地址 agw-control-plane:30816 和 agw-data-plane:30820。检查 PVC 为 Bound、Pod 正常运行后,再验证登录、执行连接和各节点实际接收的请求。
不要执行 kubectl apply -f deploy/k8s/:目录中的 kind Cluster 文件是 kind 的输入,不是 Kubernetes API 资源。更改 kind 的端口或目录映射需要重建集群,操作前先备份数据。完整步骤见 本地 kind 部署说明。
Nginx 配置示例
下面的配置中,Nginx 提供统一入口,Control Plane 监听 30816,Data Plane 监听 30820,与前面的 kind 示例一致;仓库中的 deploy/nginx.split.conf.example 和 cluster Compose 示例则让 Data Plane 使用 30817。端口只是示例,需要与实际 Host 的监听地址一致;如果服务运行在不同主机或容器中,将 127.0.0.1 换成 Nginx 能访问的地址。
Control Plane 同时提供 Web
将以下内容保存为 Nginx 的站点配置文件,并确保它被 nginx.conf 的 http {} 引入。map、log_format 和 upstream 不能放进 server {}。日志路径相对于 Nginx prefix,使用前创建对应目录或替换为可写的绝对路径。
此示例使用 HTTP 便于本机验证。对外使用时,在该 server 中配置 listen 443 ssl;、ssl_certificate 和 ssl_certificate_key,使用自己的域名与有效证书,并将 HTTP 入口重定向到 HTTPS。
| 请求 | 转发目标 | 作用 |
|---|---|---|
/api/hubs/exec 及其子路径 | Data Plane | SignalR 协商与执行连接 |
/a2a/* | Data Plane | A2A 请求及流式响应 |
/.well-known/agents.json | Data Plane | Agent 发现 |
| 其余路径 | Control Plane | 初始化、管理 API、OpenAPI、Web 页面与静态资源 |
proxy_pass 不附加 URI,保留原始路径和查询参数。认证头和 Cookie 默认随请求转发;Upgrade、Connection 和 HTTP/1.1 用于 WebSocket。关闭执行与 A2A 路由的响应缓冲,避免流式内容被代理积攒后才返回。3600s 是代理读写超时设置,不保证任意时长的任务都不会断线。
多 Data Plane 实例时,ip_hash 让来自同一 IP 的连接尽量落到同一实例,避免 SignalR 协商和后续连接被分到不同节点;它不能替代共享数据库、执行状态和恢复配置。若 Nginx 前还有代理,需结合实际网络配置可信代理与客户端 IP;不要直接信任来自任意来源的 X-Forwarded-For。
示例访问日志使用 $uri,不记录查询参数;upstream 字段可帮助确认请求实际进入哪个节点。client_max_body_size 只控制 Nginx 请求体限制,不会提高 AGW 对图片等附件的限制。
Web 单独运行
如果 Web 在 3001 单独运行,保留上述 Data Plane 路由和公共代理设置,再添加 agw_web upstream,按下面的方式调整管理路由并替换原来的 location /。3001 是仓库 Web 开发端口,实际部署按 Web 服务端口填写。
这样 /setup 和 /setup/ 都会进入 Control Plane,普通 /api/ 不会误送到 Web;更长的 /api/hubs/exec 匹配仍进入 Data Plane。独立 Web 服务自身的后端地址也应指向 Control Plane。客户端统一使用 Nginx 的入口地址。
检查并加载配置
保存实际配置后,先检查,再重新加载:
重新加载需要在自己的部署环境执行。检查登录和页面资源是否正常;在浏览器网络面板检查执行连接是否成功升级为 WebSocket(101),并查看访问日志中的 upstream 是否为 Data Plane。普通管理 API 则应进入 Control Plane。登录失败先核对 Cookie、转发协议和应用的代理信任设置;执行连接失败先检查 Upgrade、路由及 Data Plane 端口。
验证
依次验证登录、一次 Chat、一次 Job,并观察实际执行节点。所有 Host 从同一数据库读取初始化和认证状态。重启恢复还依赖共享目录、密钥和运行时凭据一致,不能仅验证容器都已启动。
实现与参考
4.3 - 配置与认证
最近更新:
本页说明 AGW Server 的运行设置:服务地址、数据存放位置、任务执行方式、日志和登录认证。模型、Agent、Project 和集成账号则在管理界面中设置。修改本页配置后,请重启相应的 Server 程序。
初次在本机使用时,大多数设置可以保留默认值。需要远程访问时,重点检查服务地址、客户端来源和代理设置;需要分离部署时,再配置 PostgreSQL 和 Distributed 模式。分布式执行的轮询、批量写入等参数,通常可以先保持默认值。
先看与当前任务有关的设置
只在本机开始使用时,可以先保留默认配置并完成初始化。准备长期运行前,确认数据库和数据目录在哪里,按备份指南保存数据。
远程访问遇到问题时,优先检查“服务地址与数据目录”“初始化、来源与反向代理”和“认证与 API Key”。分离部署则先看两端的必需配置;后面的轮询和批量参数是调优参考,无需在首次部署时逐一修改。
配置方法与优先级
同一项设置可以写在配置文件、环境变量或启动命令中。如果多处都设置了它,后面的来源优先:
程序默认值 → appsettings.json → 环境专用 JSON → 开发环境的 Secrets(机密配置)→ 环境变量 → 命令行。
例如,文件中设置为 SQLite,启动命令中指定 PostgreSQL,最终会使用 PostgreSQL;但连接字符串不会随之自动更换,需要一起修改。配置文件位于 Server 程序目录。日志工具 Serilog 的读取方式有所不同,见下方日志配置。
本页用冒号表示配置的分组,例如 Database:Provider 表示 Database 分组中的 Provider。它在环境变量中写成 Database__Provider,在启动命令中写成 --Database:Provider postgres。开关使用 true(开启)或 false(关闭);需要从几个选项中选择时,请使用表格列出的名称。
表格中的“appsettings.json”指 Server 自带的 appsettings.json;“未设置时”指文件、环境变量和命令行中都没有这一项。两种情况下的默认值若有不同,会分别说明。
按部署方式选择配置
先选择部署方式,再查对应的配置组。部署方式决定启动哪些 Server 程序,执行模式决定任务如何运行,两者需要分别选择。
| 配置组 | 什么时候需要看 |
|---|---|
| 通用配置 | 所有部署都需要了解:服务地址、数据目录、数据库、认证和日志等 |
| Standalone 单机部署 | 一个 Server 同时负责管理、调度和执行;默认使用 SQLite 和 InProcess |
| Control/Data Plane 分离部署 | 控制面负责管理调度,数据面负责执行;必须使用 PostgreSQL 和 Distributed |
| Distributed 执行调优 | 使用 Distributed 时再看:包括分离部署,也包括主动启用 Distributed 的 Standalone |
Standalone 单机部署
本机试用或单台 Server 部署,可以先保留下面的默认组合,通常无需填写这些配置:
| 完整配置名 | 默认选择 | 含义 |
|---|---|---|
Database:Provider | sqlite | 使用本地数据库文件 |
Database:ConnectionString | Data Source=agw.db | SQLite 文件位置;相对路径以 <AgwDataDir>/database/ 为起点,默认文件为 <AgwDataDir>/database/agw.db |
Execution:Provider | InProcess | 由当前 Server 直接运行任务 |
DistributedLock:Provider | 未设置 | 随 SQLite 自动使用进程内锁 |
DistributedLock:ConnectionString | 空 | 进程内锁无需连接数据库 |
Standalone 也可以使用 PostgreSQL,而继续保留 InProcess。若选择 Distributed,则需要同时满足下一节的 PostgreSQL 数据库和锁要求,并按分布式执行方式配置。单机部署方法见单机与 Docker 部署。
Control/Data Plane 分离部署
两端必须使用同一套业务数据库,并采用下面的组合。先完成 Control Plane 初始化,再启动 Data Plane。
| 完整配置名 | 必需设置 | 配置在哪一端 |
|---|---|---|
Database:Provider | postgres | 两端 |
Database:ConnectionString | 指向同一个 PostgreSQL 数据库 | 两端 |
Execution:Provider | Distributed | 两端 |
DistributedLock:Provider | postgres,或不填以跟随数据库 | 两端 |
DistributedLock:ConnectionString | 留空复用数据库连接,或指向相同的锁服务 | 两端保持一致 |
通用配置也要按各自职责填写:
- Control Plane:配置初始化密码、管理页面使用的地址,以及集成 OAuth 的公开地址。
- Data Plane:准备 Agent 所需的 CLI、Shell、工作目录和文件。工作节点的并发数、检查间隔在这一端影响实际执行。
- 两端共同检查:各自的监听地址、客户端来源和代理、日志与监控;需要解密共享数据的节点应使用一致的加密密钥。所有执行节点都必须能访问任务使用的工作目录。
执行模式
下表配置项的完整名称都以 Execution: 开头。
| 配置项 | 默认值 | 用途与可选值 |
|---|---|---|
Provider | InProcess | InProcess:由当前 Server 直接运行任务,适合简单的单机部署。Distributed:将执行状态保存到 PostgreSQL,由负责执行的 Server 领取并运行任务,支持多个执行节点协作。选择 Distributed 时,数据库和分布式锁都必须使用 PostgreSQL。 |
TurnBroadcastRetentionSeconds | 300 | 一个回合结束后,本 Server 在内存中保留该回合回放内容的秒数。在这段时间内重新连接,或重试已被接受的同一回合的客户端,可以收到完整回放。 |
InProcess 模式下,回合只存在于当前 Server 进程中。Server 重启时,上一个进程遗留的运行中回合会被结束为 Interrupted,不会继续执行;需要跨重启恢复时使用 Distributed。
这里的 Host 就是运行中的 Server 程序。启动 Standalone 时,一个程序同时负责管理、调度和执行;分离部署时,Control Plane 负责管理和调度,Data Plane 负责执行。分离部署的两端都需要设置 PostgreSQL 数据库、Distributed 执行模式和 PostgreSQL 锁。请按部署方式启动对应程序,Execution:Provider 只决定任务如何执行。
分布式锁
多台 Server 协作时,需要确认“这项工作现在由谁处理”。锁用来保证同一时刻只有一个执行者取得这项工作的处理权,避免相互冲突。
下表配置项的完整名称都以 DistributedLock: 开头。
| 配置项 | 默认值 | 用途与可选值 |
|---|---|---|
Provider | 未指定,跟随数据库 | inmemory:在当前 Server 内记录谁正在执行,适合单节点。postgres:让多个 Server 通过 PostgreSQL 共同确认执行权。未设置或填 null 时会自动选择:SQLite 使用 inmemory,PostgreSQL 使用 postgres。 |
ConnectionString | 空 | postgres 锁使用的连接字符串;空值复用 Database:ConnectionString。inmemory 不使用连接字符串。 |
Distributed 执行调优
下面的设置用于 Distributed 执行模式。分离部署需要使用它;Standalone 只有启用 Distributed 后才需要关注。先保留默认值,出现明确的性能问题后再逐项调整。
分布式工作节点
工作节点是负责实际运行任务的 Server。下面这些设置决定它多久检查新任务、同时处理多少任务,以及执行租约的时长和续期间隔。
下表配置项的完整名称都以 Execution:Distributed: 开头。
| 配置项 | 默认值 | 用途与可选值 |
|---|---|---|
WorkerPollingMilliseconds | 250 | 每隔多久检查一次是否有新任务,单位毫秒。默认 250 毫秒,即每秒约检查 4 次。调小后可能更快开始任务,但数据库也会更忙。 |
MaxConcurrentExecutions | 4 | 每个执行 Server 最多同时处理多少次任务。默认 4,表示这一台 Server 最多同时运行 4 次任务;部署多台时,每台分别计算。 |
LeaseSeconds | 30 | 执行租约的时长,单位秒。领取任务的 Server 持有租约;租约到期而没有续期时,其他 Server 可以接手这次执行。正常运行的长任务会持续续期,不会仅因运行超过 30 秒就被接手。 |
LeaseRenewSeconds | 10 | 持有租约的 Server 每隔多久续期一次,单位秒,必须小于 LeaseSeconds。 |
只有选择 Distributed 模式时才需要关注这些设置。所有数值都必须是大于 0 的整数,且 LeaseSeconds 必须大于 LeaseRenewSeconds,否则 Server 启动时报错;没有明确的性能问题时,建议先使用默认值。
执行事件与回放
Agent 执行时会不断产生回复和状态消息。系统保存这些消息后,客户端重新连接时可以补读执行过程,这就是“回放”。这里设置消息保存在哪里,以及读写的频率。
下表配置项的完整名称都以 Execution:Distributed:EventStream: 开头。
| 配置项 | 默认值 | 用途与可选值 |
|---|---|---|
Provider | Postgres | 执行过程中的消息总是先保存到 PostgreSQL。Postgres:只从 PostgreSQL 读取,无需额外安装 Redis。Redis:同时把已保存的消息复制一份到 Redis Stream,读取时优先使用 Redis,缺少的部分(包括已过期或 Redis 暂时不可用时)从 PostgreSQL 补齐。任务状态和分布式锁始终需要 PostgreSQL。 |
ReadPollingMilliseconds | 250 | 暂时没有新消息时,隔多久再检查一次,单位毫秒,必须大于 0。 |
ReadBatchSize | 100 | 一次最多读取多少条执行消息,必须大于 0。 |
WriteIntervalMilliseconds | 250 | 收到第一条待保存消息后,最多等待多久把消息一起写入,单位毫秒。默认 250;填 0 表示立即写入,不能为负数。 |
WriteBatchSize | 100 | 待保存消息达到多少条时,就触发一次批量写入,必须大于 0。默认积累到 100 条时写入。 |
Redis:ConnectionString | 空 | 选择 Redis 时必填,所有相关 Server 使用相同 Redis 服务,例如 redis:6379,password=...。 |
Redis:StreamTtlMinutes | 1440 | 执行消息在 Redis 中保留多久,单位分钟。默认 1440 分钟,即 24 小时;选择 Redis 时必须大于 0。过期的部分会改从 PostgreSQL 读取。 |
通用配置
以下设置适用于两种部署方式。分离部署时,根据每个 Server 承担的职责配置相应项目。
服务地址与数据目录
| 配置项 | 默认值 | 用途与可选值 |
|---|---|---|
ASPNETCORE_URLS / --urls | 本地默认端口 30816;容器由运行配置指定 | Server 接收请求的地址。用 --urls http://127.0.0.1:30816 仅供本机访问,或按部署需要绑定其他地址。多个地址用分号分隔。 |
ASPNETCORE_ENVIRONMENT | Production | 选择环境专用 JSON,例如 appsettings.Production.json。常用名称为 Development(开发)、Staging(预发布)、Production(生产);这是环境名称,不是只接受三个值的枚举。 |
AgwDataDir | ~/agw | AGW 数据根目录,包含运行数据、Skills 和加密密钥等。支持 ~;相对路径以启动程序时的工作目录为起点。 |
AgwLogDir | ./logs | 独立的日志目录,不随数据目录移动;支持 ~,相对路径从工作目录解析。 |
AllowedHosts | * | 允许用哪些域名访问 Server。* 表示不限制;也可以填写 agw.example.com;localhost 这样的域名列表,用分号分隔。客户端从哪个页面连接,则由 AllowedOrigins 设置。 |
数据库
下表配置项的完整名称都以 Database: 开头。
| 配置项 | 默认值 | 用途与可选值 |
|---|---|---|
Provider | sqlite | sqlite:本地 SQLite 文件,适合单机;postgres:PostgreSQL 服务,支持分离和分布式部署。只有这两种值。 |
ConnectionString | Data Source=agw.db | 所选数据库的连接字符串。SQLite 使用 Data Source=...,相对路径以 <AgwDataDir>/database/ 为起点;PostgreSQL 使用 Host=...;Port=5432;Database=...;Username=...;Password=...,Host 不能为空。切换 Provider 时必须一起修改。 |
初始化、来源与反向代理
| 配置项 | 默认值 | 用途与可选值 |
|---|---|---|
Setup:AdminPassword | 未设置 | 首次初始化的管理员密码,8–256 个字符。通过环境或 Secrets 注入可完成无人值守初始化;已有认证配置时不会覆盖密码。分离部署在 Control Plane 初始化。 |
Auth:AllowedOrigins | agw://app、http://localhost:3000、http://127.0.0.1:3000 | 允许哪些客户端地址连接 Server。Origin 是地址的“协议 + 主机名 + 端口”,例如 http://localhost:3000。请填写实际地址,协议和端口都要一致;完全未设置时列表为空。 |
ReverseProxy:TrustedProxies | appsettings.json含 127.0.0.1、172.16.0.0/12、10.0.0.0/8 | 如果请求经过反向代理,填写代理的实际 IP,让 Server 能识别原始访问地址和 HTTP/HTTPS 协议。当前只接受单个 IP;10.0.0.0/8 这样的网段写法不会生效。程序读取 X-Forwarded-For、X-Forwarded-Host、X-Forwarded-Proto,最多处理一层转发。 |
数组通过数字下标配置,例如 Auth__AllowedOrigins__0=agw://app。配置覆盖按下标合并;只覆盖第 0 项不会自动删除appsettings.json中的第 1、2 项,需要完整核对最终列表。
集成 OAuth 地址
下表配置项的完整名称都以 Integrations:OAuth: 开头。
| 配置项 | 默认值 | 用途与可选值 |
|---|---|---|
PublicBaseUrl | http://localhost:30816 | 用户在 GitHub 等服务中完成授权后,浏览器返回 AGW Server 时使用的地址。程序会在它后面加上 api/integrations/oauth/callback。远程部署时,请填写浏览器实际能访问的 Server 地址。 |
WebBaseUrl | http://localhost:3001 | 授权流程结束后,用户返回 AGW 页面时使用的地址。请填写实际打开 Web 界面的地址。 |
两项都填写以 http:// 或 https:// 开头的完整地址,不要附带用户名、密码、? 后的查询参数或 # 后的内容。未设置或留空时,使用当前请求的基础地址。
对话历史写入
下表配置项的完整名称都以 ConversationHistory: 开头。
| 配置项 | 默认值 | 用途与可选值 |
|---|---|---|
Mode | Interval | Immediate:有需要保存的内容就立即写入数据库。Interval:先暂存在内存中,隔一段时间一起保存。TurnEnd:主要等这一回合结束后再保存。暂存内容达到大小上限时,也会提前保存。 |
FlushIntervalSeconds | 10 秒 | Server 自带的 appsettings.json 设为 10 秒;如果所有配置来源都没有设置这一项,程序使用 5 秒。Interval 模式下,隔多少秒把暂存内容保存到数据库。必须大于 0,且不能超过程序计时器支持的范围。 |
MaxBufferedBytes | 16777216(16 MiB) | 允许暂存在内存中的内容大小,单位字节。默认 16 MiB;达到上限会提前保存到数据库,必须大于 0。 |
这些设置决定聊天记录什么时候保存到数据库,页面仍可实时显示回复。先暂存、后保存可以减少数据库写入,但程序意外退出时,尚未保存的部分可能丢失。如果更看重记录及时保存,可以选择 Immediate。
Shell 工具
下表配置项的完整名称都以 Agents:Shell: 开头。
| 配置项 | 默认值 | 用途与可选值 |
|---|---|---|
Backend | local | local:直接在运行 Agent 的主机上执行命令,使用项目工作目录。docker:在 Docker 容器中执行命令,需要主机已安装并能使用 Docker。容器中的项目目录为 /workspace,附加目录为 /project-directories/{id};当前容器禁用网络,命令超时为 30 秒。 |
此项只选择 AGW Shell 工具的执行后端,不改变整个 Server 的部署模式,也不为外部 Agent 安装 CLI。
OpenTelemetry
OpenTelemetry 用于把运行指标和调用追踪等信息发送到监控系统,帮助排查慢请求和错误。已有监控服务时,填写它的接收地址;刚开始使用时,先了解下面的默认行为即可。
下表配置项的完整名称都以 OpenTelemetry: 开头。
| 配置项 | 默认值 | 用途与可选值 |
|---|---|---|
ServiceName | appsettings.json Agw | 监控系统中显示的服务名称。分离 Host 遇到appsettings.json值 Agw 时会改为 Agw.ControlPlane 或 Agw.DataPlane;未设置时使用 Agw.{Host角色}。 |
ServiceVersion | 1.0.0 | 监控系统中显示的版本号,方便区分不同版本的运行情况。 |
OtlpEndpoint | appsettings.json空 | 接收运行指标、调用追踪等数据的监控服务地址。留空或不填时,不启用 OpenTelemetry 的追踪、指标和日志导出。 |
日志配置
日志记录 Server 运行中发生的事情。级别越详细,越有利于排查问题,但产生的日志也越多。下面保留完整配置名,日常调整通常只需关注日志级别和保存目录。
| 配置项 | 默认值 | 用途与可选值 |
|---|---|---|
Logging:LogLevel:Default | Information | Microsoft 日志默认记录到什么详细程度;可用 Logging:LogLevel:{类别} 单独调整某个模块。 |
Logging:LogLevel:Microsoft.AspNetCore | Warning | Web 请求处理相关日志的详细程度。 |
Logging:LogLevel:Microsoft.EntityFrameworkCore | Warning | 数据库访问相关日志的详细程度。 |
Serilog:Using | Console、File、Async sinks | 启用控制台、文件和异步输出功能所需的日志组件。一般无需修改。 |
Serilog:MinimumLevel:Default | Information;Development 为 Debug | Serilog 默认保留的最低日志级别。低于该级别的日志不会输出。 |
Serilog:MinimumLevel:Override:Microsoft.AspNetCore | Warning | 单独设置 Web 请求相关日志的最低级别。 |
Serilog:MinimumLevel:Override:Microsoft.EntityFrameworkCore | Warning | 单独设置数据库访问日志的最低级别。 |
Serilog:MinimumLevel:Override:System | Warning | 单独设置 System 系统组件日志的最低级别;其他类别可按同样方式设置。 |
Serilog:WriteTo:0:Name | Async | 让日志在后台输出,减少写日志对请求处理的影响。一般保留 Async。 |
Serilog:WriteTo:0:Args:configure:0:Name | Console | 将日志输出到运行 Server 的终端或容器日志中。 |
Serilog:WriteTo:0:Args:configure:0:Args:outputTemplate | 见下方 | 控制台行格式,包含时间、级别、来源、TraceId、SpanId、线程、消息与异常。 |
Serilog:Enrich | FromLogContext、WithMachineName、WithThreadId、WithOpenTelemetryTraceId、WithOpenTelemetrySpanId | 给日志补充主机名、线程和请求追踪信息,方便把同一次操作的记录联系起来。 |
当前 Host 的 Serilog 配置从 appsettings.json 及 appsettings.{ASPNETCORE_ENVIRONMENT}.json 单独读取;不能假设 Serilog__... 环境变量会覆盖这条管线。修改日志输出或级别时编辑相应 JSON 并重启。Logging 与 Serilog 是两套级别配置,当前主要输出使用 Serilog。
Microsoft 日志级别全部为:Trace(最细追踪)、Debug(调试)、Information(正常运行)、Warning(异常征兆)、Error(操作失败)、Critical(严重故障)、None(关闭)。Serilog 对应支持 Verbose、Debug、Information、Warning、Error、Fatal;其中 Verbose 对应最细追踪,Fatal 对应严重故障,Serilog 最小级别没有 None。
WriteTo 的 Name、Using 和 Enrich 是插件名称,不是固定枚举;上表列的是当前appsettings.json。Host 还额外写入 AgwLogDir/application-{角色}-.log,每小时生成一个新日志文件,保留 30 个文件,每秒将日志写入磁盘;这些规则由程序固定,不能通过本页配置修改。
认证与 API Key
在浏览器中使用远程 Web 时,用管理员密码登录,浏览器会通过 Cookie 记住登录状态。Desktop、Mobile 和自动化程序则使用 API Key(访问密钥),它相当于这些客户端连接 Server 的钥匙。请求格式为:
在 Server 所在主机上直接访问时,满足以下全部条件的请求会自动以管理员 1001 的身份通过认证,不需要密码或 API Key:来源是回环地址,没有任何转发请求头,访问的主机名是 localhost 或回环 IP,且请求不带认证请求头或登录 Cookie。经过反向代理或从其他主机访问的请求不满足这些条件。
创建 API Key 时为它起一个便于识别的名称,并保存当时显示的完整值;之后不会再次显示。自动化程序可以从环境变量或机密配置中读取它。不再使用时撤销该 API Key。Server 会按创建者的身份判断它能访问哪些资源。每个 Server 会把验证通过的 API Key 缓存 30 秒:处理撤销请求的 Server 立即清除缓存;分离部署且没有共享的分布式缓存时,其他副本最多 30 秒后停止接受该 API Key。多账号登录通过下一节的第三方登录配置;当前不提供角色、API Key 权限范围(scopes)或 JWT 的配置。
密码和 API Key 都以用于验证的哈希值保存在数据库中,不保存原文。管理员认证信息位于 setting 表的 auth 分组,API Key 信息位于 api_token 表,由管理功能自动维护,无需在 appsettings 中填写。修改管理员密码后,各 Server 会检查新的登录状态版本;检查每秒进行一次,读取失败时不再沿用缓存的认证信息。忘记密码可先停止 Server,再运行 agw-server auth reset-password;分离部署使用 agw-control-plane auth reset-password。新密码需要 12–256 个字符,重置后已有的 Web 登录会话全部失效。
第三方登录
启用第三方登录后,用户可以用组织账号进入 Web 和 Desktop。每个账号首次登录时创建一个独立的本地用户,编号从 10000 开始,管理员仍是 1001。未配置提供商时,管理员密码和 API Key 继续可用。行为说明见第三方账号登录。
在提供商侧把 AGW 登记为 Web 应用(保密客户端),回调地址按提供商 ID 组成。Desktop 用户同样使用这个地址,提供商把浏览器送回 Server,不直接送回桌面程序:
下表配置项的完整名称都以 Auth:Oidc: 开头,{id} 是你为提供商起的编号。
| 配置项 | 默认值 | 用途与可选值 |
|---|---|---|
PublicBaseUrl | 空 | 浏览器访问 Server 的地址,验证完成后返回这里。程序在它后面加上 api/auth/oidc/callback/{id}。必须是不带路径的完整地址,生产环境使用 HTTPS,开发环境允许本机 HTTP。启用任一提供商后必填。 |
WebBaseUrl | 空 | 登录结束后返回的 Web 界面地址。Web 与 Server 同源时留空;源码开发中 Web 在 3001、后端在 30816 时需要填写。 |
Providers:{id}:Enabled | false | 是否启用该提供商。 |
Providers:{id}:Type | Oidc | Oidc:按 Authority 自动读取端点,请求 openid profile email。OAuth2:逐项填写端点和字段名称。 |
Providers:{id}:DisplayName | 提供商 ID | 登录按钮上显示的名称。 |
Providers:{id}:ClientId | 空 | 在提供商侧登记 AGW 得到的客户端编号,必填。 |
Providers:{id}:ClientSecret | 空 | 对应的客户端密钥,必填,通过环境变量或机密配置注入。 |
Providers:{id}:Authority | 空 | Type 为 Oidc 时必填,例如 https://sso.example.com/realms/company。 |
Providers:{id}:AuthorizationEndpoint | 空 | Type 为 OAuth2 时必填,用户跳转到提供商的授权地址。 |
Providers:{id}:TokenEndpoint | 空 | Type 为 OAuth2 时必填,Server 换取访问令牌的地址。 |
Providers:{id}:Issuer | 空 | Type 为 OAuth2 时必填,用于标识账号来源,与账号编号一起确定用户身份。 |
Providers:{id}:IdentitySource | UserInfo | 仅用于 OAuth2。UserInfo:调用用户信息接口读取账号。AccessToken:从签名的 JWT 访问令牌读取账号。 |
Providers:{id}:UserInfoEndpoint | 空 | IdentitySource 为 UserInfo 时必填。 |
Providers:{id}:AccessTokenIssuer | 空 | IdentitySource 为 AccessToken 时必填,校验令牌的签发者。 |
Providers:{id}:AccessTokenAudience | 空 | IdentitySource 为 AccessToken 时必填,校验令牌的接收方。 |
Providers:{id}:AccessTokenJwksUri | 空 | IdentitySource 为 AccessToken 时必填,读取验签公钥的地址。 |
Providers:{id}:ClientAuthMethod | Post | OAuth2 换取令牌时提交客户端凭据的方式:Post 放在请求体,Basic 放在请求头。 |
Providers:{id}:UsePkce | false | OAuth2 是否启用 S256 校验。Type 为 Oidc 时固定启用。 |
Providers:{id}:Scopes | 空 | OAuth2 申请的权限范围,按数字下标配置,例如 Scopes__0=read:user。 |
Providers:{id}:SubjectClaim | sub | 仅用于 OAuth2,账号编号对应的字段名称,例如 GitHub 使用 id。Oidc 固定使用 sub。 |
Providers:{id}:DisplayNameClaim | name | 仅用于 OAuth2,显示名称对应的字段名称,例如 GitHub 使用 login。Oidc 固定使用 name。 |
Providers:{id}:EmailClaim | 仅用于 OAuth2,邮箱对应的字段名称;Oidc 固定使用 email。缺少显示名称或邮箱不影响登录。 |
提供商 ID 使用小写字母、数字和连字符,最长 64 个字符,例如 company、entra-id。每个 ID 对应各自的回调地址,登记后不要再修改。
不含密钥的配置示例:
对应的密钥通过 Auth__Oidc__Providers__company__ClientSecret 注入,不要写入 appsettings、前端环境文件或截图。GitHub 这类只提供 OAuth2 的服务改用下面的写法:
常见提供商的 Authority:
| 平台 | Authority |
|---|---|
https://accounts.google.com | |
| Microsoft Entra ID | https://login.microsoftonline.com/<租户 ID>/v2.0 |
| Keycloak | https://sso.example.com/realms/<realm> |
| Authentik | https://sso.example.com/application/o/<应用标识>/ |
修改这些配置后重启相应的 Server 程序。分离部署把登录相关请求指向 Control Plane,数据面使用由此得到的本地凭据;所有副本共用同一套数据库和数据保护密钥,Desktop 的一次性代码可以在不同副本上完成换取。停用某个提供商会阻止新的登录和尚未完成的 Desktop 换取,已经签发的 Cookie 和 API Key 需要单独撤销。
配置示例与验证
下面的示例只展示设置方式,连接字符串应通过环境或 Secrets 注入实际值:
分离部署将相同数据库和执行配置传给各 Host,先初始化 Control Plane,再启动 Data Plane。上面的 agw-server 是 Standalone 程序,分离部署使用相应 Host 程序。
重启后检查启动日志、访问地址、数据库连接和客户端登录。调整执行参数后,先运行一个小任务,观察开始速度、完成时间和资源占用。启动报错时,先检查选项名称是否拼写正确、数值是否在允许范围内、数据库地址和凭据是否正确,以及 Distributed 所需的数据库和锁是否已配置。排查日志时不要公开密码或 API Key。
实现与参考
4.4 - 数据目录、备份与升级
最近更新:
备份需要同时保留 AGW 的配置和记录、加密密钥,以及项目文件。只复制安装目录,或只保存代码仓库,都可能遗漏恢复服务所需的数据。
开始前,确认实际数据库、数据目录和各 Project 工作目录的位置;下面的默认路径仅用于帮助定位,以运行中的配置为准。
数据范围
AgwDataDir 默认 ~/agw,Docker 使用 /data。路径支持 ~,其他相对路径相对进程工作目录解析。默认的 SQLite 数据库文件是 <AgwDataDir>/database/agw.db,Docker 中为 /data/database/agw.db。
需要一起保存:
- 数据库,包括
setting、api_token、会话和执行记录。 - 数据目录中的
keys/和skills/。 - 部署配置及其秘密引用,实际秘密通过安全存储备份。
- 各 Project 主目录与附加目录中的业务文件,使用独立文件备份策略。
日志目录独立于数据目录;日志和临时文件不属于认证恢复必需数据。丢失 Data Protection 密钥可能使已保护凭据无法读取。
先列出备份清单
记录数据库位置、AgwDataDir 的实际值、各 Project 的目录及当前程序版本。项目使用文件型 Memory 时,还要包含主目录下的隐藏目录 .agw/memory/;数据库型 Memory 随数据库保存。表单默认的主目录 ~/.agw/<项目文件夹名> 和 Server 默认的 ~/.agw/projects/{projectId:N} 都位于运行 Server 的账号的主目录下,不在 AgwDataDir 中;Docker 中也不在 /data 卷内,需要另外挂载并备份。
备份数据库和文件前,先等待任务结束或中断任务,避免备份期间仍有写入。SQLite 的简单做法是停止 Server 后复制数据库及相关文件;PostgreSQL 使用自己的备份工具。数据目录和项目目录可能在不同位置,应逐项核对,不能假定它们都在 /data 内。
升级顺序
- 阅读目标 Release 说明,记录当前镜像或安装包版本。
- 停止全部旧版 Standalone、Control Plane 和 Data Plane 进程,取得一致性备份:SQLite 简单部署可在停止后复制文件;PostgreSQL 使用数据库自身的备份机制。
- 应用新版本对应数据库的迁移(SQLite 或 PostgreSQL 其中一套)。已初始化的 Server 正常启动时不会自动执行迁移,只有首次 Setup 会执行;源码部署可使用 Development Guide 中按数据库区分的命令。
- 更新 Server 与客户端,保留数据、Data Protection 密钥和目录挂载,再启动新版本。新版 Host 在接受请求和启动 Worker 之前,会检查并升级正在进行的执行记录;某条记录无法解密或验证失败时,Host 启动报错,需要修正数据后重新启动。
- 验证初始化状态、登录、Project 文件和一个小任务;分离部署还需验证 worker 与 Job。
AGW 在 1.0 前的升级可能包含 schema 变更。回滚时需要使用彼此兼容的程序版本、数据库备份和密钥备份。
恢复验证
优先在隔离环境验证备份能恢复,确认凭据可解密、文件路径可见。更改数据或日志根目录需要重启并自行迁移文件,不会自动搬运已有数据。
实现与参考
4.5 - 日志与常见问题
最近更新:
排查时先确定故障发生在哪一步:页面连接、登录、模型调用,还是文件和工具操作。用一个简单任务重现问题,通常比反复重启更容易找到原因。
记录出错的 Server、Project、会话和时间,再查看对应服务日志。分离部署的管理问题主要查控制面日志,任务执行问题主要查数据面日志。
排查顺序
| 现象 | 优先检查 |
|---|---|
| 无法打开界面 | 监听地址、端口、容器映射、代理目标 |
| Setup 无法完成 | 数据库连接、目录写权限、远程 Setup Code |
| 登录或 API Key 失败 | 实际 Server、API Key 撤销情况、数据库认证状态 |
| 第三方登录失败 | Auth:Oidc:PublicBaseUrl、提供商侧登记的回调地址、客户端凭据、Server 到提供商的网络 |
| Agent 不回复 | Model Provider、模型 ID、凭据、待审批/待输入状态 |
| CLI 无法启动 | 执行节点的可执行文件、账号与环境 |
| 文件找不到 | 当前目录选择、Server 路径、挂载和访问权限 |
| Job 没运行 | 启用状态、未来时间、UTC Cron、有效目标和日志 |
| 断线后状态不对 | 会话选择、WebSocket 代理、执行是否仍在后台运行;InProcess 模式下 Server 重启后,原来运行中的会话会显示为 Interrupted,不会继续执行 |
示例:页面能打开,但 Agent 不回复
- 查看 Chat 是否正在等待审批或补充信息。如果是,先处理请求。
- 使用同一个模型连接运行一条纯文字问题。如果仍失败,检查 API 地址、模型 ID 和凭据。
- 纯文字正常而工具任务失败时,检查工具绑定、工作目录和执行主机的访问权限。
- 分离部署中,若配置页面正常而对话连接失败,检查
/api/hubs/exec是否转发到数据面,以及代理是否支持 WebSocket。 - 根据出错时间查找服务日志中的具体错误,修改后重复同一个小任务验证。
这个顺序可以把模型、工具和连接问题分开,避免同时更改多项设置后无法判断原因。
第三方登录失败
第三方登录失败时,浏览器回到登录页,地址中带有 error=oidc-<类别>,Desktop 在 Server 配置处显示提示。用这个类别配合 Agw.Auth.Oidc 日志定位原因:日志记录提供商、客户端、失败所处的阶段、失败类别和 TraceId。
| 类别 | 通常的原因 |
|---|---|
provider-unavailable、provider-timeout | Server 访问不到提供商:网络、出站代理或防火墙 |
provider-rejected | 能访问提供商,但 OAuth2 的用户信息接口返回错误状态码:检查 UserInfoEndpoint、Scopes 和令牌权限 |
protocol-rejected | OIDC 提供商返回协议错误:客户端编号、密钥或已登记的回调地址不符 |
invalid-state、invalid-nonce | 回调校验未通过:浏览器访问的地址与 PublicBaseUrl 不一致,或校验用的 Cookie 被拦截 |
invalid-token | 令牌校验未通过:Authority、签发者、接收方或验签地址配置不符 |
protocol-validation-failed | 其他未归类的协议失败,包括 OAuth2 换取令牌被拒绝:先检查客户端编号、密钥和回调地址 |
provisioning-failed、grant-creation-failed、session-creation-failed | Server 本地处理失败:先检查数据库连接和迁移是否完成 |
authorization-denied | 用户在提供商页面取消了授权 |
排查时不要关闭签发者、接收方、签名、state、nonce 或 PKCE 校验。反向代理需要保留原始协议和主机名,否则回调会落在另一个来源上。报告问题时不要附带认证相关的查询参数和完整的提供商响应。
日志与遥测
AgwLogDir 默认 ./logs,不随 AgwDataDir 自动变化。分离部署要查看对应角色日志。需要集中遥测时配置 OpenTelemetry:OtlpEndpoint;空值或缺失时不启用 OpenTelemetry 的追踪、指标和日志导出。
历史采用 Interval 批量写入。Host 模板的 ConversationHistory:FlushIntervalSeconds 为 10 秒,省略时回退到 5 秒。即时输出与已落库历史存在时间差。
Web 开发代理
Web 开发运行在 3001,后端默认 30816。代理目标依次取 BACKEND_API_BASE_URL、NEXT_PUBLIC_API_BASE_URL、默认本机地址。静态 export 模式不使用 Next.js 代理,应由 Server 或外部入口提供同源路由。
修复后重复原来失败的小任务,确认界面状态和日志都恢复。报告问题时提供版本、部署方式、复现步骤和脱敏错误,不附带真实 API Key 或完整 OAuth 响应。
实现与参考
5 - 开发指南
最近更新:
本章面向准备修改 AGW 源码或接入 API 的开发者。只想安装和使用 AGW,可以先阅读快速开始。
建议先完成开发环境,再用架构与模块边界判断代码应放在哪里。接入客户端时阅读API 与执行协议,新增能力时阅读扩展 Tools 与 Integrations。提交改动前,按测试与贡献约定完成相关验证。
5.1 - 开发环境与运行
最近更新:
前提:.NET 10 SDK、Node.js 24、pnpm 12.5.1(版本由 src/clients/package.json 的 packageManager 指定)和 Git。只有构建容器镜像时才需要 Docker Buildx。以下应用命令在 AGW 仓库执行,文档站本身不依赖这些工具链。
后端
在 http://localhost:30816/setup 初始化。热重载可将 dotnet run 改为 dotnet watch。
客户端
另开终端,从仓库根进入 workspace:
打开 http://localhost:3001。Desktop 使用 pnpm dev:desktop,其独立 renderer 运行在 3000,不需要同时运行 Web。Mobile 使用 pnpm dev:mobile,或 pnpm android:mobile / pnpm ios:mobile;原生工程由 Expo CNG 生成。
启动后应该看到什么
保留后端终端运行,再启动需要的客户端。Web 页面能打开后,先确认 Server 初始化和登录,再按第一次对话配置模型。仅看到前端页面还不能说明后端连接正常。
后端默认端口是 30816,Web 开发端口是 3001,Desktop 界面开发端口是 3000。端口被占用时先确认是否已有开发进程,不要误把其他服务当成 AGW。手机上的 localhost 指手机本身,真机连接需使用手机可访问的电脑地址。
验证
确认后端初始化完成,客户端能连接并运行一条简单消息。移动真机需要可达的后端地址;外部 CLI 需在执行进程环境下可用。
运行站点需要 Hugo Extended 与 Go,运行检查脚本 scripts/check-site.py 还需要 Python 3,命令见 site/README.md。不要将站点加入客户端 Turborepo,也不要让 Web/Desktop 消费站点产物。
实现与参考
5.2 - 架构与模块边界
最近更新:
本页帮助开发者判断一项改动应放在哪个模块、哪一层。AGW 按业务拆分代码,例如 Agents、Projects 和 Jobs;它们可以共享一个部署进程和数据库,但各自负责自己的数据和操作。
先完成源码运行,再选择一个具体功能沿请求追踪,通常比一次阅读所有项目更容易理解。
后端组织
AGW 是模块化单体。Agw.Host 提供共享 Hosting,Control Plane、Data Plane 和 Standalone 组合所需模块。业务模块遵守 Api → Application → Domain ← Infrastructure,只创建实际需要的层。
flowchart LR
API[Api] --> APP[Application]
APP --> DOMAIN[Domain]
INFRA[Infrastructure] --> DOMAIN| 层 | 负责什么 | 阅读时关注什么 |
|---|---|---|
| Api | 接收请求并返回响应 | 路由、输入和返回值 |
| Application | 完成一次业务操作 | 身份检查、查询、事务和调用顺序 |
| Domain | 保存业务数据并表达规则 | Entity、Behavior 和 DomainService |
| Infrastructure | 连接数据库和外部系统 | 持久化、外部服务适配和具体实现 |
Domain 中的 Entity 保存状态。单个 Aggregate 的业务规则由 Behavior 处理;需要其他 Aggregate 信息的规则由 DomainService 处理。Application 读取数据、协调调用并保存变更。普通增删改查由 Application 直接完成。
数据所有权
每张表只有一个负责它的模块。即使多个模块共用实体类型和数据库,也要通过所属模块提供的接口访问数据,不能直接查询或修改其他模块的表。
拥有数据表的模块在 Application/Persistence 中声明自己的持久化接口 I<Module>DbContext,目前共有九个:Agents、Auth、Integrations、Jobs、Projects、Providers、Settings、Skills 和 Tools;Files、Setup 和 A2A 不拥有数据表,也没有这类接口。同一次请求中,这些接口由同一个 AgwDbContext 实例实现。这样既能共用数据库连接和事务,又能限制模块可见的数据范围。跨模块调用使用 Contracts 中的公开约定,必要的跨模块事务放在经过批准的 Infrastructure 适配器中。
Agw.Agents.Execution → Agw.Agents 单向依赖,两程序集属于同一 Agents 模块。Agentflow 的选择性 DDD 不扩展到普通 CRUD 模块。
以修改 Agentflow 为例
请求先进入 Api,再由 Application 检查用户能否访问该流程,并加载流程及全部节点和连线。Policy 判断新图是否符合规则,返回 Decision;Behavior 将有效变更应用到已加载的对象,最后由 Application 保存。
因此,修改连线规则时应查看 Agentflow 的 Policy 和 Topology;调整权限、加载或保存顺序时应查看 Application;修改数据库实现时再进入 Infrastructure。这个分工让业务规则与网络、数据库细节分开,也便于分别测试。
客户端
Web 与 Desktop 各自拥有路由壳和构建,业务包位于 src/clients/packages。chat-core 负责消息语义,chat-runtime 负责执行连接和状态,chat 负责 DOM 呈现。Mobile 通过 chat-native 与 RN-safe 包接入,不直接依赖 DOM 包。
增加功能前确认所属模块与公开入口;修改边界后运行 pnpm test:boundaries 和后端架构测试 dotnet test tests/Agw.Architecture.Tests。
实现与参考
5.3 - API 与执行协议
最近更新:
AGW 的管理操作和任务执行使用不同接口。创建或查询配置使用普通 HTTP JSON API;持续接收 Agent 回复和状态使用 SignalR 执行连接;对接其他 Agent 系统时可以使用 A2A。
接入前,先准备可访问的开发 Server 和有效的认证身份,例如 API Key 或浏览器登录会话。具体参数以运行实例的 OpenAPI 及所属模块 Contracts 中的类型定义为准,避免照抄与运行版本不一致的请求。
协议边界
| 接口 | 用途与约定 |
|---|---|
| 管理 JSON API | Bens.Results ApiResult 封装,客户端 typed helpers 解包 |
/api/hubs/exec | SignalR 执行命令、状态和事件;仅 Data Plane 和 Standalone 映射,只接受 WebSocket 传输,官方客户端以 skipNegotiation: true 直接连接 |
/api/agents/permission-capabilities | 查询目标支持的权限能力 |
/api/auth/oidc/providers | 查询已启用的登录提供商,登录界面据此显示按钮 |
/api/auth/oidc/login | 跳转到提供商完成验证,client 取 web 或 desktop |
/api/auth/desktop/exchange | Desktop 用一次性代码和自身校验值换取 API Key |
| A2A | 协议专用响应,仅 Data Plane 和 Standalone 映射 |
/openapi/* | OpenAPI 接口描述,与 Scalar API 参考页一起只在 Development 环境中由 Control Plane 或 Standalone 提供 |
第三方登录相关的路由由 Control Plane 和 Standalone 提供。Desktop 换取到的 API Key 与手动创建的 API Key 用法相同,按创建者身份访问资源。
接入流程
- 自动化使用 API Key,通过
Authorization: Bearer请求头发送;浏览器使用 Cookie 发送 POST、PUT、DELETE 等修改请求时,还要按现有客户端流程处理 CSRF 防护,防止其他网站借用登录状态发起操作。 - 通过管理 API 获取当前用户可访问的资源,保留其稳定标识。
- 启动执行前查询目标权限能力,按现有执行协议发起命令并订阅事件。
- 断线重连时恢复会话/执行状态,不把连接断开当作任务完成。
新增接口默认通过 query/body 传标识,遵守仓库规则。具体接口的路由和参数以当前 OpenAPI 与 Contracts 为准。
客户端应如何处理结果
管理 JSON API 使用 Bens.Results 统一响应格式。仓库的 @agw/api 已提供类型化辅助方法来提取业务数据,调用方应复用这些方法,并分别处理请求失败和业务错误。
执行连接会持续返回事件。客户端需要保留会话与执行标识,展示工具活动和等待输入状态,并在重连后查询实际进度。收到部分文字不代表执行结束,连接断开也不代表执行已经取消。协议消息及顺序见执行协议说明。
Agent 的结构化响应字段
responseSchema 保存 Agent 配置的 JSON Schema 原文,出现在完整的 Agent 响应中:GET /api/agents/{id}、GET /api/agents/paged、POST /api/agents、PUT /api/agents/{id} 和 PUT /api/agents/enabled。选择器使用的 GET /api/agents 不包含该字段。
两类响应都包含 resultFormat,取值为 markdown 或 json,由是否配置 Schema 推导。客户端据此决定最终结果按 Markdown 还是 JSON 显示,无需自行解析 Schema 内容。
更新时,字段缺失表示保持原值,null 或只包含空白的字符串表示清空,其他字符串表示替换。服务端要求内容是合法 JSON 且根节点为对象,否则返回参数错误;Pi Agent 设置任何 Schema 都会返回参数错误。Schema 只作为文本保存和传递。
契约变更
DTO(请求和响应的数据类型)放在所属模块的 Contracts 中。预期的业务错误使用 AgwException 和稳定的七位 ErrorCode,再由 API 或协议入口转换成响应。WebSocket、OAuth 跳转、A2A 和静态文件使用各自的协议格式。
后端接口定义更新后,先把 Development 环境的 OpenAPI 文档导出到 src/clients/packages/api/openapi.json,再从 src/clients 运行 pnpm gen:api,最后验证调用方。gen:api 只转换这个本地文件,不会自动从 Server 获取最新文档。不要手写修改生成的 openapi.d.ts,也不要向日志输出实际的 API Key。
实现与参考
5.4 - 扩展 Tools 与 Integrations
最近更新:
扩展前先确定要增加什么:一个具体操作可以写成 Tool,一组任务说明和专属工具可以通过 Skill 提供,需要用户连接外部账号的能力则适合 Integration。
先阅读模块边界,确认能力由哪个模块负责。本页说明放置代码、注册能力和验证调用的顺序;具体声明写法可参考文末的工具示例。
工具扩展路径
- 手写的
IAgwTool、IContextualTool和IToolBlock实现放在Agw.Tools,全局目录只扫描这个程序集中的手写工具。业务工具放在所属模块的Application/Tools,以 Attribute 容器声明或通过 Skill 提供,DTO 放Contracts/Tools。 - 引用
Agw.Tools.Abstractions,需要 Attribute 声明时将Agw.Tools.Generators作为 Analyzer 引用。 - 显式声明权限、参数说明和返回类型。独立工具及使用 Attribute 声明的工具容器不能保存会话状态;状态放在 Provider、会话对象或所属存储中。
- 在所属模块注册所需服务与生成声明。选择通过 Skill 提供,或显式加入全局目录。
- 验证工具发现、参数、权限、项目绑定和错误映射。
生成器输出元数据、JSON Schema 和直接调用委托。不要加入运行时反射扫描兜底。Skill 工具有两个来源:IAgentSkillRegistration.Tools 提供手写的 IProjectScopedAgwTool 实例,ToolTypes 提供 Attribute 容器类型(由 IAgwToolSet<T> 生成)。它们在执行时绑定 Project,不因注册生成模块就自动进入全局目录。
集成扩展路径
IPluginCatalog 拥有 Plugin、Connector、认证和能力源定义。定义是代码/内容资产;用户设置是 PluginInstallation,可选账号或端点是 Connection。不要将它们合成一张全局配置表。
先增加目录定义和必要的工具来源,再验证用户完成设置、账号进入 Ready 状态、绑定 Agent 和实际调用的全过程。凭据由 Infrastructure 加密保存并在调用时读取;读取和执行都要检查账号归属。通过 HTTP/SSE 发送凭据时使用 HTTPS。
选择全局工具还是 Skill 专属工具
如果工具是可单独选用的通用操作,可显式加入全局目录。如果它只服务于某个 Skill,就通过该 Skill 注册,使说明和工具一起提供给 Agent。例如,agw-job 的任务管理工具属于 Jobs 模块,并随 Skill 提供。
工具成功编译后,还要确认 Agent 实际能发现它。若目录中没有出现,应先检查生成声明和注册位置;若调用时失败,再检查 Project 绑定、权限及参数。编译通过并不等于已经完成运行时接入。
方式一:通过接口定义 Tool
适合一个类负责一个可独立调用的操作。实现 IAgwTool,声明稳定名称、分类、Plan 可用性和权限,并实现唯一必需的成员 ToAITool()。仓库工具的写法是把操作放在 Execute 方法中,再在 ToAITool() 中用 AgwAIFunctionFactory.CreateParameterObjectFunction 包装成模型可调用的函数;这个工厂是 Agw.Tools 的内部类型,所以示例放在 Agw.Tools 中。下面是一个不读写外部资源的最小示例:
IAgwTool 继承元数据接口 IAgwToolMeta,ToAITool() 把执行方法包装成模型可调用的函数。参数 DTO 和方法上的 Description 帮助模型理解何时调用、如何填参。实际异步 I/O 应参考仓库工具使用异步方法并传递 CancellationToken;业务 DTO 放在所属模块的 Contracts/Tools。
接入与使用
- 将实现放到
Agw.Tools/Impl/Tools。全局目录只扫描Agw.Tools程序集中的手写工具,放在业务模块中的IAgwTool不会被发现;业务模块改用方式二的 Attribute 容器,或把IProjectScopedAgwTool实例放进 Skill 的IAgentSkillRegistration.Tools。声明对象保持无状态,不在字段中保存当前 Project、用户或会话数据。 - 在
src/server/Agw.Shared/Tooling/ToolValueObject.cs中把工具名称加入ToolDefinitionNames及其All列表,并加入具体ToolDefinition、[JsonDerivedType]名称映射和空的或实际的 Options 类型,保持定义与实现一一对应。名称没有登记时,注册会报错 “does not have a registered ToolDefinition”。 - 在所属模块 DI 入口登记依赖,确认工具出现在
/api/tools;工具绑定到 Agent 或 Project 后,才供该执行目标使用。 - 在 Chat 让 Agent 调用该操作,检查输入和输出。直接调用 C# 方法适合单元测试,但不能证明运行时权限和 Project 绑定已接通。
有 Project 或运行时目录依赖的独立工具,应参考 IContextualTool.MaterializeAsync(接口位于 Agw.Tools/Contracts/Abstractions,与其他手写工具一样只从 Agw.Tools 程序集发现),把已校验的上下文绑定到本次贡献的函数中。不要让模型通过一个随意填写的 Project ID 决定资源归属。
方式二:通过 Attribute 定义 Tool
适合把一个服务中的多个操作声明为工具,也适合随 Skill 提供的业务能力。先添加抽象项目和生成器引用,路径按项目位置调整:
下面与接口示例实现同一个 echo 操作,二选一使用,不要同时注册同名工具:
示例容器是普通的 sealed class,其中的方法都是静态方法;后面的 IAgwToolSet<TextTools> 要求类型参数是非静态类,所以容器不能声明为 static class。AgwToolContainer 批量选择类型直接声明的 public 普通方法;AgwTool 指定名称和权限;AgwToolIgnore 排除辅助方法。没有显式名称时,默认使用方法名并移除末尾的 Async。容器及每个操作都应明确声明或继承权限;AllowInPlanMode 是独立设置。
实例容器使用显式构造函数注入,并在 DI 中注册实例类型。静态方法可通过标记 [AgwToolService] 的参数取得服务。服务参数与 CancellationToken 不进入模型可填写的参数 Schema;每次调用都有独立的异步 DI scope。
生成、注册与选用
编译器生成元数据、输入输出 Schema 和直接调用委托。以程序集 My.Module 为例,在模块组合入口登记生成模块;需要全局选用时再选择容器类型:
上述代码片段需要生成声明命名空间及所属注册扩展的引用。只包含静态方法的容器不必登记实例;包含实例方法的容器还需 services.AddScoped<YourToolContainer>()。生成模块只登记声明,不会自动公开全部工具。全局工具仍要完成具体 ToolDefinition 和 JSON 多态映射。
若工具只服务于 Skill,让 Skill 注册类使用 partial 并实现 IAgwToolSet<TextTools>,生成器补齐 ToolTypes;同时按 IAgentSkillRegistration 完成 Id、说明和创建逻辑。在所属模块的 DI 入口用 services.AddSingleton<IAgentSkillRegistration, YourSkillRegistration>() 注册 Skill,并登记生成模块和实例容器,写法参考 Jobs 模块的 JobManagementSkillRegistration。将该 Skill 绑定到 Agent/Project 后,其工具才参与运行时组合。手写的 Skill 工具实现 IProjectScopedAgwTool,放进 IAgentSkillRegistration.Tools,不应额外放进全局目录。
生成失败时先处理编译诊断:不支持的签名是 AGWTOOL001,无效声明是 AGWTOOL002。不要用运行时反射绕过诊断。完整的实例容器和 Skill 示例见 工具抽象说明。
ToolBlock:定义共享状态的一组工具
当多个操作需要维护同一份状态,例如添加 Todo、完成 Todo 和查看待办列表,应把它们作为一个 ToolBlock 整组选用。Attribute 容器只是声明方式,本身不提供会话状态隔离。
下面是仓库的 TodoToolBlock 完整实现:
Todo 的状态与生命周期
Descriptor.Members声明五个成员、各自权限和 Plan 可用性。成员不能单独注册成全局工具。MaterializeAsync创建本次能力组合使用的AgwTodoProvider,放进ToolContribution.ContextProviders,同时提供循环检查器。AgwTodoProvider把AgwTodoState保存到当前AgentSession.StateBag,并通过StateKeys声明状态键。调用时从当前 session 读取、修改并保存,不能用 static 列表或共享单例保存所有人的 Todo。- 同一 session 的后续调用可继续使用已有 Todo;不同 session 的状态分开。持久化恢复依赖外层会话保存与恢复流程,不能仅因为 Provider 中有字段就认为状态可以恢复。
TodoCompletionLoopEvaluator检查待办是否完成;与 Mode 一起启用时只在 Execute 阶段参与检查。自定义 ToolBlock 不一定需要循环检查器,按具体任务添加。
开发自己的有状态 ToolBlock
- 定义数据对象和状态范围:回合、会话或项目长期存储。会话状态参考
AgwTodoState,项目长期状态参考 Project Memory。 - 在
Agw.Shared/Tooling/ToolValueObject.cs中把名称加入ToolBlockDefinitionNames及其All列表,增加具体ToolBlockDefinition、Options 和[JsonDerivedType]名称映射,再在ToolBlockNames中加入引用该常量的运行时名称。启动时的覆盖检查会拒绝缺少定义或缺少实现的 ToolBlock。 - 实现
IToolBlock,一次声明全部成员,明确每个成员的权限与allowInPlanMode。 - 在
MaterializeAsync创建 Provider,将函数和状态操作绑定到当前上下文;把生命周期交给ToolContribution,不要缓存跨用户的 Provider 或 scoped 服务。 - 在目录和定义解析流程接通整组选用,再测试:新增、完成、移除、不同 session 隔离、保存恢复、Plan 限制与审批。
参考 Todo Provider 和 Todo 状态,不要只复制描述符而遗漏状态的读取与保存。
Plugin:从目录定义到实际调用
这里的 Plugin 是 AGW 集成目录中的代码与内容定义。当前内建示例是 GitHub;新增 Plugin 需要修改并构建服务端,不是上传任意插件包即可运行。界面用 Available integrations 展示目录,用 Configured integrations 展示用户配置的账号或端点。
| 开发对象 | 定义内容 |
|---|---|
PluginDefinition | 稳定 Id、版本、显示名、Connector 和可选 Skill 内容 |
ConnectorDefinition | 服务或协议变体,例如 GitHub Cloud |
AuthSchemeDefinition | 认证方式、用户配置字段及 OAuth 流程设置 |
CapabilitySourceDefinition | 工具由内部 C# Provider 创建,或从 MCP 服务取得 |
PluginInstallation | 当前用户的安装设置,例如 OAuth Client ID/Secret |
Connection | 当前用户配置的具体账号、凭据和 Ready 状态,绑定时使用 ConnectionId |
定义目录与认证
下面是现有 GitHub 目录实现,可作为开发新集成时的完整结构参考。OAuth 地址、scope 和字段需按目标服务的协议设置,不能照搬 GitHub 的值:
新增定义时保持 Plugin、Connector、认证方式和能力源的 Id 稳定,并让 PluginCatalogValidator 验证整个目录。InstallationFields 用于每用户的安装配置;账号级字段应放到相应认证方案的连接字段中。秘密字段使用 Secret 类型,不能把真实凭据写入目录定义。
实现能力源
Native:定义中的 Provider = "github" 对应 IConnectionNativeCapabilityProvider.Provider。实现 CreateTools(ConnectionNativeCapabilityContext),用已解析的 ConnectionId、Alias 和 ProjectId 创建工具。工具名称通常为 {alias}__{operation},防止多个账号的工具混淆。
参考 GitHubConnectionNativeCapabilityProvider:生成函数绑定账号和 Project,实际调用时创建 scope、解析 IGitHubConnectionInvoker;Invoker 再执行账号归属、Ready 状态与凭据检查。不得让模型指定任意 ConnectionId,或在单例 Provider 中缓存账号密钥。为新增操作接入当前能力源的权限元数据与执行审批流程。
MCP:使用 McpCapabilitySourceDefinition,选择 stdio、HTTP 或 SSE Transport,再通过 CredentialBindings 把安装字段、连接字段或 OAuth Token 注入所需环境变量或 HTTP Header。经过网络注入凭据时使用 HTTPS;字段引用必须与认证定义匹配。MCP 路径复用连接授权与运行时校验,不是直接把未验证的 URL 交给 Agent。
注册、内容与测试
- 在 Integrations 的 DI 入口维护目录注册;Native Provider 注册为
IConnectionNativeCapabilityProvider,调用服务按其生命周期登记,例如 GitHub 的 scoped Invoker。 - 若附带 Skill,将内容放入 Plugin 内容目录,并通过
PluginSkillDefinition.ContentPath指向SKILL.md。它提供使用说明,不自动执行第三方脚本;同时确认构建产物包含内容文件。 - 在 Available integrations 找到定义,为测试用户配置安装字段和账号。完成认证后确认 Ready,再绑定 Agent 或 Project。
- 验证一次读取和一次受控写入,检查工具名称、参数、权限及错误处理。测试使用真实实现,不使用 mock 或 fake 实现;需要真实账号或 OAuth 授权的测试不放进默认测试套件。
- 覆盖跨用户 ConnectionId、未就绪账号、失效凭据、目录字段错误、同名工具和配置变更。修改用户安装设置只应影响该用户的账号连接。
当前没有远程 Marketplace 的下载、签名与自动升级机制。完整调用链参考 GitHub Native Provider、GitHub Invoker 和 能力源定义。
验证
至少覆盖成功调用、非法参数、权限不足、外来 Connection 和未就绪 Connection。保持编译期诊断有效。测试使用真实实现,不使用 mock 或 fake 实现;依赖真实账号或外部 CLI 的测试需要显式开启,不放进默认测试套件。
实现与参考
5.5 - 测试与贡献约定
最近更新:
前提:依赖已安装。修改前阅读根目录 AGENTS.md 和 docs/human/ 中的相关规则,保留无关的本地改动。
后端检查
从仓库根运行:
测试项目使用 xUnit v3,并通过根目录 global.json 使用 Microsoft.Testing.Platform 运行。定位问题时先运行相关测试,例如 dotnet test tests/Agw.Files.Tests。单元和组合测试使用真实实现和纯选项辅助方法,不使用 mock 或 fake 实现。构造 CodexAIAgent 或 ClaudeCodeAIAgent 时会探测 CLI,这类测试作为真实 CLI 测试运行,需要显式启用并确认可执行文件可用,不放进默认测试套件。
修改错误码或异常规则后运行 dotnet test tests/Agw.Shared.Tests;修改模块依赖后运行后端架构测试 dotnet test tests/Agw.Architecture.Tests。
持久化执行的 PostgreSQL 测试(租约保护、事件顺序、活动执行升级和调度容量)通过 AGW_TEST_POSTGRES_CONNECTION_STRING 连接独立的测试实例,测试用户需要创建数据库的权限;Redis 事件投影测试使用 AGW_TEST_REDIS_CONNECTION_STRING。没有设置这些变量时,对应测试会跳过。CI 使用 PostgreSQL 18 运行 PostgreSQL 测试,并检查 TRX 结果,确认必需的测试全部执行成功;完整命令见开发文档。
改动登录相关代码时,运行 dotnet test tests/Agw.Auth.Tests。这些测试默认使用受控的提供商和各自独立的 SQLite 数据库。需要在 PostgreSQL 上验证时,把 AGW_TEST_OIDC_POSTGRES 设为测试服务器的管理连接字符串,该账号需要能够创建数据库;不要指向生产服务器。Desktop 主进程的登录与凭据存储测试使用 pnpm --filter @agw/desktop test。
客户端检查
从 src/clients 运行:
使用 oxlint/oxfmt,不是 ESLint/Prettier。修改包边界后必须通过 pnpm test:boundaries;改变 API 后先把 Development 环境的 OpenAPI 文档导出到 src/clients/packages/api/openapi.json,再运行 pnpm gen:api 重新生成 typed client,并验证调用方。
组件渲染测试通过共享的 @agw/test-harness 建立 DOM 环境;需要 API 响应时,用其中的 startApiServer 启动真实的本地 HTTP 服务,让组件走自身的请求路径。Web 的浏览器测试先运行 pnpm --filter @agw/web exec playwright install chromium,再运行 pnpm --filter @agw/web test:e2e;Playwright 会在 127.0.0.1:3101 启动独立的 Web 服务,不需要后端。
数据与提交
模型变更需要配套 SQLite 与 PostgreSQL 迁移,但只有明确授权后才生成或应用。生成时分别以 src/server/Agw.Migrations.Sqlite 和 src/server/Agw.Migrations.Postgres 为迁移项目、src/server/Agw.Standalone.Host 为启动项目,并在命令末尾传入 -- --provider sqlite 或 -- --provider postgres,完整命令见开发文档。dotnet tool restore 只安装 CSharpier,dotnet ef 需要另行安装。NoForeignKeyModelDiffer 禁止生成数据库外键,引用验证和清理由应用层/基础设施负责。
C# 使用显式构造函数,禁止 primary constructor;日期使用 DateTimeOffset。遵守根目录 AGENTS.md。提交需显式授权,并使用 Conventional Commits。
按改动选择检查
| 改动 | 至少确认 |
|---|---|
| 修复后端行为 | 相关项目构建通过,能重现原问题的验证通过 |
| 修改接口或 DTO | 导出 OpenAPI 文档并重新生成 API 类型,检查调用方及错误处理 |
| 调整模块或包依赖 | 后端架构测试或客户端边界检查通过 |
| 修改错误码 | tests/Agw.Shared.Tests 通过 |
| 修改界面 | 检查实际操作、不同屏幕宽度和相关测试;涉及 Web 浏览器行为时运行 test:e2e |
| 修改本站文档 | Hugo 严格构建、链接与中英文对应检查通过,页面显示正常 |
验证失败时保留错误信息,修复后重跑受影响的检查。提交说明应写清改了什么、如何验证,以及是否影响数据库或部署。
完成标准
缺陷修复应有可复现验证,行为改动覆盖相关成功和失败路径。文档站只改 site 时运行其 Hugo、链接和浏览器检查,无需为纯文档改动启动模型服务或执行数据库初始化。