第三章 工具体系
本章覆盖第 9–13 章:先总览工具体系,再分述智能编程工具与安全分析工具,随后是外部工具服务的接入方式,以及贯穿所有工具的权限与审批机制。
第九节 工具体系总览
工具(Tool)是 AI 在你电脑上"动手"的载体。
9.1 三类工具
- 智能编程工具:读写文件、跑命令、版本控制、查找等(详见第十节)。
- 安全分析工具:哈希、字符串、IOC、可执行格式解析、反汇编、规则匹配、流量元数据等(详见第十一节)。
- 外部工具服务:连接外部系统的工具,如 Notion、内部 API、私有知识库等(详见第十二节)。
9.2 工具开关
每个工具都可以设置为:
- 启用:直接放行。
- 询问:每次调用前弹窗审批。
- 禁用:直接拒绝。
入口在输入区模式滑块旁的齿轮(智能体管理器)→「配置工具」Tab,可按工作模式独立配置。三态真实约束运行:「禁用」在主代理与子代理两侧一并生效;「询问」接入实际确认流程,调用前暂停等你批准;卸载插件或外部工具服务时会一并清理残留的工具配置,盘上配置与实际可用工具保持一致。
工具列表更稳:工具列表拉取失败时自动退避重试,多次重试仍失败才提示;兜底工具表与内置工具同源生成,不会莫名少一截。
9.2.1 工具分类延迟加载(默认开启)
工具总数已过百,若每轮都把全部工具描述发给模型,既占上下文又拖慢响应。因此默认只携带常用的一小部分(二十余个),其余按分类在需要时才加载。
- 常驻分类:文件读写与搜索、命令执行、工具自省、子任务委派与待办规划 —— 这些几乎每轮都要用。
- 按需加载的分类(16 类):代码理解、git、安全分析、威胁情报、SBOM、外部工具服务、联网检索、技能、测试、lint、SAST、插件市场、插件管理、GitHub、系统信息、时间。
- 两种加载方式:你的提问里出现相关词汇时自动预加载对应分类;助手也可以主动调用
tools.load点名加载。中途新连上的外部工具服务会自动放行。 - 助手知道工具表是不全的:系统提示词里会说明这一点并给出分类目录,助手不会因为"表里没有"就认定某项能力不存在;查询自身可用工具时,返回结果也会提示"看不见 ≠ 不存在,可以先加载"。
开关:智能体管理器 →「配置工具」Tab →「工具分类延迟加载」。关掉后所有工具恒常驻。当可用工具本就不多(不超过 32 个)时,系统会直接整表放行,不做延迟加载。
若某个外部工具服务你用得很频繁,可以在同一面板里单独为它关闭延迟加载,让它的工具始终可用 — 见 §12.4。
9.3 工具命名空间
外部工具服务暴露的工具会被自动加上前缀(例如 notion.*),与内置工具区分,互不冲突。
9.4 工具调用的可视化
每一次工具调用都会以可折叠卡片形式显示在消息流中,包含:
- 工具名 + 入参摘要
- 执行耗时
- 结果(成功 / 失败 / 截断)
你可以独立查看每个工具调用的细节,便于审计与回溯。
在途调用的行内进度:耗时较长的工具在调用行的工具名右侧实时显示进度(转圈图标 + 文案,有比例时另带一条细进度条);进度文案优先展示,参数摘要让位截断。只有真正在途的调用才会点亮。
| 来源 | 显示内容 |
|---|---|
sec.decompile / code.ask 等待模型输出(每 20 秒一次心跳) |
「等待 {模型} 输出(已 Ns)」→「{模型} 思考中(已 Ns,思考 ~N tokens)」→「{模型} 生成中(约 P%,预计还需 ~Ms,已 Ns,~N tokens,R tok/s)」;百分比与预计剩余排在最前,基于同一工具 / 模型的历史估算,首次调用不报百分比,最多显示到 99% |
| 建代码索引 | 「建立代码索引 X/N」,带比例条 |
| 语言服务器自动下载、SBOM 同步 | 文本进度 |
| 其它工具执行超过 60 秒 | 「已运行 1m05s」逐秒走表;工具声明了执行时限时一并标出上限,如「已运行 1m05s / 上限 2m00s」(fs.exec 默认上限 120 秒、test.run 300 秒、lint.run 180 秒、sast.run 240 秒,可由调用参数或策略调整)。参数解析、审批确认、Hook 的等待不计入;工具自己正在报进度时不显示 |
- 子任务派发、等待类工具(
Agent/AgentParallel/TaskWait等)与向你提问不显示「已运行」。 - 后台会话的进度会以一条原地更新的提示告诉你(「会话名:进度」);「已运行」只在调用行内显示。
- 「极简」密度下,正在显示行内进度的那条调用不会被合并进「N 次工具调用尝试」。
9.4.1 Hook 执行过程可见
每次钩子(hook)执行都会在对话流里出现一条系统消息,渲染成类似工具调用的可折叠条(内容按 Markdown 显示),方便确认钩子到底跑没跑、跑了什么、是否影响了下一步动作 — 不再是黑盒。
9.4.1.1 工具执行空闲超时(默认 10 分钟)
给工具执行加了「空闲超时」兜底:某个工具长时间没有任何反馈时会被安全收尾,不再让整轮一直挂着干等。这道兜底按「空闲(无反馈)」判定,不按总时长 —— 只要工具持续有进度反馈,长任务就不会被固定时限打断。
- 触发条件:工具连续 ≥ 默认 10 分钟没有上报任何进度。判据是工具自己上报的进度,网关层的保活心跳不算反馈。
- 不剥夺工具自己的时限:声明了执行时限的工具(如
fs.exec的timeout),兜底至少让到「工具时限 + 6 分钟」之后才生效 —— 例如fs.exec设timeout=900的长命令不会再在 10 分钟处被放弃。 - 外部工具服务(MCP)调用同样改为空闲制:连续 35 分钟没有工具反馈才判超时(每次收到反馈即重新计时),不再按 35 分钟总时长取消仍有反馈的调用;有时限通告时至少等到「剩余时限 + 5 分钟」。
- 被放弃的调用迟到的进度不会记到同名的下一次调用上。
- 豁免:子 Agent 家族(
Agent/AgentParallel/TaskWait/TaskOutput/TaskStop)单独走 §15.2.1 的空闲窗口 + 绝对兜底,不被这道空闲超时误杀。
9.4.1.2 重复调用提醒(疑似空转)
助手偶尔会陷入"用同样的参数把同一个工具反复调用"的循环 —— 它一直在动,所以空闲超时抓不到,但其实毫无进展,额度却在持续消耗。
- 连续 3 次同参调用同一工具即在工具结果里提示助手,请它换个思路;次数继续增加会逐级加重措辞。
- 会话列表上标记「疑似空转」,悬停可见已重复的次数与工具名;侧边栏与顶部标签页两种布局都会标记。同时发出通知,即使你切到别的会话也能第一时间发现。
- 重启应用后标记依然保留,不会因为重启而漏掉;等你在该会话发出新的一条消息后自动清除。
- 轮询类工具(等待子任务、拉取命令输出等)本就需要反复调用,不在此列。
9.4.1.3 回复复读检测(复读空转)
与上面"同参反复调用工具"不同,这里看的是不调用工具、只在正文里反复输出相似内容的情况 —— 模型在一条回复里同一行刷屏,或者一连几轮都回同一句话却不动手。
- 单轮内按行截停:一条回复最近 25 行里同一行出现 ≥ 3 次(其中至少两次相邻),或出现 ≥ 5 次,就当场截停这次输出 —— 正文保留到复读区的第一遍,已经流出的思考内容保留。几句话之间来回轮转、「好。」「执行。」这类极短句刷屏也能识别;代码块、表格行、纯标点行不计入。已经带了工具调用的回复不截。
- 跨回合提醒与停转:连续几轮没调用任何工具、回复内容都一样时,第 3 次起给模型一句提醒(不落盘),第 5 次加重;第 8 次(或一条链上累计 3 次单轮截停)自动停转,同时暂停自动续跑,并在会话里留一条说明:「模型最近 N 次回复都是「…」且没有任何实际动作,判定为复读空转,已自动停止……」。补充更具体的指示后继续,或换个模型再试。你的新输入、工具结果都会把计数清零。
- 看得见:会话列表上同样标出「疑似空转」,后台会话还会弹提示;停转时即使是当前会话也会提示。
9.4.2 轨迹面板(Trace)
会话顶部的统计气泡(StatsPopover)里和「Stats」面板并列有一个 「轨迹」(Trace)面板:把 AI 一次运行里调用了哪些工具、按什么顺序、各自的输入输出与耗时摊开成时间线,方便回看它到底怎么一步步把活做完的,也方便排查「哪步走偏 / 烧在哪」。
按「运行」切分,不再把整个会话糊成一团:面板顶部有一排运行(run)选择器,按你发出的每条消息切分成一次次独立运行,默认看最近一次;每个 run 标签上直接带步数、工具调用数、token 与失败数,一眼挑出可疑的那次。
顶部聚合卡显示这一次运行的:
| 指标 | 说明 |
|---|---|
| 对话轮次 / 工具调用 / 工具失败 / 错误 | 这一次运行的基本盘 |
| 门禁注入 | 自动注入的合计次数,悬停可见来源拆分(门禁 / 目标 / 历史折叠 / 待办 / 自愈) |
| Token 合计 | 口径已标注:含已被排除出上下文窗口的步(所以可能大于"当前上下文占用") |
| 缓存命中 | 提示词缓存命中比例,判断"重复前缀有没有省下钱" |
| 疑似循环 | 同一「工具 + 参数」指纹重复的最高次数与工具名,≥ 3 次开始警示(见 §9.4.1.2) |
| 上下文压缩 | 本次运行发生的 SUMMARY 压缩次数 |
| 暂停待办 | 模型自报"已按你的要求停下、不再推进待办"的次数(见 §16) |
| 工具耗时 / 总时长 / 模型清单 | 时间去向与用到的模型 |
下面还有工具维度的统计表(每个工具的调用数 / 失败数 / P50 / P95 / 最长耗时),以及一条 「每轮 Prompt」趋势条 —— prompt token 逐轮等差递增往往就是"陷入循环 / 上下文在膨胀"的指纹,看这条比逐步翻快得多。
时间线:
- 每步显示序号 / 角色 / 类型 / 来源 / 工具名、耗时、prompt / completion / total token、模型、finish reason、成败与错误信息,以及内容与调用参数的预览(工具步能直接看到这次到底传了什么参数,不用回消息流里翻)。
- 点一步即跳到消息流中对应位置,回看「哪步走偏」更方便。
- 过滤:全部 / 仅工具 / 仅错误 三档,排障时直接切到「仅错误」。
- 长运行只加载末尾一段(默认末 500 步,聚合数字仍是全量),顶部提示「已省略更早的 N 步」,点「加载更早」按窗翻页,不会一次把超长运行全灌进来。
- 特殊步会单独标出:「上下文压缩(SUMMARY)」标明这次收编了多少条;「自报暂停」标明此处模型输出了停下的信号(该标记不进正文,只在轨迹里可见)。
子代理下钻:Agent / AgentParallel 这类派发步上有「子轨迹」入口,点进去看这个子代理自己的完整轨迹,看完点「返回主轨迹」回来。下钻态下步骤不提供跳转(那些行属于子会话文件,主消息流里没有对应位置)。
导出:面板右上「导出」把当前视图(当前 run / 当前子轨迹)落成文件,旁边有「脱敏」勾选框,默认勾上 —— 勾上则按 设置 → 数据脱敏 的规则替换后再落盘(没配规则时等于无变化),取消勾选按原文导出。成功后 toast 里给出落盘路径。子轨迹视图下不提供导出与脱敏。
刷新与错误态:数据来自会话 JSONL 的服务端聚合,打开面板时加载一次,不做实时轮询;这一轮跑完时面板会自动刷新一次(此时 JSONL 已带终态),也可以随时点右上的刷新按钮。读取失败时面板给出「读取轨迹失败,点『刷新』重试」而不是空白。
9.5 让助手自己配置 MCP 服务
除了在设置面板里手动添加外部服务,助手还可以在对话里直接帮你配置 MCP server。AVL Code 提供 9 个 mcp.* 工具,常配合内置 mcp-admin 助手使用:
| 工具 | 用途 |
|---|---|
mcp.list_servers |
列出当前所有 MCP server |
mcp.describe_server |
看某个 server 的详细配置(密钥脱敏) |
mcp.list_tools |
看某个 server 暴露的工具 |
mcp.test_server |
用临时连接做真握手探活(30 秒预算),区分 validate_args / policy_denied / needs_approval / connect / list_tools / ok 六个阶段:policy_denied = stdio 命令被当前工作模式 / 命令策略禁止,或 http / sse 地址指向本机 / 内网 / 链路本地(含 localhost、*.internal、云元数据地址;会话开启无限制模式时不拦,本机的 server 请在「设置 → MCP」的服务表单里点「测试」);needs_approval = stdio 命令不在命令白名单里,已请你本人批准,批准后自动重试 |
mcp.add_server |
新增(写类,两步制) |
mcp.remove_server |
删除(写类,两步制)。默认 MCP 后端现在也可删(此前网关会拒删,导致默认后端怎么点都删不掉) |
mcp.toggle_server |
启停(写类,两步制) |
mcp.import_config |
批量导入;同时识别原生格式与 Claude Desktop 的 {mcpServers:{...}} 形态 |
mcp.export_config |
导出当前配置(密钥脱敏) |
两步制(dry-run):写类工具(add / remove / toggle / import)必须显式传 confirm=true 才会真正落配置;首次调用默认返回 dry-run 预览(完整命令行、路由、默认后端变更、冲突清单)让你审完再确认。这是没有 PreToolUse defer hook 时的兜底闸门 — LLM 单步不可直接做破坏。
密钥脱敏:所有读类工具返回的 authToken 一律只显示尾 4 位(其余字符以星号占位),环境变量值整体打码,避免在对话流里泄露凭证。
典型对话:
「帮我把 mcp-trends-hub@1.6.0 接进来。」
助手 → 调
mcp.add_server(dry-run)→ 返回预览 → 你确认 → 助手再调mcp.add_server(confirm=true)→ 落配置 → 用mcp.test_server真握手探活 → 报告 21 个 trending 工具可用。
