概览
使用 Codex 和 Build macOS Apps plugin,在窗口、侧边栏、命令或同步流程周围添加少量高信号的 `Logger` 事件,然后运行应用,并通过 Console 或 `log stream` 证明正确的操作已被触发。
适合场景
- Mac 应用功能:当 Codex 需要可靠地追踪窗口打开、侧边栏选择、菜单命令、菜单栏操作、同步里程碑或回退路径时
- 智能体调试循环:Codex 应根据证据修改代码、重新运行应用、检查日志,并决定下一步修复,而不是靠猜测
- 本地应用会话采集循环:当你希望获得一段紧凑的用户操作和应用生命周期事件序列,以便在多次重复运行之间进行比较时
为一个功能添加埋点并通过日志验证
使用 Build macOS Apps plugin 在[写出一个 Mac 功能或操作流程名称]周围添加轻量级统一日志,然后运行应用,并从日志中验证这些事件是否按预期顺序触发。 约束: - 优先使用来自 `OSLog` 的 `Logger`,不要用 `print`,并为该功能创建清晰的 subsystem/category 组合,以便轻松过滤日志。 - 为每个重要的动作边界或状态转换记录一行简洁日志:例如窗口已打开、侧边栏选择已更改、菜单命令已调用、同步已开始、同步已完成,或已进入回退路径。 - 将长期保留的 `info` 日志保持稳定且高信号。仅将 `debug` 用于噪声较大的本地细节,并在完成前移除或降级临时埋点。 - 不要记录密钥、auth token、个人数据或原始文档内容。如果必须记录某个标识符,请选择最安全的隐私注解并解释原因。 - 构建并运行应用,亲自操作该功能路径,并使用 Console 或聚焦的 `log stream` predicate 验证这些事件。 - 如果流程较长、间歇性出现,或更适合手动复现,请将过滤后的日志流保存为一个小型本地会话追踪文件;必要时让我手动操作应用;然后再读回该文件并总结事件时间线。 - 如果预期事件没有出现,就将日志移动到更接近可疑控制路径的位置,重新运行流程,并持续迭代,直到日志能够解释发生了什么。 交付内容: - 新的 logger 配置,以及你添加的确切事件 - 你使用的 Console 过滤条件或 `log stream` predicate - 一段简短的前后对比总结,说明现在日志能够观察到什么 - 如果这变成了更长时间的采集会话,则提供保存的追踪文件和时间线摘要 - 一两条具有代表性的日志行,用来证明该流程已被正确埋点
在调试变得模糊的地方添加一个 Logger
这个用例适用于 Mac 应用流程:当“发生了什么”过于模糊、仅靠代码审查无法调试时。让 Codex 围绕某个行为添加少量高信号统一日志,运行应用,触发该行为,并通过 Console 或 log stream 验证预期事件是否已触发。
可使用 Build macOS Apps 插件 完成这个循环。它的 macOS 遥测技能刻意保持轻量:使用 Apple 的 Logger,选择清晰的 subsystem/category 组合,记录动作边界和状态转换,避免敏感负载,并在本地构建/运行后验证事件,而不是想当然地认为埋点已正确接通。
为什么遥测对智能体工程很有用
好的日志能在每次补丁之后为 Codex 提供可重复的反馈循环。智能体不必要求你手动检查每个窗口、菜单操作或同步转换,而是可以运行应用、操作流程、检查过滤后的日志,并基于证据决定下一次代码修改。
这对于三类智能体循环尤其有用:
- 免手动调试循环: Codex 为可疑流程添加埋点,启动应用,点击侧边栏或触发命令,读取发出的日志序列,修补状态更新路径,并重复运行同一流程,直到日志与 UI 行为一致。
- 应用会话采集循环: Codex 为应用启动、窗口打开、侧边栏选择、导入开始、导入完成和导入失败各添加一个事件,然后运行一次本地会话并总结得到的时间线,从而让缺失或乱序的状态转换变得一目了然。
- 人工驱动采集循环: Codex 在启用日志的情况下启动应用,在你手动操作一个棘手流程时持续保持聚焦的日志流运行,然后在会话结束后检查捕获结果,并基于该追踪提出下一次补丁建议。
保持埋点精简且可过滤
让 Codex 按功能区域设置 logger,而不是为每一次状态变更都永久添加一条日志。像 Windowing、Commands、MenuBar、Sidebar、Sync 或 Import 这样的功能分类,会让下一轮调试时的日志过滤容易得多。
import OSLog
private let logger = Logger(
subsystem: Bundle.main.bundleIdentifier ?? "SampleApp",
category: "Sidebar"
)
@MainActor
func selectItem(_ item: SidebarItem) {
logger.info("Selected sidebar item: \(item.id, privacy: .public)")
selection = item.id
}对应该长期有用的简洁动作和生命周期事件使用 info,对噪声更大的本地状态细节使用 debug,这些细节可以在任务完成前移除或降级。只有在需要测量时间跨度时才添加 signpost,不要默认添加。
让 Codex 从日志中证明事件已发生
有价值的不只是添加 Logger 调用。让 Codex 运行应用、触发已埋点的流程,并提供它使用的确切 Console 过滤条件或 log stream predicate,以及一两条具有代表性的日志行。
log stream --style compact --predicate 'subsystem == "com.example.app" && category == "Sidebar"'
如果预期事件没有出现,就让 Codex 把日志移动到更接近可疑控制路径的位置,重新运行同一流程,并持续迭代,直到日志能够解释发生了什么。如果任务演变成崩溃或回溯分析,则切换到该 plugin 的构建/运行调试工作流,同时让遥测继续聚焦于动作边界。
保存会话追踪,供后续 Codex 轮次使用
对于更长或间歇性出现的 bug,让 Codex 将聚焦的日志流保存为一个小型本地追踪文件,总结时间线,并将该产物保留在工作区中。这样,后续的 Codex 运行就可以检查同样的证据,而不必凭记忆重放整个会话。当你希望一次智能体运行负责采集追踪、另一次运行负责比较补丁前后行为时,这会让多轮调试更加容易。
当人类需要参与驱动部分会话时,这种方式也很有效。让 Codex 在适合记录日志的调试循环中启动应用,开始一次过滤后的采集,在你手动复现问题时等待,然后在你完成后读取保存的追踪文件。
实用建议
一次只为一个功能添加埋点
先从一个侧边栏、窗口、命令或同步路径开始,这样日志序列会更容易检查。如果该路径变得可靠,Codex 就可以把同样的模式扩展到相邻流程。
将隐私要求写进提示词
要求 Codex 解释每一个被记录的标识符,并避免将密钥、个人数据或原始内容写入统一日志。对于本地调试来说,一套很小的事件词汇通常就足够了。
在最终总结中保留示例输出
与“已添加遥测”相比,具有代表性的日志行更容易让人信任这项改动。让 Codex 包含过滤 predicate 和一段简短的操作时间线,以便下一次智能体运行复用同样的验证循环。
