mcpField
I
ios-agent

ios-agent

本地服务
github.com开发工具33 周前更新

关于 ios-agent

ios-agent 通过 XCTest 驱动 iOS 模拟器或真实 iPhone,供 iOS 开发者和构建 Agent 的人员操作设备、检查应用流程。每步返回屏幕状态,并对发送、付款等风险操作要求批准。

主要功能

  1. 01驱动模拟器和真实 iPhone
  2. 02每次操作返回屏幕状态
  3. 03以元素引用定位控件
  4. 04风险操作需先获批准
  5. 05提供终端、Python 库和 MCP 接入

适用场景

  1. 01验证应用改动是否生效
  2. 02让 Agent 修改 iOS 设置
  3. 03测试应用中的操作流程
  4. 04手动检查 Agent 可读取的屏幕

MCP 相关

提供包含 31 个工具、5 个资源和一个 ios_operator 提示词的 MCP 服务,支持 stdio 或 HTTP,供 MCP 客户端连接设备。

配置

本地服务的配置在各客户端中通用,复制后粘贴到客户端的 MCP 配置文件即可。

mcp.json · 通用配置
{
"mcpServers": {
"emazaheri-ios-agent": {
"command": "uvx",
"args": [
"ios-mcp"
],
"env": {
"IOS_MCP_POLICY__CONFIRM_DESTRUCTIVE": "<IOS_MCP_POLICY__CONFIRM_DESTRUCTIVE>",
"IOS_MCP_POLICY__ENABLED": "<IOS_MCP_POLICY__ENABLED>",
"IOS_MCP_WDA__BUNDLE_ID": "<IOS_MCP_WDA__BUNDLE_ID>",
"IOS_MCP_SIMULATOR__SHOW_WINDOW": "<IOS_MCP_SIMULATOR__SHOW_WINDOW>"
}
}
}
}
启动命令uvx ios-mcp
需要配置的环境变量
IOS_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+)。各客户端的配置文件位置不同,请参考客户端文档。

安装包
pypiios-mcp0.6.0

工具

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 库使用它。

CI Docs License: MIT Python 3.12+ macOS Tests

ios-agent 通过操作 Apple Maps 回答问题

以 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"

目录

你可以用它做什么

你的需求从这里开始
给 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:

操作次数观察次数摘要
脚本化虚拟设备31不适用
iOS 27.0 模拟器41166 个原始节点 → 15 个元素,272 个 token
iPhone,iOS 26.6,Wi-Fi31140 个原始节点 → 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

评论

支持 Markdown

第一次接触 MCP?

从协议是什么,到在客户端里装上第一个服务,这几条回答覆盖了大多数入门问题。

一个开放协议,规定了 AI 应用如何以统一方式连接外部工具与数据源。客户端负责与模型对话,MCP 服务负责提供工具、资源和提示模板,两者通过标准消息通信,同一个服务可以被不同客户端复用。