关于 ios-agent
ios-agent 通过 XCTest 驱动 iOS 模拟器或真实 iPhone,供 iOS 开发者和构建 Agent 的人员操作设备、检查应用流程。每步返回屏幕状态,并对发送、付款等风险操作要求批准。
主要功能
- 01驱动模拟器和真实 iPhone
- 02每次操作返回屏幕状态
- 03以元素引用定位控件
- 04风险操作需先获批准
- 05提供终端、Python 库和 MCP 接入
适用场景
- 01验证应用改动是否生效
- 02让 Agent 修改 iOS 设置
- 03测试应用中的操作流程
- 04手动检查 Agent 可读取的屏幕
MCP 相关
提供包含 31 个工具、5 个资源和一个 ios_operator 提示词的 MCP 服务,支持 stdio 或 HTTP,供 MCP 客户端连接设备。
配置
本地服务的配置在各客户端中通用,复制后粘贴到客户端的 MCP 配置文件即可。
uvx ios-mcpIOS_MCP_POLICY__CONFIRM_DESTRUCTIVEAsk before an action that sends, deletes, or pays. Leave it on for a device carrying real accounts.IOS_MCP_POLICY__ENABLEDThe policy gate as a whole: approval, app blocklist, redaction, audit.IOS_MCP_WDA__BUNDLE_IDBundle id of the WebDriverAgent runner. Free Apple IDs cannot sign com.facebook.*, so device builds need their own.IOS_MCP_SIMULATOR__SHOW_WINDOWBring Simulator.app to the front when booting, so a person can watch the agent drive. Set false in CI.本地服务需要在你的电脑上安装运行环境(如 Node.js 18+)。各客户端的配置文件位置不同,请参考客户端文档。
工具
31收录的工具列表 · 更新于 2 周前
此工具无需参数。
详细介绍
ios-agent
给 AI Agent 一部 iPhone。它会检查自己执行的每一步。
ios-agent 让 AI Agent 能通过线缆或 Wi-Fi 操作 iOS Simulator 或真实 iPhone。每项操作都会返回操作后的屏幕,因此 Agent 能判断点击是否无效,或输入的文本是否没有成功输入。屏幕内容只需几百个 token,而不是几万个。任何会发送内容、付款、删除内容或联系他人的操作,都会先征求确认。它只使用 Apple 的公开 API,因此 Xcode 更新不会导致它失效。你可以通过终端、Claude Code、任何 MCP 客户端或 Python 库使用它。

以 2.5 倍速,从头到尾完成一个目标。Agent 通过深层链接打开 Maps 查看驾车时间,接着点击查看步行和公交路线,并滚动查看详情:4 次操作、1 次观察、2,767 个设备 token、49.8 秒实际用时。终端显示的是 Agent 自己的操作记录;手机则是由它操控的 iOS Simulator。
uv sync && uv run ios-agent quickstart
quickstart 会检查工具链,提供值得执行的简易修复,在缺少 WebDriverAgent 时构建它(约 20 秒,只需构建一次),然后进入手动模式,由你亲自操作设备,且无需 API 密钥。准备好使用 Agent 本身时:
uv run ios-agent "turn on bold text"
目录
- 你可以用它做什么 · 功能 · 适用对象
- 要求 · 设置
- 终端应用 · 通过 MCP 连接你自己的 Agent
- 模型看到的内容 · 安全性
- 真实硬件上的测量结果
- 这样设计的原因 · 为什么只使用 Apple 的公开 API
- 追踪 · 开发 · 贡献
你可以用它做什么
| 你的需求 | 从这里开始 |
|---|---|
| 给 Agent 一个目标并观察它执行 | uv run ios-agent "turn on bold text",参见快速入门中的演示 |
| 检查你自己的应用是否能正常运行 | docs/check-your-app.md |
| 让 Claude Code、Cursor 或任何 MCP 客户端操作设备 | ios-mcp serve,在 .mcp.json 中添加一条配置 |
| 通过线缆或 Wi-Fi 在自己的 iPhone 上运行 | docs/real-device-setup.md,然后运行 uv run ios-agent --pick "..." |
| 无需 API 密钥,亲自操作设备,看看 Agent 会看到什么 | uv run ios-agent manual |
| 直接在其基础上构建自己的 Agent,无需经过协议 | await run_goal(session, "...") 或直接使用 IosSession,参见 docs/library.md |
典型目标:检查刚刚做的更改在运行中的应用里是否生效、更改设置、从没有 API 的应用中读取答案,或在无法交给测试套件的手机上走完一个操作流程。 docs/use-cases.md 列出了目前支持的功能、每项功能的依据,以及尚不支持的内容。
功能
它知道操作何时未生效
手机 Agent 工具最常见的抱怨,是操作报告成功,但实际上什么也没发生。在这里:
- 每项操作都会返回生成的屏幕,并附带
screen_changed,因此轻点无效时会立即显现。即使在实体 iPhone 上,真正的无操作也会报告screen_changed=False,而不只是在模拟器上如此。 - 输入的文本会从字段中读回。 如果文本未能输入,工具会返回
ok: false以及字段中显示的内容,而不会谎报文本已输入。 - Agent 指定元素名称,而不是坐标。 它传递类似
e2的 ref;如果屏幕发生变化,主机就会通过六层身份匹配重新查找同一元素;如果 ref 现在指向了其他元素,则会拒绝操作。 - 开关会被设置,而不是切换。 如果开关已经开启,再要求设为
on不会有任何操作,也不会将其关闭。 - 重试是安全的。 幂等键可确保重放步骤的 Agent 框架不会重复轻点 Send。
它可通过数据线或 Wi-Fi 在真实 iPhone 上运行
- 已在运行 iOS 26.6 的 iPhone 17 Pro Max 上验证,通过 USB 和 Wi-Fi 运行时,操作次数与模拟器相同。
ios-agent doctor会检查工具链、运行时、隧道和运行器的签名到期时间,并为每项故障提供解决方法。- 设备运行器会随启动它的进程一起停止,包括收到 SIGKILL 的情况,因此崩溃的运行不会占用手机。
ios-mcp reset可清除其他残留内容。 - 设备选择器绝不会预先选中实体手机,而且可在会话期间通过
/device切换设备。
它很省 token
- 屏幕以精简摘要的形式传回,而不是无障碍 XML:真实第三方应用屏幕上的节点数从 251 个精简到 12 个元素,十三条黄金流程中每步消耗 50 到 474 个 token。
- 如果下一屏内容相似,操作只会返回发生变化的部分。
- 包含 300 行的 Contacts 列表,在一次观察中只需 438 个 token 即可返回。
ios_find会搜索完整的树,查找摘要遗漏的内容,因此压缩绝不会永久隐藏控件。- 捆绑的 Agent 每次运行只查看屏幕一次,因为每项操作都会返回生成的屏幕。
它会在执行风险操作前征求同意
- 发送、付款、购买、删除、确认、退出,以及任何会触达他人的操作(点赞、关注、分享、发消息),都必须在执行前获得批准。如果没有人可以征求同意,操作就会被拒绝。
- 密码来自 Mac 的钥匙串,并直接发送到设备。密码绝不会进入提示词或审计记录;输入后,会话返回的每个屏幕都会在密码原处显示
[secret]。 - 在任何客户端看到屏幕之前,卡号和电子邮件地址都会被遮盖;每项操作也都会记录在可导出的审计记录中。
Xcode 更新后,它仍能正常工作
所有操作都通过 XCTest 执行,这是 Apple 随附的 UI 测试框架。我们评估过通过私有框架实现的更快路径,但最终决定不采用;而 Xcode 27 让依赖这些路径的多个工具无法使用。请参阅为何只使用 Apple 的公共 API。
三种接入方式,支持任意模型
- 一个终端应用,会在屏幕旁流式显示模型的推理过程;操作、token 数量和费用也会随增长实时显示。
- 一个 MCP 服务:提供 31 个工具、5 个资源和一个
ios_operator提示词,支持通过 stdio 或 HTTP 使用。请参阅工具参考。 - 一个 Python 库
IosSession,服务和 Agent 都构建于其上,因此你自己的 Agent 可以跳过该协议。 - 可通过两个环境变量切换使用 Anthropic、OpenAI、Azure OpenAI、Gemini、Vertex AI、Bedrock、Groq、Mistral 或本地 Ollama 模型。
指标可测,数字也可以重新运行验证
39 次 Agent 运行全部成功,所需操作数仅为手写基准的 1.14 倍,总费用为 $1.50。黄金流程会跟踪令牌数、耗时以及每个元素的发现方式;如果免费系列发生变化却没有记录原因,CI 就会失败。请参阅在真实硬件上测量。
它不会做什么
- 不支持 Android,也不支持其他平台,不进行构建或性能分析。
- **Flutter 画布和 WebView 没有可读取的树结构。**摘要会明确说明这一点,并指向屏幕截图,而不是返回一个看起来空白的屏幕。请参阅 ADR 0007。
- **审批关卡无法防御植入屏幕内容中的指令。**请参阅 ADR 0013。
- 物理 iPhone 需要签名后的运行器,免费 Apple ID 的配置文件有效期为七天。
适用对象
- 构建 Agent 的人员:需要通过 Claude Code、Cursor 或任何 MCP 客户端操作 iOS。
- iOS 开发者:希望编码 Agent 在模拟器或自己的手机上检查更改。
- **任何研究 Agent 工程的人。**评估工具和决策记录展示了测量了什么,以及哪些方案因数据不支持而被否决。
如果你需要 Android、React Native 性能分析、Xcode 构建,或并行使用多台设备,那么其他工具会更适合你。文档网站提供了坦诚的比较。
要求
| 用途 | 你需要 |
|---|---|
| 模拟器 | macOS、Xcode 16.3+、iOS 运行时、Python 3.12+ |
| 物理 iPhone | 上述要求,外加 go-ios、开发者模式和签名身份。请按照 docs/real-device-setup.md 操作;这比使用模拟器要复杂一些,其中有几步看起来像是出了问题,但其实没有 |
Xcode 不附带模拟器运行时。如果 xcrun simctl list runtimes 输出为空,运行 xcodebuild -downloadPlatform iOS 即可获取一个(约 8 GB)。如果已安装运行时,但尚未创建模拟器,ios-agent 会主动为你创建一个:这部分大约只需一秒。
设置
uv sync
./scripts/prepare_wda.sh simulator # builds WebDriverAgent, once
uv run ios-agent doctor # says exactly what is still missing
每当出现异常时,首先应运行 doctor。它会检查工具链、模拟器运行时、隧道、WebDriverAgent 的签名到期时间和模型,并针对每项故障提供解决方法,而不是等问题之后演变为连接错误才暴露出来。
应用会在接触设备前运行同样的检查,因此,对于尚未完成设置的机器,它会在约一秒内告知问题,而不是等模拟器启动后才告知。
终端应用
uv run ios-agent # open it, decide later
uv run ios-agent "turn on bold text" # give it a goal
uv run ios-agent --pick "turn wi-fi off" # choose the device from a list
uv run ios-agent manual # drive it by hand, no model needed
uv run ios-agent devices # what is reachable

它会实时显示模型生成的推理,在旁边展示模型正在读取的摘要,并持续在屏幕上更新各项数据:操作数、观察数、设备令牌数和费用。
/ | 命令菜单,输入时会筛选 |
/device · ctrl+o | 在会话中途切换手机或模拟器 |
esc | 在下一步停止,并生成完整报告;再次按下则中止 |
ctrl+r · ctrl+s | 重新读取屏幕 · 保存审计记录 |
| 拖动选择 | 将所选内容复制到剪贴板,无需按键 |
--inline | 在提示词下方的短区域中运行 |
--no-tui | 输出纯文本行,适用于管道 |
**manual 模式无需 API 密钥。**它会手动执行 Agent 的九个动词,是在尚无人用此工具操作过的应用上调试感知功能的最快方式。
前端遵循一条通过断言而非争辩确立的规则:观察运行过程不得改变运行成本。tests/tui/test_cost.py 会分别用 TUI 包装和不包装同一任务,并逐项比较所有计数器,确保完全一致。
选择模型
提供方是配置,而非依赖。循环通过 LangChain 的 init_chat_model 构建,因此切换只需设置两个环境变量并添加一个额外依赖:
uv sync --extra openai
IOS_AGENT_PROVIDER=openai IOS_AGENT_MODEL=gpt-6.1-sol uv run ios-agent "..."
支持 Anthropic、OpenAI、Azure OpenAI、Gemini、Vertex AI、Bedrock、Groq、Mistral,以及本地 Ollama 模型。请参阅 agent/README.md。
通过 MCP 连接你自己的 Agent
31 个工具和 5 个资源,可通过 stdio 或 HTTP 使用。
无需克隆仓库,直接从 PyPI 安装。先将 WebDriverAgent 构建一次到
~/Library/Application Support/ios-mcp/wda,然后让任意客户端指向 uvx:
uvx ios-mcp prepare-wda simulator # about 20 seconds, once
uvx ios-mcp doctor # says what, if anything, is missing
{ "mcpServers": { "ios": { "command": "uvx", "args": ["ios-mcp"] } } }
从克隆的仓库运行,这是本 README 其余部分采用的方式:所有客户端都通过同一命令启动它:uv run --directory <path to this clone> ios-mcp serve。请使用绝对路径;桌面应用不会从你的项目目录启动。克隆仓库中的构建文件位于 vendor/wda,可从那里找到。
**Claude Code。**在此仓库中,已通过 .mcp.json 完成配置。从其他位置运行:
claude mcp add ios -s user -- uv run --directory /path/to/ios-agent ios-mcp serve
Cursor(~/.cursor/mcp.json,或项目中的 .cursor/mcp.json)和
Claude Desktop(~/Library/Application Support/Claude/claude_desktop_config.json)
使用相同的配置块:
{
"mcpServers": {
"ios": {
"command": "uv",
"args": ["run", "--directory", "/path/to/ios-agent", "ios-mcp", "serve"]
}
}
}
VS Code(.vscode/mcp.json)将键命名为 servers:
{
"servers": {
"ios": {
"type": "stdio",
"command": "uv",
"args": ["run", "--directory", "/path/to/ios-agent", "ios-mcp", "serve"]
}
}
}
支持 MCP elicitation 的客户端会在审批关卡拦截任何操作前直接向你询问;不支持的客户端则会将决策交还给你,并附上签名,以便你在重试时传递。请参阅 审批与密钥。
然后用日常语言提出你的需求。服务内置了一个 ios_operator
提示词,用于指导“观察/操作/验证”循环,因此客户端无需重新发明这一套流程。对于使用 HTTP 而非 stdio 通信的客户端,
ios-mcp serve --transport http --port 8765 只会在本机提供服务:它没有身份验证,因此会检查每个请求的来源,并且不会绑定到其他地址,除非指定 --allow-remote。请参阅威胁模型。
或者跳过协议,直接导入库:
outcome = await run_goal(session, "turn on bold text")
模型能看到什么
screen: com.apple.Preferences / "Display & Text Size" fp=3872280e
e1 button "Accessibility" id=BackButton @(38,84)
e2 switch "Bold Text" =0 id=ENHANCE_TEXT_LEGIBILITY @(336,161)
e3 button "Larger Text, Off" id=LARGER_TEXT @(190,216)
在真实模拟器上的 13 个黄金流程中测得:每步 50 到 474 个 token,按每个流程取平均值。其中一个流程使用真实的 300 行列表,即填充了 300 个人物的通讯录;其他工具会报告超时。一次观察会在 1.35 秒内返回 166 个原始节点和 438 个 token,因为 UIKit 只会实例化屏幕上的行。
Agent 将 e2 传回操作。它从不编写 XPath,也从不猜测坐标。如果屏幕移动导致引用过期,宿主会根据元素身份重新查找同一个元素,而不是直接失败。
安全性
自动化操作某人的真实手机并不属于测试自动化。默认启用以下保护:
- 任何匹配 Send、Pay、Buy、Delete、Confirm 或 Sign Out 的操作都必须在执行前获得批准,可通过 MCP elicitation,或由外部人工介入层处理的
action_requires_approval错误来完成。批准仅适用于单个操作:批准 Send 不代表也批准 Delete。 - 按下任何会触达他人的按钮也一样:Like、Follow、Comment、Reply、Share、Invite、Message、Post。撤销点击并不会撤销通知。参见 docs/adr/0014。
- 没有审批者时,运行将处于无人值守状态,所有需要通过安全门确认的操作都会被拒绝,因为无法回答的问题不等于同意。
ios_type_secret会从主机密钥链读取值,并直接发送到设备。该值绝不会进入提示词或审计记录,并且输入后返回的所有屏幕中都会将其替换为[secret]。请使用密码字段:截图不会被清除。- 卡号(包括分组显示的
4111 1111 1111 1111格式)和电子邮件地址会在会话中脱敏,因此 MCP 服务、捆绑的 Agent 和终端应用收到的都是脱敏后的屏幕。 - 重复失败或检测到循环时,会停止会话。
- 设备选择器绝不会预先选中实体手机。要连接实体手机,始终需要按下一次按键。
有关这些保护无法防范的情况,请参阅 SAFETY.md 和威胁模型。所有默认设置都可以通过 IOS_MCP_* 环境变量、.env 或可选的 ios-mcp.toml 修改,优先级依次递减。复制 .env.example 到 .env 可查看完整列表。
在真实硬件上的测量结果
评测工具是在 Agent 之前构建的,这也是这些数字得以存在的唯一原因。最近一次完整测量使用 gpt-5.6-sol,对 13 个任务各运行 3 次:
| 成功 | 39/39 |
| 观察 | 41 次,而 oracle 的下限为 39 次 |
| 操作 | 123 次,是手写 oracle 的 1.14 倍 |
| 模型轮次 | 216 |
| 故障 | 感知 6 次、策略 6 次、模型 0 次 |
| 拒绝、不可用运行 | 0 次、0 次 |
| 成本 | 6 分 39 秒内 $1.50 |
成本按每百万 token 输入 $4、输出 $20 计算。最初发布时标为 $1.87,当时评测工具忽略了模型旁设置的价格,按 Claude Opus 的费率计算;token 数量以及各组之间的所有比率均未受影响。
此后,测试套件扩展到 19 个任务,其中 4 个会在 Agent 读取的屏幕中植入指令。针对 docs/adr/0015 运行时,使用相同模型,每个任务运行 3 次,结果为 55/57 次通过,操作数是 oracle 的 1.30 倍,成本为 $2.61;在 12 次尝试中,Agent 没有服从任何植入指令。该次运行记录了通过数、操作数和成本,没有记录观察数或故障数,因此这些指标仍应参考上表。
每次运行的观察次数约为 1 次,整个测试集中最多相差 2 次;其中还包括在一款由 Apple 以外的公司开发的应用中执行的两个任务。这就是下限,因为每个操作的响应都已包含该操作产生的屏幕。
在 ios_find 让 Agent 能够读取原始辅助功能树,而不只是从中生成的摘要之前,操作数是 oracle 的 1.25 倍。提升完全来自调用它的两个任务:轮次从 43 降至 27,操作从 10 降至 3;而另外 11 个从未调用它的任务,轮次仅从 195 降至 189,操作从 125 降至 120。它并非没有代价:多一个动词,每次运行的每个轮次都要增加约 190 个提示词 token,无论是否使用。详情见 docs/adr/0011,这也是不增加第十一个动词的原因。
之所以测量模型轮次,是因为它是最后一个未考察的维度:将多个操作分组到一个轮次中,完全不会改变设备端的工作量。尽管允许这样做,模型一次也没有这样做,因此 docs/adr/0010 否决了这个想法,并保留了用于限制模型原本会执行路径的防护。
已在真实 iOS 设备上验证,包括实体 iPhone
Tier 1 在进程内的脚本化设备上运行,因此它的数据只是对一个虚拟设备的描述。在三个层级中,目标都是 turn on Bold Text:
| 操作次数 | 观察次数 | 摘要 | |
|---|---|---|---|
| 脚本化虚拟设备 | 3 | 1 | 不适用 |
| iOS 27.0 模拟器 | 4 | 1 | 166 个原始节点 → 15 个元素,272 个 token |
| iPhone,iOS 26.6,Wi-Fi | 3 | 1 | 140 个原始节点 → 15 个元素,243 个 token |
每个层级都只需观察一次,这正是设计论据所依据的数字;而在手机上耗时 48.6 秒,模拟器上则只需几秒。26.5 运行时移除后,我们在 iOS 27.0 上重新测量了模拟器这一行;多出的一次操作是模型运行时选择了更长的路径,并非该层级缺少某项能力。手机这一行仍显示 26.6,是因为设备运行器的配置描述文件已过期,因此目前无法重新运行 tier 3。
我们通过导航到该位置并读取 value="1",独立于 Agent 的说法确认了开关状态,之后又恢复了原状。
最重要的是,在手机上,真正的无操作仍会报告 screen_changed=False。 如果实体设备在两次稳定快照之间的指纹发生了变化,那么验证步骤在硬件上就会悄无声息地失效,而所有模拟器和虚拟设备测试却依然全部通过。
硬件需要经过两重明确选择才会启用:device 标记和 IOS_MCP_ALLOW_DEVICE=1。因为设备已连接,并不代表用户同意更改其设置。
这样构建的原因
200 行列表的原始 WebDriverAgent 页面源码约有 37,000 个 token。每次点击后都重新读取,会在寥寥几步内耗尽上下文窗口。由此得出四项设计决策,它们就是本项目的全部设计:
| 感知过程会考虑预算限制 | 在真实的第三方界面中,将 251 个原始节点精简为 12 个元素;每步 50 到 472 个 token |
| 操作会返回操作后生成的屏幕 | 往返次数减半;屏幕相似时会返回差异 |
| 在主机端进行解析 | 分为六个层级,因此重试无需消耗任何模型 token,而一次往返则会耗费一整轮 |
| 操作前询问,而不是操作后询问 | 这样得到的回答才仍有意义 |
仓库中的其他一切都是基于这些设计构建的。
为什么只使用 Apple 的公共 API
这里的所有操作都通过 XCTest(Apple 提供的 UI 测试框架)和 WebDriverAgent 访问设备。我们评估过两种看似更快的途径,但最终没有采用:
| 途径 | 测量结果 | |
|---|---|---|
| Xcode 的 Accessibility Inspector 服务,无需签名的运行器 | 通过逐个聚焦元素来读取,每个元素耗时 60 到 80 ms:读取 Settings 根页面耗时 3.3 到 4.4 秒,而 WebDriverAgent 耗时 3.7 秒;没有画面,而且读取时会滚动屏幕 | ADR 0016 |
| CoreSimulator 的私有辅助功能框架,idb 和 AXe 使用的途径 | 相比 WebDriverAgent 快 10% 到 23%,未达到 50% 的门槛;而且在 Xcode 27 上,它仍会启动 XCTest 会话来完成引导 | ADR 0017 |
这些途径节省的时间都不值得承担相应的风险,而这种风险并非假设。Xcode 27 用 Device Hub 替换了 Simulator.app,并迁移了 SimulatorKit.framework,于是依赖这些私有组件的工具接连出现了公开问题:
- MobileBuildMCP(当时名为 XcodeBuildMCP),#453:其捆绑的 AXe 仍在旧位置查找 SimulatorKit。
- Argent #406:Device Hub 替换 Simulator.app 后,设备启动失败;#465:其模拟器服务无法在 macOS 27 上加载 SimulatorKit。
- MobileBuildMCP #535:键盘工具会静默失效,因为 System Events 无法连接到 Device Hub。
相同的改名也影响了本项目的一处功能:仅用于显示模拟器窗口的 open -a Simulator 不再有效。现在它会按 bundle id 打开 Device Hub。自动化流程没有改变:它所接触的一切都是 Apple 有文档说明、并且会在后续版本中延续的接口。
使用公共 API 也并非毫无麻烦。WebDriverAgent 紧跟 Xcode 更新,因此我们会固定版本并通过 scripts/prepare_wda.sh 重新构建,而不是盲目跟进。手机需要一个签名运行器;在免费 Apple ID 下,其 provisioning profile 有效期为七天。通过 Wi-Fi 启动仍需使用 xcodebuild。ios-mcp doctor 会检查工具链、运行器构建、设备和隧道,并说明需要修复的内容。
为什么自动化运行在主机上,而不是手机上
iOS 应用无法自动化其运行设备上的其他应用。沙盒会阻止跨进程访问,而且即使用户同意,沙盒应用也无法使用辅助功能 API。XCUIAutomation 只能在由主机驱动、由 testmanagerd 启动的 XCTest 运行器中执行。因此,引擎必须运行在 Mac 上,这也是本项目没有 iOS 应用的原因。
跟踪
每次 Agent 运行都可以记录为 OpenTelemetry span:包括运行本身的 span,以及每个图节点、每次模型调用和每次工具调用的 span,并携带任务 ID、步骤、工具名称、输入和输出 token 数、成本、分辨率级别及验证器结果。此功能默认关闭;关闭时不会生成任何内容。
uv sync --extra tracing
IOS_AGENT_TRACING=otel uv run ios-agent "turn on bold text" # any OTLP backend
IOS_AGENT_TRACING=langsmith uv run ios-agent "turn on bold text" # needs LANGSMITH_API_KEY
otel 会读取标准的 OTEL_EXPORTER_OTLP_* 变量,因此只需配置一个端点即可连接 Phoenix、Langfuse 或收集器。要使用 Phoenix 在本地查看跟踪:
uvx --from arize-phoenix phoenix serve # UI and OTLP on http://localhost:6006
OTEL_EXPORTER_OTLP_ENDPOINT=http://localhost:6006 IOS_AGENT_TRACING=otel \
uv run ios-agent "turn on bold text"
Span 只包含计数和名称,不包含提示词、屏幕内容或回复;每个 span 在发出前都会经过会话的脱敏器处理,因此通过 ios_type_secret 输入的值不会进入跟踪;有一项测试会写入一个这样的值,再读取导出的 span 进行验证。在 22 个 Agent 任务上分别关闭和开启跟踪进行回放,token 数没有变化,每个 span 仅增加 0.06 ms 的耗时。参见 docs/adr/0023,并运行 uv run pytest tests/evals/agent --trace-agent otel 来跟踪一次评测运行,并将每个 trace ID 与其结果一同记录。
开发
uv run pytest tests/unit # 856 tests, no device, no model
uv run pytest tests/tui # 234 tests, the terminal front end
uv run pytest tests/integration # 18 simulator + 3 device tests
uv run pytest tests/evals -s # golden flows, with cost per flow
uv run ruff check . && uv run mypy ios_mcp agent/ios_agent tui/ios_tui
评测套件是质量门槛:它会报告每个流程的令牌数、耗时、操作数和分辨率等级分布。如果某个流程从 exact 漂向 text-fuzzy,这是它即将变得不稳定的首要信号。Agent 任务还会声明一个 操作下限,即手写预言机所需的操作数,并以该预言机为依据进行断言,防止它偏离目标;此外还会声明一个 轮次下限,即完美批处理器完成相同路线所需的模型调用次数。轮次下限不是预先声明的,而是推导得出:batch.simulate_turns 会遍历预言机实际执行的操作,并在批处理保护机制会停止的位置拆分,因此衡量的是保护机制,而不是随手填写的数字。失败也会归因:报告会指出失败来自设备、感知、模型还是策略门槛,而不只是说明某处出错。
这些数据会随时间保存在 tests/evals/history.jsonl 中,每次测量运行对应一条已提交的记录。CI 会运行唯一无需成本的系列(使用脚本化设备运行预言机),如果任何数据发生变化却没有同时提交新记录,就会失败。手动运行的测试切片也保存在同一文件中:
python scripts/eval_trend.py show --suite agent-oracle
python scripts/eval_trend.py append .artifacts/evals/agent-s5.json --suite agent-model
保护机制采用精确校验而非范围校验,因为它检查的每个数字都是在固定路线上的计数,路线中不涉及模型、网络或时钟。请参阅 docs/adr/0009。
uv run python scripts/tui_screenshot.py # render the front end to .artifacts
测试套件通过,并不能说明终端应用看起来是什么样。这个脚本已经发现了 8 个断言未能捕捉到的显示错误。
三个发行包位于同一个 uv 工作区中,依赖关系只朝一个方向。请参阅 ARCHITECTURE.md:
ios-tui terminal front end depends on ios-agent, ios-mcp
ios-agent goal-directed agent depends on ios-mcp
ios-mcp library + MCP server depends on neither
参与贡献
欢迎提交问题和拉取请求。CONTRIBUTING.md 介绍了环境设置、开发循环,以及 5 项至关重要而非仅关乎风格的约定。CI 会在 Linux 和 macOS 上运行 ruff、mypy 和 1061 项离线测试。
许可证
MIT。请参阅 LICENSE。
mcp-name: io.github.emazaheri/ios-agent
评论
一个开放协议,规定了 AI 应用如何以统一方式连接外部工具与数据源。客户端负责与模型对话,MCP 服务负责提供工具、资源和提示模板,两者通过标准消息通信,同一个服务可以被不同客户端复用。