15.4 自定义工具系统

模型: claude-opus-4-6 (anthropic/claude-opus-4-6) 生成日期: 2026-02-17


oh-my-opencode 通过 OpenCode 的 Plugin tool 接口注册了 15 个自定义工具,为 Agent 提供了远超 OpenCode 内置工具集的能力。本节将概览这些工具,并深入分析两个最具创新性的工具:AST-Grep 和 Hashline Edit。

15.4.1 工具列表与实现

以下是 oh-my-opencode 注册的全部工具:

工具
源码位置
功能
技术栈

ast_grep_search

tools/ast-grep/

AST 级代码模式搜索

ast-grep CLI

ast_grep_replace

tools/ast-grep/

AST 级代码模式替换

ast-grep CLI

background_output

tools/background-task/

获取后台任务输出

OpenCode SDK

background_cancel

tools/background-task/

取消后台任务

OpenCode SDK

call_omo_agent

tools/call-omo-agent/

直接调用指定 Agent

OpenCode SDK

delegate_task

tools/delegate-task/

将任务委托给子 Agent

OpenCode SDK

glob

tools/glob/

增强版文件模式匹配

Node.js fs

grep

tools/grep/

增强版内容搜索

ripgrep

hashline_edit

tools/hashline-edit/

基于行号哈希的精确编辑

xxHash32

interactive_bash

tools/interactive-bash/

tmux 交互式终端

tmux

look_at

tools/look-at/

多模态文件分析

多模态 LLM

lsp_*(6 个)

tools/lsp/

LSP 集成(定义跳转、引用查找等)

LSP 协议

session_*

tools/session-manager/

会话历史查询与搜索

OpenCode Storage

skill_mcp

tools/skill-mcp/

Skill 内嵌 MCP 调用

MCP SDK

skill

tools/skill/

Skill 文件加载

文件系统

slashcommand

tools/slashcommand/

斜杠命令执行

命令系统

task

tools/task/

增强版任务委托

OpenCode SDK

工具注册的入口在 tools/index.ts

工具分为两种注册模式:

  1. 静态工具(如 builtinTools 中的 LSP 工具):不需要运行时上下文,直接导出

  2. 工厂工具(如 createAstGrepTools(ctx)):需要注入 Plugin 上下文(目录路径、客户端引用等),通过工厂函数创建

15.4.2 AST-Grep 工具深入分析

AST-Grep 是 oh-my-opencode 中最复杂的工具之一。它提供了基于**抽象语法树(AST)**的代码搜索和替换能力,远超传统的文本搜索(grep)。

衍生解释:什么是 AST(抽象语法树)?

AST(Abstract Syntax Tree)是编程语言编译器/解释器在解析源代码时生成的树状数据结构。它将代码的语法结构表示为一棵树,其中每个节点代表一个语法构造(如变量声明、函数调用、if 语句等)。

例如,代码 const x = 1 + 2 的 AST 大致如下:

AST 级搜索文本级搜索 的关键区别在于:

  • 文本搜索 grep "console.log" 会匹配所有包含该字符串的行,包括注释中的 // console.log 和字符串中的 "console.log"

  • AST 搜索 ast-grep -p "console.log($MSG)" 只匹配真正的 console.log 函数调用,忽略注释和字符串

AST 搜索还支持元变量(Meta-variables):$VAR 匹配单个 AST 节点,$$$ 匹配多个节点。这使得搜索模式可以表达复杂的代码结构。

架构设计

AST-Grep 工具的实现涉及 13 个源文件,架构如下:

工具定义

oh-my-opencode 提供了两个 AST-Grep 工具:搜索替换

空结果智能提示

一个贴心的设计是 getEmptyResultHint() 函数——当搜索没有结果时,它会分析搜索模式并给出修正建议:

这利用了 AST-Grep 的一个常见陷阱:AST 模式必须是完整的 AST 节点。搜索 function $NAME 不会匹配任何内容,因为这不是一个有效的 JavaScript AST 节点——它缺少参数列表和函数体。正确的模式应该是 function $NAME($$$) { $$$ }

CLI 进程管理

AST-Grep 的底层是通过调用 ast-grep CLI 二进制文件实现的:

oh-my-opencode 自动处理了 ast-grep 二进制文件的获取——如果系统中没有安装,它会自动下载对应平台的预编译二进制。

15.4.3 Hashline Edit 的创新设计

Hashline Edit 是 oh-my-opencode 独创的文件编辑工具。它通过给每一行代码附加一个行号哈希,解决了 LLM 编辑文件时的一个根本问题:编辑目标定位的准确性

问题背景

传统的文本编辑工具(如 OpenCode 内置的 Edit 工具)使用"旧文本 → 新文本"的替换模式:

这种模式的问题是:如果文件中有多处 const x = 1,工具无法确定应该替换哪一个。OpenCode 的 Edit 工具要求 oldString 必须唯一匹配——如果匹配到多处,编辑会失败。

这迫使 LLM 不得不提供更多的上下文代码来确保唯一性,增加了 Token 消耗和出错概率。

Hashline 解决方案

Hashline Edit 的核心思想是:给每一行代码附加一个短哈希值,作为行级别的"身份标识"

格式为 行号:哈希|内容,其中:

  • 行号:1-based 的行号

  • 哈希:行内容的 xxHash32 哈希值的前 2 个十六进制字符(256 种可能值)

  • 内容:行的原始文本

哈希计算

哈希计算的几个设计选择:

  1. 去除空白后哈希content.replace(/\s+/g, "")。这意味着缩进变化不会改变哈希值,增强了稳健性。

  2. 使用 xxHash32:一种非常快速的非加密哈希函数,适合大量小字符串的快速哈希。

  3. 256 种可能值:哈希值只有 2 个十六进制字符(00ff),这是有意的设计——太短可能碰撞,太长浪费 Token。256 种值在"定位准确性"和"Token 效率"之间取得了平衡。

四种编辑操作

Hashline Edit 支持四种编辑操作:

哈希不匹配保护

Hashline Edit 的最重要特性是哈希验证。当 LLM 引用一行时提供的哈希与文件当前内容的哈希不匹配时,编辑会失败并返回错误:

这解决了"陈旧编辑"问题——如果文件在 LLM 读取后被修改了(可能被另一个并行 Agent 修改),Hashline Edit 会拒绝编辑而不是在错误的位置写入内容。

自底向上应用

编辑操作按照从下到上的顺序应用(最高行号优先)。这是一个关键的设计——因为插入或删除行会改变后续行的行号。如果从上到下应用,前面的编辑会使后面的行号引用失效;从下到上应用则避免了这个问题。

与 Read 工具的集成

Hashline Edit 不是孤立的工具——它需要与 Read 工具配合使用。oh-my-opencode 通过 hashline-read-enhancer Hook 增强了 OpenCode 的 Read 工具输出:

这样,LLM 在读取文件时就自动获得了每行的哈希值,可以直接用于 Hashline Edit 操作。

衍生解释:AST 级代码搜索的优势

传统的代码搜索(如 grepripgrep)是基于文本的——它将代码视为字符串序列,使用正则表达式进行模式匹配。这种方式简单快速,但有明显的局限性:

  1. 无法理解代码结构:搜索 function add 会匹配函数定义、注释中的描述、字符串里的引用,无法区分它们

  2. 无法处理格式差异function add(a, b)function add( a, b ) 在文本上不同,但在 AST 上是相同的

  3. 无法表达结构化模式:"找到所有接受两个参数的函数"这种需求几乎无法用正则表达式表达

AST 搜索通过先解析代码为 AST,再在 AST 上进行模式匹配,克服了这些局限。ast-grep 支持 25 种编程语言的 AST 解析,使用 Tree-sitter 解析器(一种增量解析库,被 GitHub、Neovim 等广泛使用)。

但 AST 搜索也有代价:它需要完整解析源文件,因此比文本搜索慢。oh-my-opencode 通过调用 ast-grep CLI 而非在进程内解析来缓解这个问题——CLI 使用 Rust 实现,性能极高。

本节小结

oh-my-opencode 的自定义工具系统通过 Plugin 的 tool 接口注册了 15 个工具,覆盖了从代码搜索到后台任务管理的各个方面。

两个最具创新性的工具是:

  1. AST-Grep:基于抽象语法树的代码搜索和替换,支持 25 种语言,通过元变量表达结构化模式。它包含自动二进制下载、空结果智能提示和进程超时管理等完善的工程实现。

  2. Hashline Edit:通过行号 + xxHash32 短哈希的组合,为每行代码提供精确的"身份标识"。这解决了 LLM 编辑文件时的定位准确性问题,同时通过哈希验证防止了对陈旧文件内容的错误编辑。

Last updated