主题
调试工具与技巧
本文引用的源码文件
本文引用的文件
- src/background/tools/debugger-tools.js
- src/background/tool-debugger.js
- src/background/debugger/debugger-session.js
- src/shared/logger.js
- agent/src/logger.js
- src/background/token-recorder.js
- src/storage/token-store.js
- src/side_panel/token-stats-panel.js
- src/side_panel/utils.js
- src/side_panel/panel-context.js
- test/unit/debugger-executor.unit.test.js
目录
- 引言
- 项目结构与调试边界
- 核心调试能力总览
- Chrome DevTools 面板使用指南
- 扩展专用调试工具
- 日志系统配置与使用
- 性能监控与 Token 统计
- 网络抓包与 API 调试技巧
- 常见调试场景与问题定位
- 依赖关系分析
- 故障排查清单
- 结论
引言
本指南面向 AI Helper 的开发者、测试人员与高级用户,聚焦以下目标:
- 在 Chrome 扩展端(Manifest V3)与独立 Agent 端之间建立可复现、可观测的调试路径。
- 说明如何正确使用内置
debug_page工具完成页面级调试、网络抓包、截图与环境模拟。 - 说明扩展端与 Agent 端的日志体系、Token 统计面板、执行时间追踪思路。
- 提供 WebSocket、HTTP、响应体分析与错误过滤的实操方法。
- 给出 background 页面、content script、side panel 三类典型调试场景的操作步骤与排错建议。
本项目为双进程架构:扩展端位于 src/,Agent 端入口为 agent/src/server.js;两端版本号保持同步,当前文档以 2.3.1 为准。Agent 源码修改后必须重启进程,新接口才生效。
项目结构与调试边界
AI Helper 的调试边界由三层组成:
- Side Panel 层:对话界面、执行日志、Token 统计、工作区等 UI。
- Background Service Worker 层:消息路由、ReAct 执行循环、工具调度、本地 Agent 通信、调试会话管理。
- Agent 本地服务层:文件读写、命令执行、长期记忆、RAG、MCP 工具注册。
graph TB SP["Side Panel<br/>侧边栏界面"] --> BG["Background Service Worker<br/>扩展核心逻辑"] BG --> AGENT["本地 Agent 服务<br/>Node.js 进程"] BG --> CDP["Chrome DevTools Protocol<br/>页面调试会话"] BG --> IDB["IndexedDB<br/>Token 统计存储"] AGENT --> LOGS["Agent 审计日志<br/>JSON Lines 文件"] BG --> CONSOLE["浏览器控制台<br/>扩展日志输出"]
图表来源
- src/side_panel/token-stats-panel.js#L1-L50
- src/background/debugger/debugger-session.js#L1-L20
- src/storage/token-store.js#L1-L12
- agent/src/logger.js#L1-L12
章节来源
- src/background/debugger/debugger-session.js#L1-L20
- src/side_panel/token-stats-panel.js#L1-L50
- agent/src/logger.js#L1-L12
核心调试能力总览
| 能力 | 位置 | 用途 | 关键约束 |
|---|---|---|---|
| 页面调试 | src/background/tools/debugger-tools.js、src/background/tool-debugger.js、src/background/debugger/debugger-session.js | attach/detach、evaluate、原生输入、截图、环境模拟 | 受限页面不可调试;需先 attach 再 detach;空闲自动脱离 |
| 网络录制 | src/background/debugger/debugger-session.js | 被动记录请求、响应头、响应体 | 单条响应体最多 20KB;最多缓存 100 条;二进制资源跳过 body 拉取 |
| Token 统计 | src/background/token-recorder.js、src/storage/token-store.js、src/side_panel/token-stats-panel.js | 记录 prompt/completion/total token、上下文使用率、按模型与调用类型分布 | 部分模型不返回 total_tokens,用 prompt+completion 兜底 |
| 扩展端日志 | src/shared/logger.js | DEBUG/INFO/WARN/ERROR 控制台输出 | 统一前缀 [AIH],可通过级别控制 |
| Agent 端日志 | agent/src/logger.js | JSON Lines 审计日志、按日轮转、查询接口 | 支持 category、action、locale、stderr 输出 |
| Side Panel 可见性 | src/side_panel/panel-context.js | 窗口 id、作用域、宿主 tab 快照 | 用于通知与跨通道 IPC 竞态下的可见性判断 |
章节来源
- src/background/tools/debugger-tools.js#L1-L103
- src/background/tool-debugger.js#L1-L130
- src/background/debugger/debugger-session.js#L1-L40
- src/background/token-recorder.js#L1-L36
- src/storage/token-store.js#L1-L45
- src/side_panel/token-stats-panel.js#L1-L50
- src/shared/logger.js#L1-L51
- agent/src/logger.js#L1-L20
- src/side_panel/panel-context.js#L1-L18
Chrome DevTools 面板使用指南
Console 面板调试
- 打开扩展后台页面:在
chrome://extensions中找到 AI Helper,点击“Service Worker”或“Inspect views”。 - 查看扩展端日志:搜索
[AIH],这是扩展端 logger 的统一前缀。 - 查看 Agent 端日志:启动 Agent 后,在终端中观察 stderr 输出的带时间戳、级别、分类标签的行。
- 过滤技巧:
- 仅看错误:
console.error或筛选[AIH] ERROR。 - 仅看调试信息:筛选
[AIH] DEBUG。 - Agent 日志可按分类筛选,例如
exec:、security:、auth:。
- 仅看错误:
章节来源
Network 面板抓包
- 常规抓包:在 DevTools Network 面板勾选 Preserve log,刷新页面或触发操作,观察 XHR/Fetch/WebSocket。
- 扩展内网访问限制:扩展自身发起的 fetch 不受 Chrome PNA 预检完全约束,因此内网拦截逻辑落在扩展侧;若发现请求未发出,应检查网络范围配置与安全判定。
- WebSocket:关注 Upgrade 请求与后续 WS 帧;若流式输出异常,优先确认连接是否建立、是否被安全策略拒绝。
章节来源
Performance 面板分析
- 关注长任务:ReAct 推理循环、工具执行、截图生成、Markdown 渲染可能产生主线程阻塞。
- 关注内存峰值:大量 executionLog、DOM 属性膨胀、全量 DOM 扫描都可能造成增长。
- 结合 Token 统计:若某次调用 token 激增但无对应 UI 反馈,检查 executionLog 是否被截断或 API_COMPLETE 消息是否到达 side panel。
[本节为通用性能分析方法,不直接分析具体代码文件]
Memory 面板检测
- 重点观察:
- IndexedDB 中 token 记录数量增长。
- side panel 中 executionLog 与 HTML 内容是否被存入 DOM dataset。
- 长时间使用后是否存在未释放的 debugger session。
- 清理建议:
- 清空 Token 统计:通过侧边栏 Token 统计面板的清空按钮。
- 关闭调试会话:确保 debug_page 最终调用 detach。
- 重启 Agent:修改 Agent 源码后必须重启进程。
章节来源
扩展专用调试工具
Background 页面调试
Background 是 MV3 Service Worker,存在生命周期硬约束:
- 空闲会被终止,需要保活机制。
- debugger-session 使用
chrome.alarms在有活动会话时创建短周期 alarm,降低 SW 休眠导致会话丢失的概率。 - 若出现“会话不存在”“已脱离”类错误,优先检查是否触发了空闲自动脱离、用户取消调试、DevTools 抢占或标签页关闭。
章节来源
- src/background/debugger/debugger-session.js#L101-L111
- src/background/debugger/debugger-session.js#L183-L196
Content Script 注入检测
Content script 适合普通点击、输入、滚动和内容提取;当遇到以下情况时,应切换到 debug_page:
- 原生事件(canvas、file input、忽略合成事件的控件)。
- 需要捕获 XHR/fetch 的请求体和响应体。
- 需要在页面最早时机执行 JS。
- 需要整页截图或设备/UA 模拟。
章节来源
Side Panel 界面调试
Side Panel 与 background 的消息传递是常见故障点:
- 通知可见性判断依赖 panel-context 中的窗口 id、作用域、宿主 tab 快照。
- 若任务完成后通知行为异常,检查 side panel 是否可见、是否切换了 tab、background 是否冷启动。
- Token 统计面板通过 IndexedDB 读取数据并渲染趋势图、分布图和全局统计。
章节来源
debug_page 工具流程
debug_page 是扩展提供的强调试工具,其标准流程如下:
sequenceDiagram participant User as "用户" participant Tool as "debug_page 工具" participant Session as "DebuggerSession" participant Tab as "目标标签页" User->>Tool : action=attach Tool->>Session : attach(tabId) Session->>Tab : chrome.debugger.attach Session-->>Tool : 附着成功 Tool-->>User : 提示调试会话已开启 User->>Tool : evaluate / input / network / screenshot / emulate Tool->>Session : cdp(...) Session->>Tab : CDP 命令 Tab-->>Session : 结果 Session-->>Tool : 返回结果 Tool-->>User : 工具结果 User->>Tool : action=detach Tool->>Session : detach(tabId) Session->>Tab : 清除模拟覆盖并断开 Session-->>Tool : 脱离完成 Tool-->>User : 提示调试会话已关闭
图表来源
- src/background/tool-debugger.js#L531-L569
- src/background/debugger/debugger-session.js#L221-L296
- src/background/debugger/debugger-session.js#L301-L332
章节来源
- src/background/tool-debugger.js#L132-L147
- src/background/tool-debugger.js#L193-L233
- src/background/debugger/debugger-session.js#L221-L296
日志系统配置与使用
扩展端日志
扩展端 logger 提供四个级别:DEBUG、INFO、WARN、ERROR。默认级别为 DEBUG,所有级别都会输出到控制台,并以 [AIH] 作为统一前缀。
- 设置日志级别:通过
setLogLevel调整当前级别。 - 获取日志级别:通过
getLogLevel查询。 - 输出方法:
debug、info、warn、error。 - 使用建议:
- 日常开发保留 DEBUG。
- 生产或性能敏感场景可提升到 INFO 或 WARN。
- 错误路径必须使用 error,便于在 Console 中快速定位。
章节来源
Agent 端日志
Agent 端日志模块采用 JSON Lines 格式,写入用户目录下的 .ai-helper-agent/logs,并按日轮转,保留最近 30 个日志文件,单个文件超过 10MB 会被清理。
- 分类标签:auth、fs、exec、security、system。
- 级别标签:info、warn、error。
- 输出方式:
- 前台模式可输出到 stderr。
- 始终追加写入当日日志文件。
- 查询接口:支持按日期、分类、偏移和限制查询日志条目。
- 本地化:类别标签支持 zh/en。
章节来源
- agent/src/logger.js#L1-L12
- agent/src/logger.js#L23-L49
- agent/src/logger.js#L72-L123
- agent/src/logger.js#L132-L172
- agent/src/logger.js#L174-L230
错误信息过滤
- 扩展端:在 Console 中筛选
[AIH] ERROR。 - Agent 端:在终端中筛选
ERROR或按分类筛选security:、auth:。 - 日志文件:使用 Agent 提供的日志查询接口,或按文件名
agent-YYYY-MM-DD.log手动查看。
章节来源
性能监控与 Token 统计
Token 使用统计采集
Token 统计在 API 调用完成后由 background 触发记录:
- 记录字段包括 sessionId、model、promptTokens、completionTokens、totalTokens、contextWindow、callType。
- 若模型未返回 total_tokens,则用 promptTokens + completionTokens 兜底。
- 记录失败不会中断主流程,仅记录 warn。
章节来源
Token 存储与聚合
Token 明细存储在 IndexedDB 的 tokenStats 表中,并提供多种聚合查询:
- 会话维度:当前会话的总 token、调用次数、上下文使用率区间、最近 20 条记录。
- 全局维度:总会话数、总调用次数、总 token。
- 时间维度:最近 N 天每日聚合。
- 分布维度:按模型、按 callType 聚合。
章节来源
- src/storage/token-store.js#L47-L98
- src/storage/token-store.js#L104-L137
- src/storage/token-store.js#L194-L225
- src/storage/token-store.js#L283-L345
Token 统计面板
侧边栏 Token 统计面板提供三个 Tab:
- 趋势:最近 20 次调用的 sparkline、上下文使用率区间条、Prompt/Completion 总量。
- 分布:Prompt/Completion 堆叠条、按模型分布、按调用类型分布。
- 全局:最近 30 天趋势 sparkline、总 token、总会话、总 API 调用。
flowchart TD
Start["打开 Token 统计面板"] --> Load["加载会话统计与全局统计"]
Load --> HasData{"是否有数据"}
HasData --> |否| Empty["显示暂无数据"]
HasData --> |是| RenderTop["渲染顶部卡片"]
RenderTop --> RenderTabs["渲染趋势/分布/全局 Tab"]
RenderTabs --> Sparkline["渲染 sparkline 与条形图"]
Sparkline --> End["用户交互刷新或清空"]
图表来源
- src/side_panel/token-stats-panel.js#L102-L144
- src/side_panel/token-stats-panel.js#L204-L250
- src/side_panel/token-stats-panel.js#L309-L338
- src/side_panel/token-stats-panel.js#L468-L526
章节来源
- src/side_panel/token-stats-panel.js#L1-L50
- src/side_panel/token-stats-panel.js#L204-L250
- src/side_panel/token-stats-panel.js#L383-L419
- src/side_panel/token-stats-panel.js#L468-L526
执行时间与资源消耗分析
- 执行时间追踪:可在 ReAct 执行循环、工具执行器、API 调用前后添加计时逻辑,并结合 logger 输出耗时。
- 资源消耗分析:
- 关注 executionLog 大小,避免超过
chrome.runtime.sendMessage的 64MiB 限制。 - 关注截图尺寸与纹理上限,超长页面会被截断。
- 关注网络录制缓冲区,最多 100 条,单条响应体最多 20KB。
- 关注 executionLog 大小,避免超过
章节来源
- src/background/index.js#L1476-L1500
- src/background/tool-debugger.js#L117-L121
- src/background/debugger/debugger-session.js#L18-L22
网络抓包与 API 调试技巧
使用 debug_page 进行网络录制
debug_page 的 network 动作支持三种模式:
- start:开始录制,可选 filterUrl 过滤 URL。
- collect:取回并清空缓冲的新请求。
- stop:停止录制并返回剩余请求。
flowchart TD
A["调用 action=network, networkMode=start"] --> B["启用 Network.enable 并监听事件"]
B --> C{"是否匹配 filterUrl"}
C --> |否| D["丢弃该请求"]
C --> |是| E["记录请求头、postData、resourceType"]
E --> F["Network.responseReceived 填充状态码、mimeType、响应头"]
F --> G["Network.loadingFinished 尝试拉取响应体"]
G --> H{"是否可拉取且非二进制资源"}
H --> |是| I["解码 base64 或文本,截断至 20KB"]
H --> |否| J["跳过响应体"]
I --> K["collect/stop 返回序列化后的请求列表"]
J --> K
图表来源
- src/background/debugger/debugger-session.js#L113-L180
- src/background/debugger/debugger-session.js#L374-L406
- src/background/tool-debugger.js#L358-L387
章节来源
- src/background/tools/debugger-tools.js#L69-L75
- src/background/tool-debugger.js#L358-L387
- src/background/debugger/debugger-session.js#L113-L180
- test/unit/debugger-executor.unit.test.js#L530-L629
WebSocket 通信监控
- 在 DevTools Network 面板中筛选 WebSocket。
- 若连接失败,检查:
- 扩展网络访问开关是否允许目标主机。
- 是否为 http/https 协议。
- 是否命中内网白名单规则。
- 若连接成功但消息异常,结合 Agent 端日志与 side panel 执行日志定位。
章节来源
HTTP 请求拦截与响应数据分析
- 使用 debug_page 的 network 录制捕获请求与响应体。
- 注意:
- 二进制资源(图片、字体、媒体)不会拉取响应体。
- 响应体可能被截断。
- 多次 collect 具有 drain 语义,第二次 collect 通常为空。
- 对 JSON 响应可直接粘贴到 JSON 查看器;对 Base64 响应注意解码失败分支。
章节来源
- src/background/debugger/debugger-session.js#L159-L179
- src/background/tool-debugger.js#L370-L378
- test/unit/debugger-executor.unit.test.js#L609-L629
常见调试场景与问题定位
场景一:无法 attach 调试器
现象:调用 debug_page attach 失败,或提示受限页面。
原因:
- 目标是 chrome://、扩展商店、PDF 阅读器等受限页面。
- Service Worker 重启后出现“孤儿附着”,需要先强制 detach 再重试。
- 用户手动取消调试或 DevTools 抢占。
处理步骤:
- 确认目标标签页是普通网页。
- 若报错包含“already attached”,让工具自动执行 detach + retry。
- 若仍失败,手动关闭目标标签页后重新 attach。
章节来源
场景二:evaluate 返回空或异常
现象:evaluate 返回“无返回值”或抛出异常。
原因:
- 表达式无 return。
- 页面脚本抛错。
- 调试会话已脱离。
处理步骤:
- 检查 expression 是否有效。
- 查看异常详情。
- 若提示会话不存在,先重新 attach。
章节来源
场景三:input 点击无效
现象:click 没有触发目标元素。
原因:
- selector 未找到元素。
- 元素存在但不可见(尺寸为 0)。
- 元素在视口外且未 scrollIntoView。
- 目标在 shadow root 中但未穿透。
处理步骤:
- 先用 evaluate 验证 selector 是否能找到元素。
- 检查元素是否可见。
- 使用工具内部深查询逻辑,确保兼容 Web Components。
章节来源
场景四:网络录制为空
现象:collect 返回“没有新的网络请求”。
原因:
- 未先调用 start。
- 页面未发生相关网络请求。
- filterUrl 过滤掉了目标请求。
- 已 collect 过一次,缓冲区已被清空。
处理步骤:
- 先调用 start。
- 触发页面操作。
- 再次 collect。
- 如需清空重录,先 stop 再 start。
章节来源
场景五:Token 统计无数据
现象:Token 统计面板显示暂无数据。
原因:
- 尚未发生 API 调用。
- API 调用未返回 usage。
- recordTokenUsage 静默失败。
处理步骤:
- 检查 side panel 是否收到 API_COMPLETE。
- 检查 console 中是否有 TokenRecorder warn。
- 检查 IndexedDB 中 tokenStats 表是否有记录。
章节来源
场景六:Side Panel 通知误判可见性
现象:任务完成后通知未弹出或重复弹出。
原因:
- background 冷启动期间 panel-context 快照不一致。
- side panel 作用域或宿主 tab 发生变化。
- port 断开与 onDisconnect 存在跨通道 IPC 竞态。
处理步骤:
- 检查 side panel 是否处于可见状态。
- 检查当前作用域是全局还是 tab 绑定。
- 检查 panel-context 是否正确上报窗口 id、作用域、宿主 tab。
章节来源
依赖关系分析
classDiagram
class DebuggerTools {
+DEBUGGER_TOOLS
+executeDebugPage(args, toolCallId)
}
class DebuggerSession {
+attach(tabId)
+detach(tabId, reason)
+cdp(tabId, method, params)
+startNetworkCapture(tabId, filter)
+collectNetwork(tabId)
+stopNetworkCapture(tabId)
}
class ToolDebugger {
+handleAttach()
+handleDetach()
+handleEvaluate()
+handleInput()
+handleNetwork()
+handleScreenshot()
+handleEmulate()
}
class TokenRecorder {
+recordTokenUsage(params)
}
class TokenStore {
+recordTokenCall(record)
+getSessionTokenSummary(sessionId)
+getOverallTokenSummary()
+getDailyTokenSummary(days)
+getTokenSummaryByModel()
+getTokenSummaryByCallType()
}
class TokenStatsPanel {
+initTokenStatsPanel(getActiveSessionId, showCustomConfirm)
}
DebuggerTools --> ToolDebugger : "定义工具参数"
ToolDebugger --> DebuggerSession : "调用 CDP 与会话管理"
TokenRecorder --> TokenStore : "持久化 token 记录"
TokenStatsPanel --> TokenStore : "读取统计与分布"
图表来源
- src/background/tools/debugger-tools.js#L8-L103
- src/background/tool-debugger.js#L531-L569
- src/background/debugger/debugger-session.js#L221-L406
- src/background/token-recorder.js#L16-L36
- src/storage/token-store.js#L24-L345
- src/side_panel/token-stats-panel.js#L102-L598
章节来源
- src/background/tools/debugger-tools.js#L8-L103
- src/background/tool-debugger.js#L531-L569
- src/background/debugger/debugger-session.js#L221-L406
- src/background/token-recorder.js#L16-L36
- src/storage/token-store.js#L24-L345
- src/side_panel/token-stats-panel.js#L102-L598
故障排查清单
| 问题 | 检查项 | 处理方式 |
|---|---|---|
| attach 失败 | 是否受限页面、是否已有附着、是否 Service Worker 重启 | 切换到普通网页;等待自动修复或手动关闭标签页 |
| evaluate 异常 | 表达式是否合法、是否返回 Promise、是否已 detach | 修正表达式;重新 attach |
| input 无效 | selector 是否存在、元素是否可见、是否在 shadow root | 先用 evaluate 验证;使用工具内部深查询 |
| network 录制为空 | 是否 start、是否触发请求、filterUrl 是否匹配 | 先 start,触发操作,再 collect |
| Token 统计为空 | 是否调用 API、usage 是否返回、recordTokenUsage 是否失败 | 检查 console warn 与 IndexedDB |
| 通知异常 | panel-context 快照、作用域、宿主 tab | 检查 side panel 可见性与背景消息 |
| Agent 日志缺失 | 是否前台模式、日志目录权限、是否重启进程 | 查看 stderr;确认日志目录;重启 Agent |
章节来源
- src/background/debugger/debugger-session.js#L233-L296
- src/background/tool-debugger.js#L210-L233
- src/background/tool-debugger.js#L235-L275
- src/background/tool-debugger.js#L358-L387
- src/background/token-recorder.js#L16-L36
- src/side_panel/panel-context.js#L1-L18
- agent/src/logger.js#L141-L162
结论
AI Helper 的调试体系围绕三条主线展开:
- 页面级调试:通过
debug_page与 Chrome DevTools Protocol 实现 attach、evaluate、原生输入、截图和环境模拟。 - 网络与 API 调试:通过 debugger-session 的网络录制捕获请求与响应体,并结合扩展侧网络范围判定与 Agent 端日志定位问题。
- 性能与 Token 统计:通过 token-recorder 与 token-store 将 API 调用沉淀为 IndexedDB 记录,并在 side panel 中以趋势、分布、全局视图呈现。
实际调试时,建议按以下顺序推进:
- 先在 Console 中确认扩展端与 Agent 端日志是否正常。
- 使用
debug_page完成页面级验证。 - 使用 network 录制抓取 HTTP/WebSocket 数据。
- 通过 Token 统计面板确认调用是否落地、token 是否合理。
- 若涉及 background 与 side panel 的交互,重点检查消息传递、可见性判断与 Service Worker 生命周期。