工具和性能

使用 Claude Code 和 Android CLI 进行智能体工程

扬声器

关于

演讲简介

告别繁琐的复制粘贴,让 AI 智能体成为你的得力助手。本次讲座以实际示例为导向,将向您展示如何使用 Claude Code 和 Android CLI 提升智能体工程水平。我们将演示一个完整的工作流,以自动执行复杂的开发任务并更快地发布功能。

您将学习:

  • 使用 Android CLI、Skills、Hooks 和 MCP 优化测试框架的 token 效率。
  • 将长时间运行的任务分流并并行化给子智能体。
  • 设置持续验证循环,以阻止提前终止并运行,直到测试通过。

摘要

  • Android CLI 为编码智能体提供对 Android 工具(例如模拟器和 Firebase Crashlytics)的 shell 访问权限。它位于您的 shell 空间中,可跨智能体运行。
  • 将智能体对话控制在 150,000 个 token 左右,以防止上下文失效。将工作拆分为范围明确的问题,并在静默模式下运行 Gradle,以避免产生冗长的日志。
  • 将 AGENTS.md 保持在 250 行以内,并将其保留用于永久性规则,例如架构限制。让智能体修改此文件会降低性能并增加费用。
  • 确定性钩子和特定于上下文的技能可以更好地管理智能体操作,而无需使用庞杂的文件。仅安装经过审核的技能,或从基础 Android CLI 技能开始。
  • 验证循环可避免开发者充当手动 QA 测试人员。分层检查,先运行快速单元测试,最后运行慢速模拟器。

资源

Gemini Notebook

主题

  • claude-code
  • android-cli
  • agentic-engineering
  • 基准比较
  • 性能

转写文稿

简介和环境设置

  • 大家好,我是 Ben,来自 Android 开发者关系团队。

  • 我是 Steven,产品经理。

  • 今天,我们将讨论如何使用 Claude Code 和 Android CLI 以智能体的方式开发应用。

  • 所以,我认为可以肯定地说,我们作为开发者的角色正在发生一些变化,而且变化速度非常快,事实上,坦白说,本次演讲的内容可能已经过时了,尤其是如果您是在线观看的话。

  • 因此,我们在撰写内容和呈现信息时采取了前瞻性的立场,但他们今天运行的演示是基于现实的,所以现在应该很可靠。

  • 另外,虽然我们在本次演讲中使用了 Claude Code,但这些信息并不局限于特定智能体。

  • 它更像是一种思维方式,因此应该适用于您在构建应用时喜欢使用的任何工具。

  • 因此,我们希望您开始思考,在未来您将管理自主智能体团队,如何为它们创造成功的条件。

  • 当它们无法实现某项功能或类似任务时,我们不能只是放弃并说:“哦,AI 还做不到这一点。”我们需要退一步,思考缺少了什么信息,并像对待今天的 bug 一样对待它。

  • 如果您阅读过 Claude Code、Codex、Antigravity 等智能体 Harness 开发团队发布的任何内容,就会发现他们的团队实际上就是这样开发这些 Harness 的。如果我们把这些看作是对未来的窥探,那么这可能就是我们所有人未来的发展方向。

  • 因此,现在可能是成为构建者、成为 Android 开发者最令人兴奋的时刻,但如果您和我一样,您可能会发现很难确切知道应该关注什么。

  • 作为开发者,我们需要能够真正随智能技术而扩展的工具和工作流,这样,当新模型拓展技术边界时,我们之前的所有努力才不会白费。

  • 我们希望每一次模型改进都能为客服人员带来更智能的工作流程,最终为用户带来更好的体验。

  • 今天,我们将介绍四个主题。

  • 首先,我们将解释为什么为智能体设置一个能让其成功运行的环境如此重要。

  • 然后,我们将简要介绍上下文以及如何最好地管理上下文。

  • 之后,我们将介绍一些可供 Android 开发者在智能体中使用的最佳工具,最后,我们将说明为何要在 Agentic Workflows 中添加循环。

  • 好的,我们开始吧。

  • 所以,环境。

  • 但具体是什么意思呢?

  • 正如我之前所说,我们正在努力为智能体创造一个能够成功运行的环境,而且无需您时刻盯着,不断重新提示或纠正其方向。因为只有做到这一点,您才能真正解锁并行运行多个智能体的能力,而这正是大幅提升工作效率的关键所在。当您拥有这些智能体团队,让它们为您分担工作时,效率就会实现质的飞跃。

  • 但开源不仅仅是提供代码访问权限。

  • 他们需要访问准确的文档,包括项目规范和项目工作规则。

  • 这是显而易见的。

  • 还有一些其他做法,比如人们现在将智能体连接到团队聊天空间,这不仅是为了启动智能体,更是为了提供决策背景,让智能体了解导致他们被分配某项任务的决策过程。因为作为开发者,你在解决问题时会用到这类潜意识信息,所以这对你的智能体也很有帮助。

  • 以及过往的决策历史记录和拉取请求。

  • 他们应该能够看到您在拉取请求中收到的评论、他们被提醒的事项等,然后您会发现他们可以处理并解决这些问题。

  • 此外,您无法在没有设备或模拟器的情况下编写 Android 代码,因此您也不应期望智能体能够做到这一点。

  • 我知道它们看起来很棒,似乎无所不能,但模拟器确实很有帮助。

  • 性能分析器也是如此。

  • 如果您希望他们致力于提升性能,他们应该能够进行性能分析,这需要能够访问真实设备。

  • 理想情况下,您的智能体还应该能够与应用使用的任何后端服务进行通信。

  • Android CLI 正是为此而生。

  • 如果您还没听说过,我们在“工具新变化”演讲中也提到过,Android CLI 是我们新推出的 CLI,用于与各种 Android 工具进行交互。

  • 它本身不是 AI 产品,只是一个 CLI,即命令行界面。

  • 因此,它可让您访问 Android SDK 管理器、启动模拟器等各种功能。

  • 它还可连接到 Crashlytics 等工具和后端。

  • 它适用于您使用的任何代理,只需将其放在 shell 空间中即可。

  • 所以,是的。

  • 您可以通过此链接安装它,但我认为直接看它的实际效果会更简单。

演示:使用 Android CLI 修复 ANR

  • 好了

  • 因此,我们不想只是简单地解释为什么为智能体做好准备如此重要,而是想将这一原则真正应用到我们构建的名为 Sideline 的生产应用中。

  • Sideline 是一款面向网球运动员的 Android 应用,可为他们提供有关球的位置、球员位置和球场位置的实时反馈。

  • 它通过视频回放提供离线指导反馈,并提供最快速度、移动距离和最长对打回合等健身数据。

  • 这一切都通过直接在 Android 设备上运行的自定义 TF Lite 模型实现。

  • 首先,我想说的是,我们显然无法解决我们不知道的问题。

  • 因此,我们使用 Android CLI 将 Firebase Crashlytics 添加到我们的开发者环境中,这让我们发现了一些我们甚至不知道正在发生的问题。

  • 第一个问题是,Pixel 11 Pro Fold 设备上发生了应用无响应 (ANR) 错误,但在模拟器中无法重现。

  • 幸运的是,Android CLI 支持 Android 设备串流。

  • 我们让智能体去解决这个问题后,它创建了与发生 ANR 的设备的连接,这对我来说特别有用,因为当时我甚至没有 Pixel 11 Pro Fold 来验证修复效果。

  • 因此,通过让智能体能够访问验证修复所需的设备,我们最终能够扩展其功能集,实现更多可能。

  • 为了节省时间,我提前运行了所有实验,并在此处进行了总结。

  • 简单来说,我们遇到的问题是与 Android 17 相关的关联调用。

  • 这是一个快速的两行修复,在我看来很好。

    setenv("KMP_AFFINITY", "disabled", 1);
    setenv("KMP_INIT_AT_FORK", "false", 1);
  • 因此,我创建了拉取请求,将其合并,并使用提交到 Play 的新 build 进行了更新。

  • 因此,如果我们没有设置具备成功所需功能的编码环境,就无法发现真正的问题,也无法验证修复方案。

  • 因此,在 1.0 build 中,您可以看到问题已得到解决。

  • 不过,新问题也随之出现,我们稍后会讨论这些问题。

管理上下文和 token 限制

  • 好了

  • 接下来是:上下文。

  • 大约一年半到两年前,时间并不长,但在 AI 领域,这已经是一个时代了。当时,大家都在竞相扩大上下文窗口,理论上,我们向模型提供的信息越多,得到的结果就越好。我们甚至做过一些疯狂的尝试,比如试图将整个 developer.android.com 网站的内容都包含在提示中,但效果并不理想。

  • 不过,尽管上下文窗口大小已基本趋于稳定,模型能力仍在不断提升。

  • 这就是 Android Bench 1.0。

  • Android Bench 是我们用于评估 AI 编写 Android 代码能力的基准。

  • 其中的任务很贴近实际。

  • 这些正是您正在研究的内容,我们可以看到上下文窗口在 100 万这个节点上趋于平稳,但模型能力仍在持续提升。

  • 但背景信息仍然是固定预算,您希望将其留给重要的内容。

  • 您不希望其中包含对您正在解决的确切问题没有帮助的内容。

  • 许多智能体 Harness 实际上并没有向你开放完整的 100 万上下文窗口,因为他们觉得这没有意义。

  • 如果他们这样做,结果只会更糟。

  • 实际上,这里有一个最佳平衡点,它会因模型而异,但如果您能将对话控制在 15 万个 token 左右,就能充分发挥模型的威力,而不会出现上下文衰减。

  • 但上下文不仅仅是您输入的内容。

    [
      {
        "role": "system",
        "content": "You are an expert Android engineering agent..."
      },
      {
        "role": "workspace_context",
        "content": { "project_root": "/workspace/android-app", "build_system": "Gradle (Kotlin DSL)", "target_sdk": 35 }
      },
      {
        "role": "available_tools",
        "content": [ { "name": "read_file" }, { "name": "edit_file" }, { "name": "bash" }, { "name": "skill_android_cli" } ]
      },
      {
        "role": "user",
        "content": "ProfileViewModelTest is failing when loading errors. Fix the ViewModel and verify with unit tests."
      },
      {
        "role": "assistant",
        "tool_calls": [ { "name": "read_file", "arguments": { "path": "app/src/main/.../ProfileViewModel.kt" } } ]
      },
      {
        "role": "tool",
        "content": "class ProfileViewModel(...) : ViewModel() { ... // full file contents + Gradle output appended here }"
      }
    ]
  • 实际上,在您看不到的幕后,还有很多工作要做。

  • 它由多个部分组成。

  • 首先是系统指令。

  • 系统指令由您的代理提供。

  • 这有点像一个提示,告诉它如何与这个智能体合作,以及它应该采取什么样的行为。

  • 此外,还有工作区信息,例如当前工作目录、拥有的 SDK、已安装的技能(我们稍后会详细介绍),以及 MCP 工具和智能体提供的任何工具。

  • 模型需要知道它可以调用这些函数,因此这会占用上下文。

  • 但最重要的一点是,每次您向智能体发送提示或新消息时,系统都会发送完整的消息和工具调用历史记录。

  • 这些时间累积起来会非常可观,尤其是在使用 Gradle 时。

  • 我想大家都知道,Gradle 日志非常长,非常冗长。

  • 其中大部分内容都不是必需的。

  • 因此,这里有一个小提示,请注意这一点。

  • 您可以在静默模式下运行 Gradle。

    ./gradlew assembleDebug --quiet
  • 或者,较大的智能体 Harness 会为您截断这些内容。

  • 因此,Claude Code 和 Android Studio 不会发送完整的 Gradle 日志。

  • 但如果您使用的是极简智能体,因为它们的设计理念是把所有内容都发送给模型,让模型来做判断,所以 mini-SWE-agent 会发送完整的 Gradle 日志,这会导致成本迅速飙升。

  • 但如何才能将词汇量控制在 15 万这个神奇的窗口内呢?

  • 关键在于使用工作流。

  • 而且工作流有很多种。

  • 我非常喜欢 Matt Pocock 的课程,他提供了一系列技能,可以帮助您管理这些会话。

  • 因此,它从名为“grill-me”的技能开始。

  • 您可以在刚开始整个项目或项目中的新功能时运行此技能,让智能体向您提出一系列问题。

  • 所以,你可能会说“grill-me”。

  • 我想在应用中构建一个,我不知道,一个新时间闹钟管理器。”

  • 然后,它会开始向您提问,例如“我们应该在什么位置实现它?”“它属于哪里?”

  • 这样可以消除问题中的所有歧义,让您不再困惑,而是将问题记录在纸上或问题跟踪系统中。

  • 然后,我们运行下一个技能,即编写一份大型规范文档。

  • 然后,另一项技能会将其拆分为多个问题,并将其提交到您首选的问题管理器中。

  • 然后,每个问题都应该大致符合 15 万这个窗口。

  • 然后,您可以在终端或 IDE 中选择一个问题,无论您喜欢哪种方式,都可以构建、验证循环,最后清除上下文,不再保留对话历史记录,并且始终保持在窗口内。

  • 好了

AGENTS.md 最佳实践

  • 接下来,我们来谈谈AGENTS.md。

  • 在AGENTS.md中,您可以为代理提供额外信息,这些信息适用于代理在此项目或整个工作区(如果您选择这样做)中处理的任何问题。

  • 但由于系统指令会提供给每个提示,因此请务必仅包含在理想情况下始终适用的内容。

  • 因此,架构和模块规则等内容会发挥作用。

  • 这些是智能体不可能知道的信息,尤其是在您开发闭源应用的情况下。

  • 但这些概念非常重要,有助于您在开始时就理清特征的归属。

  • 因此,您可以将界面组件等内容放入设计体系模块中,或者将代码审核中的常见错误或您经常需要输入的内容放入其中。

    # AGENTS.md
    
    - UI components belong in :core:designsystem
    
    - Never use java.util.Date;
      always use kotlinx.datetime
    
    ## General guidance
    - Avoid changing public API signatures. Anything under an `internal` directory
      is not part of the public API and may change freely.
    - The SDK code is written for Java 8.
  • 比如,在这个项目中,我们更倾向于使用 kotlinx.datetime,诸如此类。

  • 我真的很想提供一些始终适用的最佳实践,但现实情况是,这些实践会随着每个模型的发布而发生变化。

  • 不同模型在处理额外上下文时的行为有所不同。

  • 举个例子,在 Opus 4.6 时代,经常会看到用大写字母写着“千万不要这样做”。

  • 后来 Opus 5 发布时,Anthropic 发表声明称:“实际上,大写字母的效果已经没那么好了。

  • 只需使用小写字母。”

  • 这就是我的意思:您必须时刻关注。

  • 但有些原则始终适用,比如保持简短。

  • 因此,请将代码行数控制在 250 行以内。

  • 接下来这个有点争议,因为我知道很多人喜欢这样做,但今年 2 月份的一项研究表明,如果让智能体修改自己的 AGENTS.md,性能会下降约 2% 到 3%,这其实也没什么大不了的。

  • 但重要的是,成本增加了 20%。

  • 因此,我们损失了一点点性能,成本却大幅增加,这都是因为让智能体自行编写 AGENTS.md。

  • 我见过的一种解决方法是,让智能体在每个拉取请求结束时撰写回顾,然后团队在回顾会议上一起阅读这些内容,并决定要做出哪些修改。因为如果您在大型团队中与智能体合作,这个文件就会成为关键的团队基础设施。

  • 现在,我们来快速看一下我们构建的 Sideline 应用的 AGENTS.md。

  • 这里有两点需要特别说明。

  • 首先,明确定义的架构可以节省 token 和上下文长度。

  • 基本上,这可以让智能体避免不断查看更多代码库并做出越来越多的推断。

  • 它为模型提供了非常明确的准则。

  • 我想指出的第二点是,特别是对于闭源应用。

  • 显然,如果您的代码是闭源的,那么任何智能体或 LLM 都无法基于您的代码库进行训练。

  • 因此,在这些情况下,花额外的时间和精力不断清理、审核、优化和改进 AGENTS.md 尤为重要,因为从长远来看,这会让您受益。

  • 既然我们不应该把所有内容都放在 AGENTS.md 中,那该如何改变智能体或模型的行为呢?

  • 首先是钩子,钩子非常适合用于人们在 AGENTS.md 中放置的内容,例如,在编写完成后始终运行 Linter。

    // settings.json
    
    "hooks": {
      "Stop": [{
        "command": "./gradlew lintDebug"
      }]
    }
  • 这可以作为吸引点。

  • 钩子是代理公开的所有可供订阅的事件,几乎涵盖了您能想到的所有操作,但主要事件包括启动会话、停止会话、读取和写入文件。

  • 因此,您无需在 AGENTS.md 的底部写入“始终运行 Linter”或“在说您已完成之前始终运行我的测试套件”,而只需使用一个可以运行确定性脚本的停止钩子,这有助于控制 AI 的轻微随机性。

  • 还有一种情况,如果您有一些文件,您真的不希望智能体能够读取或写入,比如您有一些机密文件,您不希望这些文件被发送到服务器,或者AGENTS.md,您不希望智能体能够写入这些文件,您可以为此设置一个钩子。

  • 因此,您有一个读取或写入钩子,您会收到它尝试编辑的文件,您可以直接返回“不,您不能这样做”。

  • 这只是增加确定性的一种方式。

智能体技能和架构

  • 下一个是技能。

  • 现在,你还可以使用技能将AGENTS.md转换为钩子。

  • 那是另一回事。

  • 但技能仅在相关时才添加上下文。

  • 因此,AGENTS.md 适用于始终相关的内容。

  • 技能适用于在特定情况下(主要是文档)相关的内容。

  • 技能由三部分组成:名称、说明(这是重要部分,说明不得超过 1,024 个字符)和主体。

    ---
    
    name: android-cli
    description: >
      Loaded into context (≤1024 chars)
    ---
    # Skill Body
  • 正文可能非常庞大,甚至可以包含其他脚本,这很常见。

  • 您可以利用技能完成很多事情。

  • 我们来看一个示例。

  • 这是 Android CLI 说明。

  • 您无需阅读所有这些内容。

  • 只需知道它就像一个简短说明,描述了 Android CLI 的适用场景。

  • 然后是正文。

  • 它非常庞大,所以我们不想一直加载所有这些内容,对吧?

  • 我们只想在尝试使用 Android CLI 时加载此内容,而技能可以帮助我们实现这一点。

  • 不过,请务必谨慎选择要安装的技能。

  • 我们不想盲目安装在网上看到的那些包含数百种智能体工程技能的代码库。

  • 首先,这会带来巨大的安全风险。

  • 你根本不知道这些技能里有什么,它可能会让你的智能体做任何事情。

  • 我们确实有一套 Android 技能,我保证我们已经对它们进行了审核,它们不会这么说。

  • 其次,100 个说明乘以 1,000 个字符,就是 100,000 个字符,而这些字符是在您开始编码之前就已经添加的。

  • 所以你已经快要达到这个窗口期了。

  • 因此,对于 Android 技能,我们建议您为所有内容安装 Android CLI 基础技能,然后 Android CLI 就可以搜索可用技能并安装适合您应用的技能。

    > android init
    
    ✓ Installed base skill: android-cli
    
    # Audit & add skills only when needed:
    > android skills find compose
    > android skills add edge-to-edge
  • 或者,如果您确实有兴趣,不妨了解一下有哪些技能可用,然后手动添加适合您项目的技能,例如 Compose 技能、全屏技能,这些技能都非常通用。

  • 当然,审核技能也需要技巧。

  • Claude Code 中有 /skill-doctor,它会查看并告诉你,你添加了哪些从未激活的技能,这样你就不会浪费那 1,000 个字符的说明了。

  • 如果您不使用 Claude Code,几乎每个智能体 Harness 都有某种形式的统计信息屏幕或审核屏幕,可以执行相同的操作。

  • 再次提醒,这是 Android CLI 的链接。

  • 但它有一个技能列表命令,假设您的项目中有 Navigation 3。

    android skills list
    android skills add navigation-3
  • Navigation 3 是一个非常新的库,因此尚未进行大量训练,您可以添加 Navigation 3 技能。

  • 我们经常…哦,抱歉。

  • 下一个是 MCP。

  • 但我们经常被问到,为什么我们将 Android CLI 设为 CLI,而不是 MCP 服务器?

  • 早在 AI 出现之前,甚至在鼠标出现之前,我们就一直在构建这些 CLI,因此它们速度快、可组合,而且由于它们在您的 shell 会话中本地运行,因此实际上可以免费运行。

  • 此外,Terminal Bench 等基准测试已成为软件工程领域最重要的基准测试,因此模型开发者一直在积极提升模型在终端使用方面的能力,所以现在的模型非常擅长使用 CLI。

  • 但这并不意味着 MCP 毫无用武之地。

  • MCP 服务器非常适合您已在使用的外部服务,尤其是当这些服务已经托管了 MCP 服务时。

  • 您可以直接接入,这是一种无需安装即可为智能体提供额外上下文的方式。

  • GitHub、Figma、Slack 等工具现在都提供了 MCP 服务器。

  • 然后,我们一直在 shell 中运行的内容可以保留在 shell 中,因此通过 Android CLI 运行的 Android 命令以及 Perfetto 和 Gradle 也可以在本地运行,以便它们可以访问您在开发中使用的所有内容。

  • 我之前负责性能方面的工作。

  • 我以前总是说,Perfetto 是解决任何性能问题所需的唯一工具。

  • 但学习曲线非常陡峭,正如我们刚才在 Rahul 的演讲中所看到的那样。

  • 我们来看看 AI 如何帮助提升效果。

利用 AI 优化应用性能

  • 谢谢 Ben。

  • 因此,为了让我们的应用 Sideline 正常运行,它需要以每秒 30 帧的速度实时运行。

  • 如您所见,在这台 Pixel 10 Pro Fold 上,我们只能达到每秒 20 到 22 帧。

  • 这些丢帧会造成问题,因为这意味着应用无法达到宣传的效果,所以我们确实需要解决这个问题。

  • Android CLI 提供了 Android 性能分析器命令。

  • 当我们将此工具添加到编码智能体中,并指示它满足每秒帧数 30 的要求时,发生了两件有趣的事情。

  • 第一种是使用 Android 性能分析器命令找到修复方法。

  • 它在连接的 Pixel 10 Pro Fold 设备上记录了系统跟踪记录,并发现其 AI 线程在设备上最慢的核心上运行。

  • 第二点是,它使用了 Android 文档搜索,有趣的是,我们并没有明确要求它这样做,但它却拉取了 Performance Hint API 的官方指南。

  • 智能体学会了优化系统调度,从而能够满足每秒帧数的要求。

  • 因此,本质上,修复措施是按照指南进行的。

  • 因此,Android CLI 的关键在于,通过将其与智能体连接,它可以帮助您找到合适的工具,即使您不熟悉该工具,也能完成您需要完成的任何工作。

  • 运行后,您可以看到 Sideline 达到了用户要求的每秒帧数,并且现在可以在 Pixel 10 Pro Fold 上运行。

实现任务验证循环

  • 好了

  • 现在,我们将通过循环将所有这些内容整合在一起。

  • 相信大家都有过这样的经历:你让智能体实施某项重大更改,它很快就回复说已经完成。

  • 如果您在安装应用后,手动点击应用并记录 bug,这种做法正是我们需要避免的。

  • 我们需要停止充当智能体的质量保证测试人员,并预先定义我们认为的“完成”标准。

  • 下面是一个示例。

  • 我们希望将整个项目迁移到 Nav3,然后智能体开始工作,这需要一些时间,但它最终会自信地返回并说:“迁移完成。

  • 我最棒。”

  • 但随后,您旋转手机,应用崩溃,错过了所有幻灯片过渡,也没有清理其 Gradle 文件。

  • 这有点像我们现在所处的世界。

  • 理想情况下,我们不希望这样做,但这是目前的实际情况。

  • 因此,我们应该事先明确定义所有预期,这样代理就能不断循环,直到满足所有条件。

  • 这就是验证循环。

  • 我们有非常有力的数据可以证明这种做法的有效性。

  • 这就是 Android Bench 2.0,它是我们在演讲开始时提到的 AI 基准测试的新版本。

  • 目前通过率约为 40%。

  • 这些任务非常艰巨,规模庞大且贴近实际,其中一项任务就是从 Nav2 迁移到 Nav3,这正是您目前在项目中正在做的事情。

  • 以 Fable 5.1 为例,其通过率为 22%,这是仅使用自然提示(例如“将 Nav2 迁移到 Nav3”)时获得的结果。

  • 但如果我们提前给它一个失败的测试套件,这并不是给它答案,我们没有告诉它如何迁移到 Nav3,我们只是给它一个已经失败的测试套件,当所有这些事情都完成后,它就会通过,它在整个基准测试中的通过率跃升至 90%。

  • 这表明,这些模型现在已经能够执行我们能想到的几乎所有 Android 任务,只是它们并不总是知道“完成”意味着什么。

  • 因此,您无需提前编写完整的失败测试套件。

  • 验证循环可以像添加提示一样简单。

  • 假设您正在处理界面,可以让它渲染 Compose 预览,确保其与 Figma 规范一致,并向您展示结果。

  • 如果你要求它展示结果并证明已完成,而不是仅仅接受“我已完成”的文本回复,它似乎真的能做到。

  • 如果您正在处理业务逻辑,可以让它运行单元测试;或者,正如我们在开始时看到的那样,如果您正在修复崩溃问题,可以让它通过远程测试实验室在发生崩溃的真实设备上验证崩溃是否已修复。

  • Claude Code 实际上内置了一项技能,可帮助您构建验证循环。

  • 因此,请务必查看该指南。

  • 如果您在 Android Studio 中使用自带智能体,Android Studio 会提供一系列工具,您可以根据正在处理的任务构建循环。

  • 因此,就像 linter 一样,您可以让它在所有 lint 错误都修复之前不要停止,或者我非常喜欢的一个功能是历程,您可以让它运行您的历程并确保它们仍然正常运行。

  • 或者,如果您编写了历程(历程非常容易编写,它们只是关于您正在处理的功能的提示),您可以让它运行该历程,并确保在它声明自己完成之前通过该历程。

  • 但历程确实需要一段时间才能运行。

  • 因此,您还可以对验证循环进行分层。

  • 因此,我们可以要求它首先确保单元测试和 Compose 预览均能正确呈现。

  • 然后,当这些测试通过后,请运行我们的连接测试和 Android Journeys,只有当这些测试通过后,再运行完整的远程设备测试实验室、完整的测试套件,这些测试可能需要几个小时。

  • 如果您提供了这些额外信息,我们会发现它会按层级循环,而不是在每次运行时尝试执行每个步骤。

  • 因为模型通常非常自信。

  • 因此,他们总是认为自己的代码已经完善,并且总是认为自己的代码会一次性通过所有测试。

  • 我们来看看 Sideline 中的情况。

Android XR 和自主 bug 修复

  • 现在,我们将这一理念应用到 Sideline 应用中,具体做法是添加一项新功能,专门针对即将推出的 XR 眼镜。

  • 由于我们还没有硬件,因此我们将使用 XR 模拟器,并指示编码智能体针对新设备规格扩展 Sideline。

  • 为此,我们将明确要求智能体按顺序循环执行 JVM 测试、Compose 预览测试和模拟器测试。

  • 每个循环都基于前一个循环进行构建。

  • 这样做时,我们首先注意到,在循环 1 和循环 2 之间,JVM 测试用于定义 6 个 Compose 预览状态。

  • 当然,由于没有调用模拟器,因此运行速度非常快。

  • 同样,在循环 2 和循环 3 之间,甚至在模拟器运行之前,系统就会发现并修复长字符串等问题。

  • 最后,模拟器循环运行后,会发现 JVM 测试和 Compose 预览无法修复的其他 bug。

  • 但从本质上讲,每次循环都会进一步强化应用,因此我们希望先运行速度最快但功能最弱的循环,然后再运行速度最慢但功能最强的循环。

  • 结果如下。

  • 视频中,眼镜显示了挥拍类型和球离开球拍时的速度,这样您就可以在打网球时实时获得有关比赛表现的反馈,而无需将视线从球上移开。

  • 对了,我之前提到过,我们会回过头来处理之前出现的两个 Crashlytics 问题。

  • 既然我们已经验证了这种方法行之有效,就可以使用 Claude Code 中的 /schedule 命令来循环执行该方法,并且可以设置任何想要的节奏,这样我们就拥有了一个自我修复应用,它可以修复所有 bug 并验证它们是否已修复,然后将它们作为拉取请求发送给我们的工程师,供其查看和合并。

要点总结和资源

  • 很好

  • 今天的内容就到这里。

  • 如果说有一个关键要点,那就是开始思考这样一个世界:我们正在为智能体构建一个成功的环境,并像对待当今的软件开发和 bug 一样对待它。

  • 这就是我们实现并行智能体的方式。

  • 您会在网上找到很多关于此主题的建议,其中许多建议会相互冲突。

  • 这就是这个快速变化的环境的现实。

  • 因此,最好的做法是为自己的项目编写专属评估。

  • 当有新的建议或新的模型出现时,您可以实际衡量并了解它是否对您有帮助。

  • 当然,每种技能都有其用武之地。

  • Claude Code 中有一项技能可以帮助您构建评估。

    /claude-api build-eval
  • 强烈建议您去看看。

  • 今天我介绍了 Android Bench。

  • Android Bench 是我们的评估工具。

  • 这是我们衡量情况是否有所改善的方式。

  • 如果您想了解我们在构建该工具时学到的经验教训,以免犯同样的错误,请观看 Android Bench 演讲。

  • 还有两个面板。

  • 一个在美国,一个在伦敦。

  • 这两个视频都将发布到网上,讨论这种概念在社区中的实际应用。

  • 因此,我们邀请了 Android 开发者社区的成员加入讨论,分享他们如何在工作中践行这些理念。

  • 此外,我们非常期待收到您的反馈。

  • 我们非常想了解我们打造的产品是否真的对您有帮助。

  • 因此,请填写调查问卷。

  • 我会把这些内容留在屏幕上。

  • 没错。

  • 感谢观看本教程。

  • 谢谢。

代码

代码段

“演示:使用 Android CLI 修复 ANR”中 07:18 处的 C++ 代码段
setenv("KMP_AFFINITY", "disabled", 1);
setenv("KMP_INIT_AT_FORK", "false", 1);
“管理上下文和 token 限制”中 09:22 处的 JSON 代码段
[
  {
    "role": "system",
    "content": "You are an expert Android engineering agent..."
  },
  {
    "role": "workspace_context",
    "content": { "project_root": "/workspace/android-app", "build_system": "Gradle (Kotlin DSL)", "target_sdk": 35 }
  },
  {
    "role": "available_tools",
    "content": [ { "name": "read_file" }, { "name": "edit_file" }, { "name": "bash" }, { "name": "skill_android_cli" } ]
  },
  {
    "role": "user",
    "content": "ProfileViewModelTest is failing when loading errors. Fix the ViewModel and verify with unit tests."
  },
  {
    "role": "assistant",
    "tool_calls": [ { "name": "read_file", "arguments": { "path": "app/src/main/.../ProfileViewModel.kt" } } ]
  },
  {
    "role": "tool",
    "content": "class ProfileViewModel(...) : ViewModel() { ... // full file contents + Gradle output appended here }"
  }
]
“管理上下文和词元限制”中 10:16 处的 Shell 代码段
./gradlew assembleDebug --quiet
“Best practices for AGENTS.md”中 12:34 处的 Markdown 代码段
# AGENTS.md

- UI components belong in :core:designsystem

- Never use java.util.Date;
  always use kotlinx.datetime

## General guidance
- Avoid changing public API signatures. Anything under an `internal` directory
  is not part of the public API and may change freely.
- The SDK code is written for Java 8.
“Best practices for AGENTS.md”中 15:24 处的 JSON 代码段
// settings.json

"hooks": {
  "Stop": [{
    "command": "./gradlew lintDebug"
  }]
}
“智能体技能和架构”视频中 16:44 处的 Markdown 代码段
---

name: android-cli
description: >
  Loaded into context (≤1024 chars)
---
# Skill Body
“智能体技能和架构”中 17:52 处的 Shell 代码段
> android init

✓ Installed base skill: android-cli

# Audit & add skills only when needed:
> android skills find compose
> android skills add edge-to-edge
“智能体技能和架构”中 18:38 处的 Shell 代码段
android skills list
android skills add navigation-3
“重要内容和资源”中 29:32 处的文字片段
/claude-api build-eval