关于 OpenAdapt: your agent decides, OpenAdapt enters it and checks it saved
OpenAdapt Agent 让 AI Agent 调用已演示的工作流,在缺少可用 API 的应用中录入数据并回读记录确认保存。它适用于仍需人工操作 EMR 或保险方门户的团队;无法确认时会返回明确结果,交由人员检查。
主要功能
- 01按演示重放应用工作流
- 02输入前核验目标记录
- 03保存后回读记录确认
- 04返回四类最终结果
- 05通过请求 ID 避免重复录入
适用场景
- 01将转诊信息写入 EMR
- 02在保险方门户录入授权信息
- 03处理需要人工复核的保存结果
MCP 相关
提供 MCP 服务,向客户端暴露 list_workflows、run_workflow 等工具;README 介绍了 Claude Code 沙盒连接方式。
配置
本地服务的配置在各客户端中通用,复制后粘贴到客户端的 MCP 配置文件即可。
工具
本地服务需要在你的电脑上运行后才能读取工具,维护者暂未提供工具列表。
详细介绍
OpenAdapt Agent
此仓库已迁移至 OpenAdapt monorepo(
packages/agent)。该仓库已归档且为只读;请在那里提交问题和 PR。PyPI 包名openadapt-agent保持不变。
你的 AI Agent 决定要输入什么。OpenAdapt 在应用中输入内容,并检查是否已保存。
如果你的 Agent 会读取转诊单、接诊表或授权文件,并判断哪些内容应录入病历,但仍需由人将结果输入一个没有可用 API 的应用,就可以使用它。例如,电子病历(EMR)和保险方门户。这个包就是你的 Agent 用来完成这些输入工作的工具。
- 由人或你的 Agent 在实际应用中向 OpenAdapt 演示任务。OpenAdapt 会重放这些步骤,并且默认情况下,运行过程不会调用 AI 模型。
- 输入内容前,OpenAdapt 会检查当前是否打开了正确的病历。保存后,它会重新读取病历。
- 你的 Agent 会收到四种结果之一:已完成并检查、已在保存前停止、需要检查病历,或未运行。如果 OpenAdapt 无法确认保存成功,就会明确说明,并由人检查病历。
- 它运行在客户的电脑上,也就是能够打开该应用的电脑上。你的 Agent 或代表它运行的小程序也必须在这台电脑上运行,因为它需要启动 OpenAdapt 并直接与之通信。如果你的 Agent 运行在自己的云端,请咨询我们了解托管方案。
选择一项如今由你的 Agent 交给员工处理的任务,然后联系我们,讨论如何接入。工程师可以先试用沙盒。
为你的 Agent 提供程序,而不是鼠标
你的 Agent 不会把屏幕截图发送给模型再进行点击。它会将已训练的工作流作为一个类型化工具调用;OpenAdapt 每次都会运行相同的步骤,并且默认情况下,Agent 收到的是结果和计数,而不是屏幕或记录的值。
openadapt-agent serve --mode production --bundles <bundle or directory of bundles>
openadapt-agent emit-skill <bundle> --out ~/.claude/skills
三步试用无需账号即可运行沙盒。提供自己的工作流和编写 Agent Skill介绍了这两种命令。
对客户团队的影响
| 步骤 | 现在 | 使用 OpenAdapt 后 |
|---|---|---|
| 阅读文档并决定要输入什么 | 你的 Agent | 你的 Agent |
| 打开应用并找到正确的病历 | 员工 | OpenAdapt 会在输入前检查病历是否正确 |
| 输入值并保存 | 员工,重新输入 Agent 的输出 | OpenAdapt,在员工使用的同一界面中操作 |
| 确认保存 | 员工,如果他们再次查看 | OpenAdapt 会在报告完成前重新读取病历 |
| 内容不匹配 | 员工在输入时发现,或之后由某人发现 | OpenAdapt 会在保存前停止,等待人工处理 |
| 员工负责处理的事项 | 每份文档 | 已停止的运行和待检查的病历。系统不会通知任何人,因此需要有人查看已停止运行的列表。 |
作为参考,两项医院时间研究显示,将一份传真转诊单录入电子病历约需 10 到 12 分钟(UCSF,JAMIA Open 2020;Calderdale and Huddersfield NHS Foundation Trust,HFMA 2024)。在部署完成测量之前,我们不会公布节省时间的数据。
谁构建什么
flowchart LR
A["Your agent reads the document<br/>and picks the values"]
B["OpenAdapt enters them in the app<br/>on your customer's computer<br/>and reads the record back"]
C["Your agent acts<br/>on the outcome"]
D["A person at that computer<br/>decides or checks the record"]
A -->|"workflow, inputs, request_id"| B
B -->|"one outcome per request"| C
B -.->|"needs_review or not_sure_if_saved"| D
| 你构建 | OpenAdapt 提供 |
|---|---|
| 用于读取文档并决定要填写什么的 Agent | 在真实应用中通过一次或多次演示学习到的工作流,由人或 Agent 演示任务 |
使用你自己的 request_id 调用 run_workflow | 在客户的计算机上执行运行,在输入前进行记录核查,并在保存后再次核查记录 |
| 你的产品如何处理每种结果 | 每个请求返回一个结果,并且即使你的 Agent 重复使用 request_id,也不会再次录入 |
| 针对四种结果编写的测试 | 可按需返回每种结果的沙盒 |
客户提供运行所需的计算机,以及负责处理暂停运行的人。人或 Agent 会在 Web 应用、原生 Windows 应用以及 Citrix 或远程桌面中演示任务。运行前,由人确认结果。请参阅录制第一个工作流,或联系我们了解如何设置。
三步试用
沙盒是一个无需账号的练习服务。它包含一个工作流 add_triage_note,用于在 MockMed(一款使用虚构患者数据的诊所测试应用)中的第一条转诊记录上添加备注。
你需要已登录的 Claude Code 和 uv。如需使用其他客户端或自己的代码,请参阅连接自己的 Agent。
-
添加沙盒服务。Claude Code 只会将其保存到当前文件夹。
claude mcp add openadapt -- uvx --python 3.12 openadapt-agent serve -
在同一文件夹中,使用
claude启动 Claude Code。Claude Code 会启动该服务。 -
提示:“使用 OpenAdapt 添加分诊备注 ‘Synthetic: recheck blood pressure in 2 weeks’,请求 ID 为 demo-0001。”
你的 Agent 应调用 list_workflows,然后使用以下参数调用 run_workflow:
{"workflow": "add_triage_note", "inputs": {"note": "Synthetic: recheck blood pressure in 2 weeks"}, "request_id": "demo-0001"}
结果如下(省略了部分字段):
{
"outcome": "done",
"label": "Done and checked",
"safe_to_retry": false,
"what_happened": "Simulated sandbox result (no app was opened): Saved the change and read the record back to confirm it.",
"next_step": "none",
"proof": "simulated",
"run_id": "run-31ecb9d66db84f1aba8cb5f6",
"model_calls": 0
}
此安装会模拟每次运行,不会打开 MockMed,而且每个结果都会注明这一点。如需观看真实引擎执行任务,请参阅使用真实引擎操作 MockMed。
openadapt-agent 从 PyPI 安装,并且需要 openadapt-flow 2.1.0 或更高版本;该依赖也在 PyPI 上,并会随它一同安装。如需试用尚未发布的更改,请使用 --from git+https://github.com/OpenAdaptAI/openadapt-agent 替代软件包名称。
查看所有结果
在输入中添加 sandbox_case,并为每次测试使用新的 request_id,即可请求每种情况。例如:“现在试试 false_saved_banner 情况,请求 ID 为 demo-0002。”
sandbox_case | outcome | MockMed 的行为 |
|---|---|---|
normal(默认) | done | 保存备注,并且记录核查会找到该备注。 |
duplicate_record | needs_review | 两次列出同一条转诊记录,因此 OpenAdapt 无法判断应打开哪条记录。它会在保存前停止。 |
false_saved_banner | not_sure_if_saved | 显示已保存消息,但备注并未存储。 |
timeout_after_save | not_sure_if_saved | 保存备注后超时并报错。 |
app_offline | did_not_run | 应用无响应,因此不会启动任何操作。 |
沙盒会跨会话记住每个 request_id。使用相同输入发送已用过的 request_id,会返回先前的结果。使用不同输入发送,例如新的 sandbox_case,则会返回 did_not_run,原因是 request_id_conflict。如需重新开始,请删除 ~/.openadapt/agent-sandbox,或将 OPENADAPT_AGENT_SANDBOX_DIR 设置为一个空文件夹。
使用真实引擎驱动 MockMed
tutorial extra 会让 OpenAdapt 背后的引擎 openadapt-flow(Flow)在隐藏浏览器中驱动 MockMed。将沙盒服务替换为此服务:
claude mcp remove openadapt
claude mcp add openadapt -- uvx --python 3.12 --from 'openadapt-agent[tutorial]' openadapt-agent serve
服务启动后,Flow 会记录一次工作流,并在需要时下载浏览器(约 300 MB)。第一次请求需要等待这一过程。我们在 Mac 上测试时,第一次请求耗时约 80 秒。调用在 60 秒后返回 running,Agent 随后调用 get_run 获取结果。如果设置耗时超过 15 分钟,请求将以 did_not_run 结束。使用 Flow 时,done 结果的 proof 为 "local",而不是 "simulated"。
模拟沙盒会在其 list_workflows 结果中提供相同的命令。
Agent 会收到什么结果
outcome 是四种最终值之一。运行仍在进行时,值为 running。
outcome(标签) | 发生了什么 | Agent 接下来要做什么 |
|---|---|---|
done(已完成并核验) | OpenAdapt 已保存这些值,并重新读取了记录。 | 将请求标记为已完成并保留 run_id。不要再次发送。 |
needs_review(保存前已停止) | 它在保存前停止,运行会一直等待,直到客户电脑前的某个人作出决定。没有写入任何内容,除非 record_changed 为 unknown:当运行等待某人批准保存(标签为 Waiting for approval)时,该运行中先前的保存可能已经生效。 | 不要重新开始相同的工作。稍后调用 get_run 查看决定。 |
not_sure_if_saved(检查记录) | 保存可能已经生效,但 OpenAdapt 无法确认。 | 绝不要重试。让某个人在应用中检查记录。 |
did_not_run(未运行) | 此调用没有写入任何内容。如果出现 request_id_conflict,具有相同 request_id 的先前请求可能已经保存。 | 如果 safe_to_retry 为 true,请修复原因并重新发送相同请求。否则请遵循 next_action。 |
running(运行中) | 运行未能在 wait_seconds(默认值为 60)内完成。 | 使用 run_id 调用 get_run,直到 outcome 发生变化。 |
根据 outcome 和 safe_to_retry 进行分支处理。next_step 会以固定代码标明下一步操作,这样代码就不必解析 next_action:none、call_get_run、wait_for_person、check_record、fix_inputs、fix_setup 或 retry。
重新发送请求
request_id 是你为请求指定的 ID,例如转诊 ID。不要在其中放入患者详细信息。一个请求由一个 request_id、一个工作流和一组输入组成。
- 重新发送相同请求不会再次输入这些值。它会返回最新结果,并标记为
replayed: true。 - 如果该结果为
did_not_run且safe_to_retry: true,重新发送将启动新尝试;每个request_id最多尝试 5 次。 - 遇到
invalid_input后,你可以修正输入并使用相同的request_id重新发送。遇到其他任何可重试结果后,请发送相同的输入。 - 对已使用的
request_id使用不同工作流或不同输入,会返回带有request_id_conflict的did_not_run。不会运行任何新操作,且先前的请求可能已经保存。使用结果中的first_run_id调用get_run,查看该请求的处理情况。 - 没有任何工具可以清除
not_sure_if_saved。如果检查记录的人发现仍需完成这项工作,请使用新的request_id将其作为新请求发送。
防止重复录入的检查仅覆盖一个运行文件夹。请参阅设置服务选项中的 --runs-dir。
了解其他字段
label:可显示的简短状态,例如“已完成并检查”。reason:来自固定列表的代码,用于说明原因,例如invalid_input或request_id_conflict。每个代码都在 contract.py 的REASONS中,docs/DESIGN.md 说明了每个代码的选择方式。what_happened和next_action:可向用户显示的固定句子。它们绝不会包含输入值或屏幕文字。proof:对于在客户电脑上经过检查的done,值为local;对于未打开应用的沙箱运行,值为simulated;对于其他所有结果,值为none。model_calls:对于到达 Flow 的运行,表示该次运行调用 AI 模型的次数。除非启用了模型定位(即让 AI 模型判断点击位置的回退机制),否则为 0(参见 安全性)。record_changed:值为yes、no或unknown。只有 OpenAdapt 能证明没有写入任何内容时,值才为no。request_id_conflict会返回unknown,因为先前的请求可能已经保存。needs_repair:适用于运行在某个步骤停止的needs_review或did_not_run结果。它会提供步骤 ID、原因和一次性repair_token,绝不会提供屏幕内容。如果用户为修复启用了屏幕访问权限,你的 Agent 可以调用get_repair_screen和teach_repair来提出修复方案,但必须由用户批准。参见 docs/REPAIR.md。
三种工具
| 工具 | 参数 | 返回值 |
|---|---|---|
list_workflows | 无 | 每个工作流的 name、purpose、done_means(完成的判定标准)以及以 JSON Schema 表示的 inputs。 |
run_workflow | workflow、inputs、request_id,以及可选的 wait_seconds(0 到 600,默认值为 60) | 一个结果。 |
get_run | run_id,以及可选的 wait_seconds(0 到 600,默认值为 60) | 该次运行的最新结果,包括用户对已停止运行所作的决定。 |
request_id 的长度为 4 到 128 个字符。它以字母或数字开头,其余字符可以是字母、数字、.、_、: 或 -。
调用时如果参数无效,例如缺少 request_id,会返回工具错误,而不是结果。对于 run_workflow,该错误会以“Nothing ran.”结尾。get_run 只能查找同一运行文件夹中的运行记录。
沙箱提供全部三种工具。使用你自己的工作流时,只有在以 --mode production 或 --mode attended 启动服务时,run_workflow 才会出现(参见运行你自己的工作流)。
开发者设置
该软件包是一个通过 stdio 通信的本地 Model Context Protocol(MCP)服务,并提供 openadapt-agent 命令。它需要 Python 3.10 到 3.12。它会检查输入、阻止重复提交,并将 Flow 的报告转换为四种结果之一。openadapt-flow 用于记录、重放和检查工作流。
若要单独试用 Flow,请使用 pip install openadapt 安装 OpenAdapt 启动器,然后运行 openadapt flow tutorial 或 openadapt quickstart --break-it。
连接你自己的 Agent
任何 MCP 客户端都可以通过命令 uvx 启动服务。在读取 mcpServers JSON 文件的客户端(例如 Claude Desktop 或 Cursor)中,添加:
{
"mcpServers": {
"openadapt": {
"command": "uvx",
"args": ["--python", "3.12", "openadapt-agent", "serve"]
}
}
}
在你自己的 Python 代码中,使用 MCP Python SDK(pip install mcp):
import asyncio
import json
from mcp import ClientSession, StdioServerParameters
from mcp.client.stdio import stdio_client
SERVER = StdioServerParameters(
command="uvx",
args=["--python", "3.12", "openadapt-agent", "serve"],
)
async def main():
async with stdio_client(SERVER) as (read, write):
async with ClientSession(read, write) as session:
await session.initialize()
call = await session.call_tool("run_workflow", {
"workflow": "add_triage_note",
"inputs": {"note": "Synthetic: recheck blood pressure in 2 weeks"},
"request_id": "demo-py-0001",
})
result = json.loads(call.content[0].text)
print(result["outcome"], result["next_step"])
asyncio.run(main())
SDK 只需少量环境变量即可启动服务。如需传入其他变量(例如 OPENADAPT_BUNDLE_KEY),请在 StdioServerParameters 中添加 env=。
scripts/smoke_client.py 是一个更完整的示例,可运行所有沙盒用例。在克隆的此仓库中运行 pip install -e .,然后运行:
python scripts/smoke_client.py -- uvx --python 3.12 openadapt-agent serve
如果你的 Agent 在自己的云端运行,就无法访问此服务,因为它没有网络监听器。启动服务的程序必须在客户的计算机上运行。一种实现方式是在客户的计算机上运行一个轻量级工作进程:它通过自己建立的连接接收来自你服务的请求,启动此服务,调用 run_workflow,再将每个结果发回。该工作进程充当你的 Agent,因此应像保护任何其他患者数据访问路径一样保护它的连接。如需使用托管方案,请联系我们。
提供你自己的工作流
Bundle 是一个编译后的工作流文件夹,其中包含 workflow.json,或者包含 workflow.json.enc,其密钥存放在 OPENADAPT_BUNDLE_KEY 中。--bundles 接受一个 Bundle 或一个包含多个 Bundle 的文件夹。
| 命令 | Agent 可获得的内容 |
|---|---|
openadapt-agent serve | 沙盒。 |
openadapt-agent serve --bundles DIR | 你的工作流(会列出,但不可运行,run_tools_enabled: false),以及用于查看过去和已停止运行的只读工具。 |
openadapt-agent serve --mode production --bundles DIR --runs-dir /var/lib/openadapt/runs | 你的工作流的运行。 |
openadapt-agent serve --mode attended --bundles DIR --runs-dir /var/lib/openadapt/runs | 运行,以及对已停止运行的决策。 |
openadapt-agent serve --allow-run 是 --mode production 的旧版形式;如果没有 --bundles,则是沙盒的旧版形式。
每次运行都会通过 openadapt-flow run。Flow 会在 Chromium 中驱动 Web 应用,访问地址由 --url 设置。它也能驱动桌面应用、RDP 和 Citrix 会话;这些场景可能需要通过 --extra-run-arg 传入 Flow 自身的目标标志。openadapt-flow README 介绍了每种应用类型。
准备好可运行的工作流
Flow 会拒绝未通过其要求的检查的 Bundle。此时,你的 Agent 会收到 did_not_run 和 not_ready_to_run,而 failed_checks 会列出每项缺失的检查,例如 not_certified 或 no_readiness_test。首次提供新的录制时,通常会遇到这种情况。
Flow 的要求取决于部署配置(--config)中设置的配置文件。主要区别如下:
- 未设置配置文件:Bundle 必须通过
openadapt-flow certify,根据策略完成认证。 standard或regulated:需要认证、针对该 Bundle 版本有效的准入(已签名的就绪测试),以及记录检查;该检查会通过单独的路径读取已保存的记录,例如应用的 API、数据库或第二个会话。在standard配置文件下,如果 Citrix 会话没有单独读取记录的方式,运行结果不能是done。demo:无需认证,但 Flow 不会确认保存结果,因此运行结束时状态为not_sure_if_saved。
Flow 的执行配置文件页面介绍了每种配置文件。
设置服务选项
| 标志 | 作用 |
|---|---|
--runs-dir DIR | 运行记录和 Flow 证据的存放位置。默认值为 ~/.openadapt/runs(如果设置了 OPENADAPT_AGENT_RUNS_DIR,则使用其值),绝不会使用客户端启动服务的文件夹;沙盒使用 ~/.openadapt/agent-sandbox。服务启动时会打印所用文件夹。防止第二次进入的检查仅覆盖一个运行文件夹,因此,同一项工作对应的每个服务都应使用相同的文件夹。较早版本使用 ./runs;如果该文件夹中有这些版本的记录,而你没有传入 --runs-dir,服务就不会启动,因此你需要选择要保留哪个文件夹。 |
--url URL | 应用的地址,会传递给每次 Flow 运行。 |
--config YAML | Flow 的部署配置(示例),用于设置配置文件以及是否允许模型 grounding。 |
--policy NAME-OR-PATH | Flow 据以认证的策略,例如 clinical-write 或 permissive。 |
--timeout SECONDS | 单次运行可执行的时长(默认 600 秒)。人员批准保存所花的时间不计入其中。达到时限后停止的运行会标记为 not_sure_if_saved。 |
--approval-mode MODE | 是否由人员批准每次保存。如果不指定,Flow 会自行决定:在 standard 和 regulated 模式下,每次保存前运行都会停止,直到人员批准(each_item)。not_gated 会为此服务启动的每次运行关闭该限制;每个结果都会在 technical.approval_mode 中记录这一设置。 |
--headed | 显示浏览器。在 Web 应用中,要继续或跳过已停止的运行,需要由人员操作。 |
--extra-run-arg ARG、--flow-cli CMD | 更改调用 Flow 的方式。任一选项都可能放宽 Flow 的检查,例如 --extra-run-arg=--allow-unencrypted。 |
--allow-protected-export、--allow-synthetic-recorded-defaults、--allow-model-grounding | 默认关闭。请参阅安全性。 |
调用方无法更改 --url、--config、--policy、--timeout 或 --approval-mode。唯一例外是,服务启用了 --allow-url-override 时,已弃用工具中的 url 可以更改。如果工作流有自己的名为 url 的输入参数,该参数仍是工作流的输入,覆盖参数则为 target_url_override。openadapt-agent serve --help 会列出所有标志。
等待人员批准的运行
在 standard 和 regulated 模式下,Flow 会在每次保存前停止,等待人员批准(默认最长 15 分钟)。等待期间,run_workflow 和 get_run 会返回 needs_review,原因是 waiting_for_approval,并且 record_changed: "unknown",因为同一次运行中较早的保存可能已经完成。人员可以通过 openadapt-flow item-approval show RUN_DIR 查看正在等待批准的保存;其中 RUN_DIR 是运行文件夹中的 run_id 文件夹,然后使用 item-approval approve 或 decline 作出答复。如果无人及时答复,运行会在保存前停止,并返回 needs_review,原因是 approval_needed。此服务没有用于批准保存的工具:批准操作由人员执行。
使用其他工具
使用 --bundles 时,服务还会注册用于工作流和运行的只读工具:get_workflow、get_run_report、list_needs_attention 和 get_attention_item。使用 --mode production 或 --mode attended 时,服务还会为每个工作流注册一个已弃用的 run_workflow_<id>。这些工具不接受 request_id,因此重试可能会重复输入值。请改用 run_workflow。
list_workflows、run_workflow 和 get_run 会返回与其 outputSchema 相匹配的 structuredContent;该 schema 定义在 contract.py 中,并且还会返回相同的 JSON 文本。
决定已停止的运行
因等待人员操作而停止的运行会留在该计算机上 Flow 的「需要关注」列表中。系统不会通知任何人。list_needs_attention 会显示该列表。
使用 --mode attended 时,你的 Agent 可以通过 continue_attention、skip_attention、reject_attention、teach_attention 或 escalate_attention 发送决定。使用该计算机的人员需要在表单中确认每项决定。继续和跳过还需要 --config。如果客户端无法显示表单,服务端会拒绝该决定,人员则需改用 Flow 控制台:
openadapt-flow console --attend --allow-actions --bundles DIR --runs RUNS_DIR
docs/DESIGN.md 介绍了每项决定。人员作出决定后,get_run 会显示新的结果。
使用卡片描述工作流
卡片为工作流提供 name、purpose、done_means 和输入描述,供 Agent 在 list_workflows 中查看。没有卡片时,工作流会获得一个不透明的名称。将 openadapt-card.json 放在 workflow.json 旁边:
{
"name": "enter_referral",
"purpose": "Create an outgoing referral for an existing patient in the clinic EMR.",
"done_means": "The referral appears in the EMR's referral report for that patient.",
"inputs": {
"patient_mrn": {"description": "Clinic MRN of the patient.", "pattern": "^[0-9]{6,10}$"},
"referral_date": {"description": "Date of the referral.", "format": "date"}
}
}
卡片文本会传给 Agent 使用的模型,因此不要在其中填写患者详情。如果卡片格式错误、purpose 或 done_means 超过 300 个字符、描述超过 200 个字符,或者文本看起来包含标识符(连续 5 位或更多数字、电子邮件地址或电话号码),服务端会忽略整张卡片并记录警告。
编写 Agent Skill
openadapt-agent emit-skill BUNDLE --out ~/.claude/skills 会为单个工作流写入一个 SKILL.md:介绍其功能、输入、如何调用 run_workflow,以及每种结果出现后应如何处理。Skill 不包含记录的值或机密,你仍需单独添加服务端。--include-bundle 还会将 bundle 复制到 Skill 旁边。该副本可能包含记录中的值,因此应像保护记录一样妥善保护它。
每个 Skill 都以其工作流命名,因此 enter_referral 会变为 enter-referral。以下两个名称为保留名称:
computer-use,因为助手会在每次需要控制屏幕的请求中加载该 Skill。openadapt-gui-write,这是适用于此仓库在 skills/openadapt-gui-write/SKILL.md 中提供的任何工作流的通用 Skill。
如果工作流名称转换后会与其中任一名称相同,emit-skill 会将 Skill 命名为 openadapt- 加上工作流的 ID,例如 openadapt-workflow-1a2b3c4d5e6f7a8b9c0d1e2f。生成的 Skill 不会替换同一文件夹中的通用 Skill。
记录第一个工作流
serve --authoring 会添加录制工具,例如 observe、start_record、click、pause_for_input、stop_record、compile 和 admit。docs/DESIGN.md 列出了全部 14 个工具。人员或你的 Agent 可以使用这些工具,在 Web 应用、原生 Windows 应用、RDP 或 Citrix 会话中演示任务;同时,人员需留在计算机旁登录并接受结果。一个任务可以通过一次或多次演示来学习。录制服务不会启用运行。
-
添加录制服务。
--url会在新的 Chromium 窗口中打开应用,且不会使用已保存的登录信息;--headed会保持该窗口可见,以便人员登录。claude mcp add openadapt-authoring -- uvx --python 3.12 --from 'openadapt-agent[tutorial]' openadapt-agent serve --authoring --url https://app.example.com --headed -
让你的 Agent 与人员一起录制任务。当 Agent 暂停以等待登录时,人员在该窗口中登录应用。
-
任务完成后,Agent 调用
compile。它会将 bundle 写入<runs-dir>/authoring/bundle;默认路径为~/.openadapt/runs/authoring/bundle。 -
Agent 调用
admit。随后,你的 MCP 客户端会向人员显示确认表单,只有人员在表单中作出确认后,bundle 才会被接受。如果客户端无法显示表单(MCP 表单征询),admit会拒绝请求,不会接受任何内容。 -
让 bundle 做好运行准备(参见准备好运行工作流)。然后使用
--mode production --bundles <runs-dir>/authoring/bundle提供服务。 在所有平台上,Web 应用都使用--url URL --headed。如果没有--url,服务器会在 Linux 上退出;在 macOS 上,它会使用客户端启动服务器时位于前台的窗口,否则会退出。
对于原生 Windows 应用,请在 Windows 计算机上已登录的桌面会话中启动 Flow 的 Windows Agent 服务端(python -m openadapt_flow.backends.win_agent.server --port 5001),并传入 --windows-agent-url http://localhost:5001。Agent 可以在这台计算机上运行,也可以在另一台计算机上运行,例如 Mac。默认情况下,服务器仅监听 Windows 计算机,因此若要从另一台计算机访问,请通过 SSH 转发端口,或通过 HTTPS 提供服务。Agent 的点击和按键会经过回放使用的同一合成输入路径;Windows 能提供 UI Automation id 时,录制内容会保留每个被点击控件的 UI Automation id。将 OAFLOW_AGENT_TOKEN 设置为服务器和 Agent 共用的同一值。
对于 RDP 或 Citrix 会话,请传入 --remote-window APP(客户端应用,例如 "Microsoft Remote Desktop"),或传入 --citrix;如果应用有多个窗口,还需传入 --remote-window-title。远程会话仅支持屏幕:没有 DOM 或 UI Automation 树,因此 observe 不会返回任何节点,Agent 会像人一样在客户端窗口中点击 x,y 像素并按键。若要让 Agent 看到该窗口,请添加 --authoring-screens scrubbed,这会启用 screen 工具,返回已清除标识符的画面;如果清除失败,则不会共享任何内容。--authoring-screens unscrubbed 会跳过清除步骤。默认情况下,屏幕功能处于关闭状态。
Windows、RDP 和 Citrix 录制介绍了 Windows Agent 服务端、Agent 在另一台计算机上运行时为何需要它、如何启动它、令牌,以及 RDP 和 Citrix 的像素操作路径。
录制内容会将每个步骤标记为由 Agent 或人员执行(events.jsonl 中的 actor,meta.json 中的 demonstrated_by),且仍由人员接受结果。在 Windows 上,如果未设置上述任何标志,这些工具只能告诉人员要点击什么。
ChatGPT 和 Claude 在 Web 浏览器中无法在你的计算机上启动服务器。要从其中一个录制,请从 https://openadapt.ai/start 开始。openadapt.ai 为录制任务提供运行器链接(其中包含 bind=oab_)后,请在装有该应用的计算机上运行:
openadapt-agent authoring connect '<runner link>'
该程序会认领任务,通过出站 HTTPS 轮询 openadapt.ai,并在允许聊天账户驱动任务前先在终端征求你的同意。不要将它与启动器的 openadapt connect 混淆,后者用于将计算机与 OpenAdapt Cloud 配对。详情请参阅 docs/MAILBOX_CLI.md。
安全性
- 服务仅通过 stdio 通信,且没有登录功能。任何能向其输入端写入内容的对象,都将以启动服务的操作系统账户身份运行,因此不要通过网络或隧道暴露服务。
- 默认情况下,Agent 只能看到卡片、固定句子、不透明 ID 和计数。记录的值、路径、报告和屏幕文本都保留在客户的计算机上。例外是记录工具产生的错误,其中可能包含 Flow 的错误消息。
--allow-protected-export会将记录的值、路径、报告和 Flow 的输出发送给 Agent。仅当 Agent 所用的模型可能会看到应用数据时才使用此选项。- 输入通过临时文件传递给 Flow,该文件只有所有者可以读取,且输入绝不会出现在命令行中。此软件包自身的运行记录会保存输入的指纹,而非输入内容。
- Flow 会在
--runs-dir下的文件夹中保留每次运行的证据。在我们的沙盒测试中,该文件夹包含一份报告,其中有输入的值,以及每个步骤前后的屏幕截图;计算机上的其他账户也能读取这些截图。请将运行文件夹视为患者数据,并限制其读取权限。 - 模型定位功能会将屏幕截图发送给 AI 模型,以便在找不到记录的控件时确定点击位置。此功能默认关闭。部署配置可以将其开启,
--allow-model-grounding则会为已停止运行的决策启用此功能。启用后,屏幕截图可能会离开计算机。 --allow-synthetic-recorded-defaults会使用记录中的值填充缺失输入。此选项仅用于合成演示,因为没有任何机制会检查工作流是否为合成工作流。
请按照 SECURITY.md 中的说明报告漏洞。
密封凭证
Seal 是 OpenAdapt Cloud 对 Execute 收据所作的 Ed25519 签名。只有满足以下所有条件时,Agent 才会报告 sealed: true:
- 运行已关联到 Cloud Execute 执行:使用
FlowRunner.run(..., cloud_execution_id=...),或运行openadapt-flow run --cloud-execution-id ID,并设置OPENADAPT_EXECUTE_API_KEY。结果为 VERIFIED 后,Flow 会获取 Cloud 收据,并将其写入report.json中的execute_receipt。之后运行openadapt-flow attach-seal RUN_DIR --execution-id ID也会执行相同操作。 - 收据签名通过此计算机上由人工固定的密钥验证。Agent 检查运行时绝不会获取密钥。
只需固定一次密钥。将打印出的指纹与 OpenAdapt 发布的指纹进行比较,然后再输入密钥 ID:
openadapt-agent seal keys pin # fetches https://app.openadapt.ai/api/public/seal-keys
openadapt-agent seal keys show
OpenAdapt 轮换密钥时,请再次运行 pin。新密钥也需要经过相同的确认。Cloud 撤销的密钥会直接标记为已撤销,不会再次询问。Cloud 停止列出的密钥仍会保持固定状态。
任何人都可以离线检查 Seal(收据、运行报告或 webhook 正文):
openadapt-agent seal verify runs/<run_id>/report.json
openadapt-agent seal verify https://example.com/receipt.json --json
限制
- 你的 Agent 或代其运行的程序,必须在客户的计算机上运行。
- 运行停止时不会通知任何人。必须有人检查
list_needs_attention或 Flow 的控制台。 - 阻止重复提交的检查仅覆盖一个运行文件夹。每次都要传入相同的绝对路径
--runs-dir。 - 如果服务在运行期间退出,运行状态会显示为
not_sure_if_saved,而 Flow 仍可能完成该运行。 - 此服务本身不会签发任何签名收据。只有当运行已关联到 OpenAdapt Cloud Execute、Cloud 已对其收据签名,并且该签名通过你固定的密钥验证时,
proof才为sealed(参见密封凭证)。 - 使用 openadapt-flow 2 时,每次保存都必须经过人工批准,除非操作员指定其他模式(
serve --approval-mode problems_only或not_gated)。你的 Agent 会收到原因是waiting_for_approval的needs_review,由运行 OpenAdapt 的计算机上的人员进行批准。未获得批准之前,不会保存任何内容。 - 每次调用仅携带一个请求,不支持批量调用。
- 账户、客户隔离、机群策略和托管运行均由 OpenAdapt Cloud 负责。
发布状态
在将某个版本用于真实患者数据之前,请查看已签名的生产记录。准入期限最长为 30 天,并且可以撤销。
在 Flow 的 standard 和 regulated 配置下,每个工作流版本也需要单独准入(参见准备好运行的工作流)。截至 2026-10-14,工作流准入公开列表中的所有条目均来自合成测试(remote-safe-synthetic)。
软件包历史
在版本 2 之前,此软件包运行用于操控屏幕的 AI Agent。现在,这个名称指的是调用它的 Agent。客户的工作流通过 --bundles 提供,绝不会随此软件包一起发布,也不会出现在其注册表条目中;从注册表安装后,软件包默认以只读模式启动。MCP 注册表读取 server.json,Smithery 从 manifest.json 打包,而 llms.txt 则为 AI 助手介绍此软件包。参见 docs/DISTRIBUTION.md。
开发
pip install -e ".[dev]"
ruff check src tests scripts
pytest -q
OPENADAPT_AGENT_E2E=1 pytest -q tests/test_sandbox_flow.py # needs .[tutorial] and Chromium
python scripts/smoke_client.py # the sandbox over real stdio
python -m build
python scripts/check_release_artifacts.py dist
python scripts/check_dist.py dist/*
npx -y @anthropic-ai/[email protected] validate manifest.json
npx -y @anthropic-ai/[email protected] pack . openadapt-agent.mcpb
许可证
MIT。参见 LICENSE。完整设计见 docs/DESIGN.md,产品文档位于 docs.openadapt.ai。
评论
一个开放协议,规定了 AI 应用如何以统一方式连接外部工具与数据源。客户端负责与模型对话,MCP 服务负责提供工具、资源和提示模板,两者通过标准消息通信,同一个服务可以被不同客户端复用。