为 Vision Agent 编写自定义工具:模板匹配(Template Matching)Custom Tool 实战指南
为 Vision Agent 编写自定义工具模板匹配Template MatchingCustom Tool 实战指南【免费下载链接】vision-agentThis tool has been deprecated. Use Agentic Document Extraction instead.项目地址: https://gitcode.com/GitHub_Trending/vi/vision-agent导读本指南以 examples/custom_tools/README.md 为主线完整讲解如何在 vision-agent 中开发一个模板匹配Template Matching自定义视觉工具并让VisionAgentCoderV2在求解问题时自动调用它。读完本文你将掌握自定义工具的注册方式、register_tool中 imports 参数的底层原理独立进程代码注入机制、旋转模板匹配算法的完整实现细节以及如何在对话中显式指定工具以获得稳定可靠的结果。一、示例概览这个 Custom Tool 能做什么官方在 examples/custom_tools/README.md 中提供了一个名为Template Matching Custom Tool的演示项目。它的业务目标是让 Vision Agent 使用自定义的template_match_工具在大图pid.png中找到小模板图pid_template.png出现的位置并进一步回答是否有匹配结果靠近 NOTE 5 区域这类空间关系问题。模板匹配本身并不是 Agent 内置工具列表里的能力而是由开发者通过register_tool机制注入给 Agent 的自定义工具。这一模式说明了 vision-agent 的工具系统是开放、可扩展的你可以把任意 Python 视觉算法封装成工具交给 Agent 在生成代码时按需调用。对应的示例目录examples/custom_tools/包含四个关键文件文件作用run_custom_tool.py自定义工具的注册代码 启动 Agent 的主流程template_match.py纯算法实现带旋转的模板匹配requirements.txt依赖声明torch、torchvisionpid.png/pid_template.png演示用目标图与模板图二、环境准备与快速运行README 给出了两条最直接的运行命令。第一步安装依赖pip install -r requirements.txt查看 examples/custom_tools/requirements.txt 可知示例的核心依赖非常精简只有两个torch torchvision其中torchvision用于调用torchvision.ops.nms做检测框的非极大值抑制NMStorch是其底层张量库。除此之外示例还依赖cv2OpenCV与numpy它们分别用于cv2.matchTemplate模板匹配和数组运算vision_agent本体则作为主框架提供注册与 Agent 能力。第二步运行示例python run_custom_tool.py脚本会完成两件事注册template_match自定义工具然后启动VisionAgentCoderV2向它提问在 pid.png 中找到 pid_template.png 的位置并判断是否有结果靠近 NOTE 5。Agent 会根据工具描述决定调用该自定义工具、生成并执行代码、最终返回带边界框的结果。说明与示例配套的完整问答流程同样可以在仓库内的 chat-app 演示examples/chat/中看到类似交互形态但本文聚焦于 custom_tools 这一最小可复现示例。三、注册自定义工具run_custom_tool.py 逐段解析examples/custom_tools/run_custom_tool.py 是自定义工具的标准模板我们逐段拆解。3.1 导入与装饰器注册import numpy as np from template_match import template_matching_with_rotation import vision_agent as va import vision_agent.tools as T import vision_agent.tools.planner_tools as pt from vision_agent.models import AgentMessage from vision_agent.utils.image_utils import get_image_size, normalize_bbox va.tools.register_tool( imports[ import numpy as np, from vision_agent.utils.image_utils import get_image_size, normalize_bbox, from template_match import template_matching_with_rotation, ] ) def template_match(target_image: np.ndarray, template_image: np.ndarray) - dict: ...几个关键点注册入口是va.tools.register_tool。vision_agent.tools包在 vision_agent/tools/init.py 中导出register_tool同时通过from .tools import ...导入大量内置工具目标检测、分割、OCR、视频追踪等。imports参数必须显式列出工具运行所需的全部导入语句。这是 README 强调的核心坑点后面第四节会深入原理。函数必须有规范的 docstring。AgentLLM正是通过 docstring 理解这个工具是干什么的、参数是什么、返回什么从而在写代码时决定是否调用它。示例的 docstring 给出了参数说明、返回值说明以及带cv2.imread的用法示例这是值得复用的最佳实践。3.2 工具函数体归一化边界框image_size get_image_size(target_image) matches template_matching_with_rotation(target_image, template_image) matches[bboxes] [normalize_bbox(box, image_size) for box in matches[bboxes]] return matches工具函数体做三件事用vision_agent.utils.image_utils的get_image_size获取目标图尺寸调用算法层template_matching_with_rotation得到原始像素坐标的边界框与得分用normalize_bbox把每个边界框归一化到 0~1 区间再原样返回。归一化是关键约定vision-agent 内置工具返回的 bbox 统一采用归一化坐标Agent 生成的代码例如画框、计算距离也都基于这一约定。自定义工具遵循同样的返回格式{bboxes: [...], scores: [...]}就能无缝融入 Agent 的代码生成与工具调用流程。3.3 主流程通过 AgentMessage 发起任务if __name__ __main__: agent va.agent.VisionAgentCoderV2(verboseTrue) result agent.generate_code( [ AgentMessage( roleuser, contentCan you find the locations of the pid_template.png in pid.png and tell me if any are nearby NOTE 5?, media[pid.png, pid_template.png], ) ] )va.agent包vision_agent/agent/init.py对外暴露VisionAgentCoderV2等 Agent 类。这里通过AgentMessage把用户问题与媒体文件media列表一起传入generate_code。Agent 内部会结合工具文档、规划结果生成可执行代码并运行最终给出带边界框的答案。四、核心算法template_match.py 的旋转模板匹配实现examples/custom_tools/template_match.py 是纯算法文件不依赖 vision-agent 的任何 API可以在任何 Python 环境单独复用。4.1 图像旋转辅助函数rotate_imagedef rotate_image(mat, angle): height, width mat.shape[:2] image_center (width / 2, height / 2) rotation_mat cv2.getRotationMatrix2D(image_center, angle, 1.0) abs_cos abs(rotation_mat[0, 0]) abs_sin abs(rotation_mat[0, 1]) bound_w int(height * abs_sin width * abs_cos) bound_h int(height * abs_cos width * abs_sin) rotation_mat[0, 2] bound_w / 2 - image_center[0] rotation_mat[1, 2] bound_h / 2 - image_center[1] rotated_mat cv2.warpAffine(mat, rotation_mat, (bound_w, bound_h)) return rotated_mat该函数对图像按指定角度旋转并通过计算旋转后的外接宽高bound_w/bound_h自动扩边避免旋转裁切。这是模板匹配支持任意旋转角度的前置条件。4.2 主函数template_matching_with_rotationdef template_matching_with_rotation( main_image, template, max_rotation360, step90, threshold0.75, visualizeFalse, ) - dict:核心参数与默认值如下参数默认值含义与影响max_rotation360旋转搜索的最大角度度step90角度步长。默认 90 度即只搜 0/90/180/270 四个方向可大幅降低耗时对任意角度模板可调小如 15/30 度threshold0.75cv2.matchTemplate归一化相关系数的命中阈值越高越严格visualizeFalse为True时用 OpenCV 窗口绘制并展示所有命中框调试用算法流程灰度化cv2.cvtColor(..., cv2.COLOR_BGR2GRAY)把目标图与模板转成灰度供cv2.matchTemplate使用多角度循环从0到max_rotation按step步进旋转模板若旋转后的模板尺寸大于目标图则跳过模板匹配对每个角度执行cv2.matchTemplate(main_image_gray, rotated_template, cv2.TM_CCOEFF_NORMED)用np.where(result threshold)找出所有得分超过阈值的坐标收集为(x, y, xw, yh)的边界框NMS 去重同一目标在多个角度/邻域可能产生多个重叠框因此调用torchvision.ops.nmsIOU 阈值0.2合并重叠框同时保留对应得分返回结果{bboxes: boxes, scores: scores}。返回值结构正是第三节中normalize_bbox与 Agent 所消费的标准格式bboxes为[x1, y1, x2, y2]列表scores为对应置信度列表。五、在对话中显式指定工具解决工具选择困难README 特别提醒了一个实战问题Tool choice can be difficult for the agent to get, so sometimes it helps to explicitly call out which tool you want to use.即让 LLM 自己从众多工具中选对自定义工具并不总是可靠。当存在大量内置工具目标检测、OCR、分割等时Agent 可能选错或编造不存在的工具名。缓解办法是在提问时点名工具import vision_agent as va agent va.agent.VisionAgentCoderV2(verbosity2) agent( Can you use the template_match_ tool to find the location of pid_template.png in pid.png?, mediapid.png, )注意两点指令中写的是template_match_带下划线后缀这是告诉 Agent 去工具列表里寻找以该前缀命名的工具media参数把图片传递给 Agent 会话如果需要同时传入模板图可像run_custom_tool.py的AgentMessage那样用media[pid.png, pid_template.png]列表形式。verbosity2README 示例与verboseTruerun_custom_tool.py 示例均为 Agent 的输出控制参数实际使用以你所安装版本的签名为准。显式点名工具之后Agent 生成代码时会优先匹配template_match_工具及其 docstring从而显著提升稳定性。六、底层原理为什么必须传 imports独立进程的代码注入机制README 的 Details 一节解释了自定义工具注册最核心的机制值得深挖Because we execute code on a separate process, we need to re-register the tools inside the new process. To do this,register_toolscopies the source code and prepends it to the code that is executed in the new process. But theres a catch, it cannot copy the imports needed to run the tool code.翻译过来即代码在独立进程中执行VisionAgentCoderV2生成的代码交由CodeInterpreter见 vision_agent/utils/execute.py在独立进程中运行新进程不认识自定义工具因此注册机制会把工具源码复制并前置拼接到新进程要执行的代码之前实现重新注册但源码复制不包含 import函数体里用到的cv2、numpy、template_match等依赖无法仅靠复制函数源码带入新进程所以必须由开发者在register_tool(imports[...])里显式声明。6.1 register_tool 的实现看 vision_agent/tools/init.py#L73-L88 的源码def register_tool(imports: Optional[List] None) - Callable: def decorator(tool: Callable) - Callable: import inspect global TOOLS, TOOLS_DF, TOOL_DESCRIPTIONS, TOOL_DOCSTRING, TOOLS_INFO from vision_agent.tools.tools import TOOLS if tool not in TOOLS: TOOLS.append(tool) globals()[tool.__name__] tool if imports is not None: for import_ in imports: __new_tools__.append(import_) __new_tools__.append(inspect.getsource(tool)) return tool return decorator逐行解读其行为把工具函数追加进全局TOOLS列表同时globals()[tool.__name__] tool使其可直接按名字访问将imports中的每条导入语句依次追加到__new_tools__用inspect.getsource(tool)取出工具完整源码也追加到__new_tools____new_tools__初始内容为[import vision_agent as va, from vision_agent.tools import register_tool]见 vision_agent/tools/init.py#L67-L70保证注入代码自身可解析。6.2 注入点DefaultImports.prepend_imports最终这些字符串被拼接到什么位置见 vision_agent/utils/agent.py#L195-L217 的DefaultImportsclass DefaultImports: common_imports [ import os, import numpy as np, from vision_agent.tools import *, from vision_agent.tools.planner_tools import judge_od_results, from typing import *, from pillow_heif import register_heif_opener, register_heif_opener(), ] staticmethod def to_code_string() - str: return \n.join(DefaultImports.common_imports T.__new_tools__) staticmethod def prepend_imports(code: str) - str: return DefaultImports.to_code_string() \n\n code可以看到Agent 每次执行代码前都会把common_imports含from vision_agent.tools import *与__new_tools__即所有已注册自定义工具的 imports 源码拼接再前置到目标代码上。这就是重新注册的完整链路common_imports默认导入 自定义工具 imports你显式传入的导入语句 自定义工具源码inspect.getsource 复制 换行 Agent 生成的业务代码由此也验证了 README 的告诫凡是工具函数体用到的第三方库都必须写进imports否则新进程执行注入代码时会直接NameError。反过来imports里只应放执行该工具所必需的导入避免污染执行环境。6.3 一条完整的最小注册示例README 给出了去掉业务逻辑的最小骨架import vision_agent as va va.register_tool( imports[import cv2], ) def custom_tool(*args): # Your tool code here pass与run_custom_tool.py中完整写法va.tools.register_tool等价只是注册路径的写法不同。两者的要点一致装饰器 imports 列表 规范 docstring。七、实战要点与最佳实践总结综合 README 与源码编写可被 Vision Agent 稳定调用的自定义工具应遵循以下要点注册三要素缺一不可va.tools.register_tool装饰器、完整的imports列表、描述清晰的 docstring含参数、返回与用法示例。返回格式对齐内置约定边界框归一化到 0~1用normalize_bbox返回{bboxes: ..., scores: ...}结构Agent 的后续代码画框、算距离、判断邻近关系才能正确消费。算法层与注册层分离template_match.py 只依赖cv2/numpy/torch与 vision-agent 解耦便于独立测试与复用run_custom_tool.py 只负责包装与注册。对话中显式点名工具提问时明确写template_match_这样的工具名降低 Agent 工具选择的随机性。依赖声明完整示例依赖torch/torchvision见 requirements.txt实际使用还应确保opencv-python、numpy与vision_agent本体安装到位。性能与精度权衡step决定角度搜索粒度——step90快但只覆盖四个方向需要任意角度匹配时调小步长同时匹配时间近似线性增长threshold0.75可根据实际误检情况上下调整。八、结语本文以 examples/custom_tools/README.md 为骨架从运行方式、注册代码、旋转模板匹配算法到register_tool的独立进程代码注入原理完整还原了为 Vision Agent 添加自定义工具的端到端流程。核心结论可以浓缩为一句话自定义工具 规范 docstring 的函数 register_tool注册 显式 imports 归一化 bbox 返回格式。掌握了这套模式你就能把任意 OpenCV / PyTorch 视觉算法快速武装成 Agent 的可调用能力。【免费下载链接】vision-agentThis tool has been deprecated. Use Agentic Document Extraction instead.项目地址: https://gitcode.com/GitHub_Trending/vi/vision-agent创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

相关新闻

词达人小工具2.0开源:C/Python双语言混合编程实战

词达人小工具2.0开源:C/Python双语言混合编程实战

简介:词达人小工具2.0是一份面向编程学习者与开发爱好者的开源工具源码资料,核心用途是解析在线学习平台“词达人”的答题数据,帮助读者理解网络抓包与答案提取的实现思路。资源包共1个文件,为PDF格式,大小约349KB&…

2026/9/22 2:26:46 阅读更多 →
从IntelliJ IDEA迁移到VS Code+AI:轻量开发工作流实践

从IntelliJ IDEA迁移到VS Code+AI:轻量开发工作流实践

上个月,我把 IntelliJ IDEA 从主力开发机里卸载了。用 AI 写代码之后,我最大的感受不是“写得更快”,而是“看的时间更多”。以前打开 IDEA,第一件事是等索引,第二件事是等着它把整个项目的依赖关系吃进内存&#xff1…

2026/9/21 3:45:13 阅读更多 →
RVC变声器完整上手:10分钟录音,免费开源训出你的AI音色

RVC变声器完整上手:10分钟录音,免费开源训出你的AI音色

RVC变声器完整上手:10分钟录音,免费开源训出你的AI音色 【免费下载链接】metahuman-stream Real time interactive streaming digital human 项目地址: https://gitcode.com/GitHub_Trending/me/metahuman-stream Retrieval-based-Voice-Conversi…

2026/9/19 22:59:53 阅读更多 →

最新新闻

文字扫描识别软件面试避坑:3个核心考点助你搞定性能优化

文字扫描识别软件面试避坑:3个核心考点助你搞定性能优化

文字扫描识别软件面试避坑:3个核心考点助你搞定性能优化 很多开发者学了 OCR 基础语法,却卡在“怎么把识别准确率提到 99% 以上”这一步。别慌,这正是面试大厂时最容易被问到的 性能优化…

2026/9/22 2:26:20 阅读更多 →
车架号查询车辆信息实战:5种后端方案对比与最佳实践

车架号查询车辆信息实战:5种后端方案对比与最佳实践

车架号查询车辆信息实战:5种后端方案对比与最佳实践 学会语法却不知怎么搭项目?这是很多开发者从教程走向生产环境时最大的拦路虎。尤其是面对像 车架号查询车辆信息 这种典型的高频业务场景,很多人只会写 SELECT * FROM cars…

2026/9/22 2:26:20 阅读更多 →
沪深300指数源码解析:3步吃透指数计算与回测框架

沪深300指数源码解析:3步吃透指数计算与回测框架

沪深300指数源码解析:3步吃透指数计算与回测框架 面试被问原理答不上来,这是很多量化新人的噩梦。当你自信满满地说“我会Python”,面试官追问“沪深300指数的加权方式具体怎么在代码里实现?处理复权因子有坑吗?”时,瞬间大脑空白。这种尴…

2026/9/22 2:26:20 阅读更多 →
控制近义词踩坑实录

控制近义词踩坑实录

搞懂控制流:从报错到源码解析的避坑指南 屏幕上的红色 StackTrace 像一堵墙,把你死死堵在调试界面。你盯着那行 Uncaught TypeError…

2026/9/22 2:25:19 阅读更多 →
枪破兑换码性能优化:新手避坑指南

枪破兑换码性能优化:新手避坑指南

枪破兑换码性能优化:新手避坑指南 学会语法却不知怎么搭项目,这是很多开发者入行时的第一道坎。很多人盯着教程里的代码敲了一遍又一遍,觉得自己懂了,真到了公司项目里,面对海量请求和高并发场景,瞬间就懵了。 这时候, 性能优化…

2026/9/22 2:25:19 阅读更多 →
C指针性能优化实战:3招解决栈溢出,附速查手册

C指针性能优化实战:3招解决栈溢出,附速查手册

C指针性能优化实战:3招解决栈溢出,附速查手册 刚接手一个老旧的C项目,打开IDE运行,屏幕瞬间被红色的报错信息淹没。Stack Trace…

2026/9/22 2:25:19 阅读更多 →

日新闻

3台商务办公笔记本实测:手写实现环境配置,告别卡半天

3台商务办公笔记本实测:手写实现环境配置,告别卡半天

3台商务办公笔记本实测:手写实现环境配置,告别卡半天 配置环境就卡半天?别怪机器慢,多半是你没选对工具链。在Java、Go或Python的项目现场, 手写实现…

2026/9/22 0:00:41 阅读更多 →
剑帝加点速查手册:3分钟搞懂核心逻辑

剑帝加点速查手册:3分钟搞懂核心逻辑

剑帝加点速查手册:3分钟搞懂核心逻辑 面试被问原理答不上来,是不是常态?别慌。很多开发者对着 GitHub 开源仓库里的代码发呆,看似简单实则暗藏玄机。今天这份【剑帝加点】速查手册,直接带你拆解核心实现,把面试必考的原理讲透。…

2026/9/22 0:00:41 阅读更多 →
手写实现图片压缩网站核心:搞定WebP转换与质量调优

手写实现图片压缩网站核心:搞定WebP转换与质量调优

手写实现图片压缩网站核心:搞定WebP转换与质量调优 复制来的代码跑不通不知道怎么调?别慌,这种“复制粘贴地狱”在开发圈太常见了。尤其是做 图片压缩网站…

2026/9/22 0:00:41 阅读更多 →

周新闻

Flutter for OpenHarmony游戏卡片渐变背景实战:从原理到性能优化

Flutter for OpenHarmony游戏卡片渐变背景实战:从原理到性能优化

直接铺开项目本身吧。这几个月我一直在折腾一件事:用Flutter给OpenHarmony做一款游戏集合类的App,说白了就是把若干小游戏塞进一个壳里,用统一入口分发。这个方向本身不算新鲜,真正让我花了不少心思的,是首页那堆游戏卡…

2026/9/21 3:13:20 阅读更多 →
Word表格编号全攻略:从列表编号到题注交叉引用

Word表格编号全攻略:从列表编号到题注交叉引用

写Word文档,最让人头疼的往往是那些“看起来不起眼”的小问题。比如表格编号这事:今天在表后面多加了两个空白行,明天给客户交稿前发现整个章节的编号全部错位,光是挨个改序号就能耗掉大半个下午。我前阵子帮人整理一份上百页的技…

2026/9/21 2:19:36 阅读更多 →
从第一个站到第二个站:独立开发者的静态网站选型与落地实践

从第一个站到第二个站:独立开发者的静态网站选型与落地实践

1. 项目概述1.1 核心需求解析做独立开发者这几年,说实话,第一个网站上线的那天晚上我兴奋得没睡着。但等它跑了半年,流量惨淡、功能臃肿、代码自己都懒得看第二遍之后,我才慢慢琢磨明白一个道理:第一个网站是练手&…

2026/9/21 4:51:05 阅读更多 →

月新闻

持续集成 流水线自动化与 声明式交付 实践:原型怎样变成可用功能

持续集成 流水线自动化与 声明式交付 实践:原型怎样变成可用功能

持续集成 流水线自动化与 声明式交付 实践:原型怎样变成可用功能分类:[AI/大模型]细分主题:AI 增强型 CI/CD 流水线自动化与 GitOps 实践:Agent 工作流、工具调用与任务拆解:从原型到生产的验收清单很多团队在尝试用大…

2026/9/21 15:36:51 阅读更多 →
容器编排 生产环境运维与排障实战:复盘记录怎样真正派上用场

容器编排 生产环境运维与排障实战:复盘记录怎样真正派上用场

容器编排 生产环境运维与排障实战:复盘记录怎样真正派上用场分类:[工程技术]细分主题:Kubernetes 生产环境运维与排障实战:可复制的项目复盘模板与决策记录大部分团队的事故复盘报告,最后都变成了躺在 Confluence 或钉…

2026/9/21 15:36:51 阅读更多 →
容器 容器化技术与镜像安全管理:核心链路应该先拆哪一步

容器 容器化技术与镜像安全管理:核心链路应该先拆哪一步

容器 容器化技术与镜像安全管理:核心链路应该先拆哪一步分类:[工程技术]细分主题:Docker 容器化技术与镜像安全管理:核心链路的逐步实现与关键代码取舍面对一个积累了五六年历史包袱的单体架构应用(包含 Web 接口、后台…

2026/9/19 23:35:34 阅读更多 →