Seom-ingit
vision_kit
Make your AI agent a math tutor. Structured extraction of vectors, matrices & geometry from math figures, with dimension-consistency + geometric self-check. Vision plugins for DeepSeek Harness, opencode (MCP) & CLI. Verify, don't believe.
- Stars
- 0
- Language
- Python
- Created
- Aug 14, 2026
- Updated
- Aug 14, 2026
Introduction
English · 简体中文
👁️ vision_kit
Make your AI agent a math tutor. · 把 AI 变成能教你做题的家教。
看数学 / 几何题图,靠的不是看图,而是「看对」:从图里抽取向量、矩阵、坐标、角度, 自动检查维度是否一致、几何是否自洽,漏了重试补全、大图自动分块。 结果不对就读不出来——而不是把错题当真。任意文本模型,接上它就能"看见"数学图。
Python · OpenAI 兼容视觉模型 · MCP · DeepSeek Harness · opencode
它是唯一会「算」的视觉插件: 竞争的插件都只会「看」(通用看图问答),
vision_kit 在 VLM 输出之后加上一层确定性校验——
三角形内角和 ≠ 180°、向量加法不匹配、矩阵维度不符、负值/越界,
任一触发就采样重试,重试耗尽后把 ✓ / ✗ 逐条返回给 agent,让它能发现
「VLM 读错数」而不是把错题当真。
能力一览
| 能力 | 说明 |
|---|---|
| 结构化识别 | 提取向量 / 矩阵 / 坐标 / 角度 / 未知量等数字标注 |
| 维度一致性 | 同组向量 / 矩阵自动校验维度,发现漏数自动采样重试补齐 |
| 几何自洽校验 | 三角内角和、向量加法、矩阵乘法维度、负值/值域 —— 纯逻辑,零外部依赖 |
| 图像预处理 | 小图自动放大(保证数字清晰)、超大图 2×2 带重叠分块后合并 |
| 多端接入 | 同一个引擎四端复用:DSH 插件 / opencode 插件 / MCP / CLI |
🤏 怎么选:describe 还是 extract?
vision_kit 的两个工具分工不同,选对才能发挥各自优势:
| 场景 | 推荐工具 | 说明 |
|---|---|---|
| 非数学/几何图(照片、场景图、流程图、电气/电路示意图、通用图片问答) | describe | 只看图返回自然语言描述/回答问题,泛化能力强,不会硬套结构 |
| 带数值标注的数学题图(向量 / 矩阵 / 点坐标 / 角度 / 长度 / 未知量) | extract | 结构化提取 + 维度一致 + 几何自洽校验,是它最擅长的 |
| 想两者都要 | both | 先描述全貌,再结构提取 |
几个需要知道的边界:
extract是"数学图专用",它强制按向量/矩阵/坐标输出结构。对没有这类结构的图(如电气布局、UI、照片),模型可能为凑格式而编造不存在的向量——这种情况请改用describe。describe不看结构,适合通用看图;但对带精确数字标注的题图,它不会做维度/几何校验,拿不到可信的结构化结果。- 判断一张图"算不算数学题图":画面上是否要精确读出成组的数字序列(向量、矩阵、坐标、角度)。是 →
extract;否 →describe。
一张(黑底)电气原理图测试:
describe能准确识别三相电源、PLC、各类开关/端子;若用它跑extract,因图中无向量/矩阵标注,可能得到编造的假向量——这正是"非数学图请用 describe"的典型场景。
对比:为什么是 vision_kit
| 插件 / 项目 | 定位 | vision_kit 的差异 |
|---|---|---|
dsh-vision (view_image) | 通用看图问答 | ✅ 唯一做结构化数学/几何图的结构输出 |
dsh-tool-see-image (see_image) | 通用看图 | ✅ 有维度校验、几何自洽、补漏重试 |
dsh-plugin-deepeye | 通用看图 | ✅ 有确定性自洽校验,非纯描述 |
dsh-vision-toolkit | OCR / UI 还原 | ✅ 面向数学标注,校验数值自洽 |
一句话:「读图 + 几何自洽校验」的组合目前无人做。vision_kit 把校验放在 VLM 输出之后—— 纯逻辑、可测试、可评测,不依赖特定的视觉模型能力。
🤔 第一次用,先确认这几点
1. 拿视觉模型的 Key(阿里云百炼 / DashScope)
推荐模型 qwen3-vl-flash 来自阿里云百炼。去 dashscope.console.aliyun.com 注册/登录阿里云 → 开通百炼 → 创建「API Key」(SK- 开头)。所有使用方式(CLI / MCP / 插件)都只需要这一个 Key。
2. 三种接入方式,先跑通哪一个?
- 只想快点看效果 → 用「命令行 CLI」(最直接,一条命令出结果)。
- 想让 opencode 的 agent 能看图 → 用「opencode 视觉插件」(推荐给开发)。
- 想在自己写的 Python 脚本里调用 → 用「快速开始(Python API)」。
下面按「CLI → opencode 插件 → DSH 插件」顺序介绍,按需跳到你需要的章节即可。
3. 工作在哪个目录?
仓库根目录就是 vision_kit 的包根(见 pyproject 的 package-dir)。请在克隆下来的仓库根目录运行命令与放置图片,
这样 python -m vision_kit.* 和 test_figure.png 才能被找到。
快速开始(Python)
💡 推荐视觉模型:
qwen3-vl-flash—— 阿里云百炼(DashScope)开箱即用的轻量多模态视觉模型, 对中文数学/几何题图里的数字标注识别稳定,速度与成本兼顾。vision_kit 已针对 OpenAI 兼容协议 做了参数化调用, 直接通过环境变量指定即可,无需改代码。 若你更喜欢智谱的glm-4v-flash:把VISION_API_BASE换成https://open.bigmodel.cn/api/paas/v4、VISION_MODEL换成glm-4v-flash, 并记得把VISION_MAX_TOKENS同步改回1024(glm-4v-flash 上限是 1024,见下方「参数调优」)。 下面示例默认使用 DashScope(阿里云百炼)兼容端点。
# 克隆后,在仓库根目录执行
pip install -e . # 安装(openai / pillow / mcp)
export VISION_API_KEY=你的Key # 填你在阿里云百炼创建的 SK- 开头 Key
# 下面两个是可选默认值(官方 DashScope 端点 + qwen3-vl-flash),不设也能用:
export VISION_API_BASE=https://dashscope.aliyuncs.com/compatible-mode/v1 # 可选
export VISION_MODEL=qwen3-vl-flash # 可选
from vision_kit import VisionClient
client = VisionClient(api_base="https://dashscope.aliyuncs.com/compatible-mode/v1",
api_key="你的Key", model="qwen3-vl-flash")
text = client.describe("题目图.png") # 渲染文本(供 LLM 注入)
data = client.describe_structured("题目图.png") # 结构化 dict
需要先安装吗?
vision_kit 把仓库根目录映射为包根(pyproject.toml 的 package-dir: vision_kit = ".")。
有两种使用方式,按需选一种即可:
- 推荐(CLI / MCP 最省事):
pip install -e .安装一次,之后任意目录都能python -m vision_kit.*。 - 也可以不安装:把仓库目录加入环境变量
PYTHONPATH后直接import vision_kit(DSH 插件的visionKitDir就是这么用的)。
两者二选一即可,不必都做。 若既没安装、又没设 PYTHONPATH,python -m vision_kit.cli 会报"找不到模块"。
命令行(供插件 / 脚本调用)
python -m vision_kit.cli 题目图.png --mode describe # 自然语言描述 / 问答
python -m vision_kit.cli 题目图.png --mode extract # 结构化识别(JSON)
python -m vision_kit.cli 题目图.png --mode both
# 或安装后:vision-kit-cli 题目图.png --mode extract
输出单行 JSON:{"ok": true, "mode": "extract", "result": {...}},失败时 {"ok": false, "error": "..."} 且退出码 1。
凭证读取环境变量 VISION_API_KEY / VISION_API_BASE / VISION_MODEL / VISION_TIMEOUT / VISION_MAX_TOKENS(与 MCP 服务器一致)。
试着跑一下(最快验证)
# 在仓库根目录(这样能找到自带的 test_figure.png)
python -m vision_kit.cli test_figure.png --mode extract
注意:
test_figure.png是本仓库自带图。用全局插件 / 在自己项目里跑时,工作区里没有它, 请换成你自己的图片路径,或先cd到仓库根目录再跑。图片路径按当前工作目录解析。
opencode 视觉插件(推荐)
给 coding agent 一双“眼睛”:无需切换多模态模型,任意文本模型也能看图。
提供两个工具
| 工具 | 作用 |
|---|---|
vision_describe | 看一张图,返回中文描述,或回答关于图的具体问题(传入 prompt) |
vision_extract | 结构化识别图中的数字标注:向量 / 矩阵 / 坐标 / 角度,带维度校验与补漏重试 |
安装
插件是放在插件目录的 JS 文件,opencode 启动时自动加载(无需改配置):
# 前提:先克隆本仓库,并使用仓库根目录的 .opencode/plugins/vision-kit.js
# 项目级(只在该项目生效):先创建目标插件目录(若不存在)再复制
mkdir -p <你的项目>/.opencode/plugins
cp .opencode/plugins/vision-kit.js <你的项目>/.opencode/plugins/
# 全局(所有项目生效):
mkdir -p ~/.config/opencode/plugins
cp .opencode/plugins/vision-kit.js ~/.config/opencode/plugins/
上面的
cp需要在仓库根目录执行。若只想要插件、不用整个库,直接拷贝那个单文件即可, 插件运行时会调用python -m vision_kit.cli,所以目标机器仍要能import vision_kit(见「要不要 pip install」)。
凭证(按优先级)
- 环境变量
VISION_API_KEY/VISION_API_BASE/VISION_MODEL/ … - opencode 配置
mcp["vision-kit"].env(全局~/.config/opencode/opencode.json或项目.opencode/opencode.json,即 opencode.example.json 中的写法)
无需重复填 Key:只要你的 opencode 配置里已有 vision-kit MCP,插件自动复用同一组凭证。
到底该在哪儿填 Key?一张表说清(避免到处都填乱):
| 你要用 | 该在哪儿配 | 说明 |
|---|---|---|
| opencode 插件 | opencode 配置 mcp["vision-kit"].env 的 VISION_API_KEY | 插件自动复用,最省事 |
| CLI / MCP 服务器 | 环境变量 VISION_API_KEY(或 opencode.json env) | 运行前 export 或写在 env |
| DSH 插件 | vision.config.json 的 apiKey | 见下方 DSH 章节 |
三处配同一个 Key 即可,不必每处都填;按你实际用的接入方式配对应那一个地方就够。
实现方式
插件不重复实现任何视觉逻辑:调用 python -m vision_kit.cli,完全复用本项目的图片预处理、结构化识别、维度校验、补漏重试与超大图分块。插件本身只负责路径解析(相对路径基于会话目录)、凭证注入与结果格式化。
试一下
opencode run "用 vision_describe 看一下 test_figure.png,告诉我图里有哪些向量"
opencode run "用 vision_extract 提取 test_figure.png 中的结构化数据"
test_figure.png 是本仓库自带的一张向量题示例图,在仓库根目录。
用全局插件 / 在别的工作区跑时,请换成你自己图片的绝对路径。
opencode MCP 服务器
python -m vision_kit.mcp_server # 或安装后:vision-kit-mcp
通过 opencode.example.json 接入 opencode(DashScope qwen3-vl-flash 示例)。
DeepSeek Harness 视觉插件
与 opencode 版同源的 DSH 动态 Cordis 插件(dsh-plugin/vision-kit.dsh.js),
给 DSH 的任意文本模型一双“眼睛”:注册 vision_describe / vision_extract 两个模型工具,
通过 python -m vision_kit.cli 复用本项目的全部视觉逻辑。
vision_extract 额外把 几何自洽校验 结果(geo_checks)返回给模型:三角形内角和、向量加法关系、
矩阵乘法维度、负值等,任一不通过会触发采样重试,重试耗尽后逐条展示 ✗ 不通过,让文本 agent 能察觉"读数自相矛盾"而非盲信。
首次配置(必须)
DSH 插件从仓库根的 vision.config.json 读取视觉凭证。出于安全考虑,这个文件不会被项目分发,需要你在自己机器上创建一份:
# 在仓库根目录
cp vision.config.example.json vision.config.json
# 然后编辑 vision.config.json,填入:
# apiKey —— 你在阿里云百炼创建的 SK- 开头 Key(必填)
# python —— (建议)你的 python.exe 绝对路径
# visionKitDir—— 本仓库根目录的绝对路径(插件据此定位 cli.py 与 vision.config.json)
- 模板 vision.config.example.json 不含密钥,可放心参考。
- ⚠️
vision.config.json保存的是你的 API Key,参考项目配置即可,不要把它分享/上传。 - 插件自动定位项目目录:优先读
VISION_KIT_DIR环境变量,其次从当前工作目录探测; 都定位不到时会报错,并按模板引导你去配visionKitDir。
安装与启用
DSH 动态插件不随重启保留(它是纯 JS 字符串,不在独立文件里被自动加载):
把 dsh-plugin/vision-kit.dsh.js 中的 return { … } 作为 cordis_define 的 code.host 重新定义,
再 cordis_run 激活即可,工具立即出现在当前会话的模型工具集中。
路径
image_path 支持相对路径(基于调用方会话工作区)或绝对路径。
样例图的模型说明(重要)
README 各处"试一下"用的 test_figure.png 识别结果,是按默认模型 qwen3-vl-flash(DashScope)标定的。
不同视觉模型对同一张图的抽取可能有细微差异,若你换成 glm 等,结果可能不完全一致,属正常现象。
试一下
用 vision_describe 看一下 test_figure.png,告诉我图里有哪些向量
用 vision_extract 提取 test_figure.png 中的结构化数据
test_figure.png在本仓库根目录。用全局插件 / 在别的工作区跑时,请换成你自己图片的绝对路径。
环境变量
| 变量 | 必填 | 默认 |
|---|---|---|
VISION_API_KEY | 是 | - |
VISION_API_BASE | 否 | https://dashscope.aliyuncs.com/compatible-mode/v1 |
VISION_MODEL | 否 | qwen3-vl-flash |
VISION_TIMEOUT | 否 | 60 |
VISION_MAX_TOKENS | 否 | 8192(qwen3-vl-flash 上限) |
VISION_KIT_DIR | 否 | 无。DSH 插件项目目录 + PYTHONPATH;插件优先读它定位项目,未设置则自动探测/按模板引导配置 |
参数调优建议
环境变量与引擎常量已给出合理默认值,大多数场景无需改动。若你有特定需求,可按下面调整:
关于 max_tokens
- 默认
8192是qwen3-vl-flash的上限。视觉结构化输出通常是短 JSON(向量/矩阵/说明), 实际用量往往只有几百到一两千 token —— 所以即使调小到1024~2048也极少截断,还能稍微降成本。 - 若一次要返回很大的矩阵、或图内文字很多,担心被截断,就保留
8192;需要更多才另说。 - ⚠️ 换模型时务必同步改这个值:推荐默认按 qwen3-vl-flash(上限 8192),
若改用智谱
glm-4v-flash,其上限 只有 1024,用 8192 会直接报参数超限 —— 记得VISION_MAX_TOKENS=1024。
针对不同使用倾向
| 你的诉求 | 建议调整 | 说明 |
|---|---|---|
| 更准(容忍慢) | VISION_TIMEOUT 调大,如 120 | 图片预处理+补漏重试+分块可能较慢,超时太紧会误判失败 |
| 更省成本 | VISION_MAX_TOKENS 调到 1024~2048 | 结构化输出普遍够用,可减少付费 token 溢出浪费 |
| 图很小/字很密 | 调大引擎 MIN_DIM(engine.py,默认 1000) | 小图自动放大,放大得越足数字越清楚 |
| 超大图(会分块) | 调小引擎 MAX_TILE_SIDE(默认 1600) | 块越小单模型压力越小,但块变多、开销变大 |
| 补漏更彻底 | 调大引擎 MAX_ATTEMPTS(默认 3) | 维度/几何校验不通过时重试次数,越多越稳但越慢 |
环境变量(
VISION_*)通过 CLI / MCP / opencode 插件的 env 直接改即可,无需动代码; 引擎常量(MIN_DIM/MAX_TILE_SIDE/MAX_ATTEMPTS等)在engine.py顶部修改后重新调用即可。
开发
pip install -e ".[dev]"
pytest # 单元测试(tests/)
ruff check . # 代码质量
项目结构
vision_kit/
├── __init__.py # 包入口,导出 VisionClient
├── client.py # VisionClient:放大预处理 / 结构化 / 分块 / 重试
├── engine.py # 识别引擎:提示词、参数化调用、维度/几何校验重试、2x2 分块
├── figure.py # FigureData:向量/矩阵解析 + 维度一致性校验 + 几何自洽校验 + 渲染
├── geometry.py # 几何自洽校验:三角内角和 / 向量加法 / 矩阵维度 / 负值(纯逻辑)
├── cli.py # 命令行 JSON 入口(视觉插件 / 脚本调用)
├── mcp_server.py # opencode MCP 服务器(stdio)
├── opencode.example.json
├── vision.config.example.json # DSH 插件配置模板(不含 Key,可直接用)
├── vision.config.json # 本机视觉凭证(由模板复制后填写,属本地文件,不随项目分发)
├── .gitignore # 已排除 vision.config.json 等本地文件
├── dsh-plugin/
│ └── vision-kit.dsh.js # DeepSeek Harness 视觉插件(cordis 动态插件源码)
└── .opencode/
└── plugins/vision-kit.js # opencode 视觉插件(见上文)