ARTICLE DETAIL

资讯详情

深耕网站视觉设计与运营推广的一线实战洞察。

Agent Skill 实战:用 /show-me 将图像转换为紧凑视觉表示

Agent Skill 实战:用 /show-me 将图像转换为紧凑视觉表示 先抛一个很多 AI 应用开发者都会遇到的问题当你的 Agent 需要描述一张界面截图、一个架构图或一份数据图表时直接把位图塞进上下文既浪费 token又未必能让模型真正抓住关键信息。而最近在 Hacker News 上引起讨论的/show-me这个 agent skill给出的方向很干脆让 Agent 输出紧凑的视觉表示而不是图像本身。这个思路的价值不在于“能画图”而在于它重新定义了 Agent 在上下文里处理和传递视觉信息的方式。这篇文章会分几条线展开先讲清楚/show-me到底解决什么问题再把 agent skill 和 MCP 这两个容易混淆的概念对比明白然后用可落地的示例演示 compact visual representations 的生成与调用最后给出贴近真实项目的使用建议和排查方法。如果你正在做 Agent 应用、自动化测试工具、智能文档或数据可视化相关的工作这篇文章值得读完并收藏。1. 这篇文章真正要解决的问题先说一个反常识的判断Agent 应用里最贵的往往不是模型推理而是上下文。尤其当任务涉及“看”的时候比如让 Agent 分析网页截图、识别图表趋势、检查 UI 还原度、总结论文里的结构图开发者通常会选择把图片转成 base64 或 Markdown 图片链接塞给模型。这样做当然能用但问题很现实一张普通截图在视觉模型里可能消耗上千 token而且模型对图片里的视觉噪声并不敏感背景色、字体、布局偏移都会干扰判断。/show-me这个技能走的是一条相反的路径先让模型理解图像内容然后生成一份结构化、紧凑、可文本化表达的视觉表示比如 SVG、ASCII 图、树形结构、坐标标注列表或步骤说明。这样一来Agent 后续的规划、记忆、多轮对话和工具调用都可以基于这份紧凑表示进行而不是反复读取原图。那它解决了哪些具体问题大致可以分为三类上下文成本。紧凑的文本表示通常只需要原图 1/10 甚至更少的 token在多轮任务里能明显降低费用和延迟。信息保留能力。图片进入模型后是一种高维隐式表示Agent 难以在后续流程中“引用”某个局部区域但如果换成了带坐标、带标签的文本结构Agent 就可以精确地说“把左上角第二个模块的标题改成蓝色”。跨工具协同。紧凑的视觉表示可以被日志系统、前端渲染器、自动化测试框架直接消费而位图往往只能给人看机器很难做二次处理。因此这篇文章的核心读者是这些人在开发 Agent 工作流时被上下文长度困扰的工程师想让 AI 输出可视化结果而不是单纯输出文字描述的开发者以及正在评估 agent skill 与 MCP 两种扩展方式应该怎么选的架构师。2. 基础概念agent skill 与 compact visual representations2.1 agent skill 是什么Agent skill 这个概念可以理解为“赋予 Agent 的一项可复用能力”通常由一组提示词、示例、工具调用流程和输出约束组成。它比一个简单的 prompt 更结构化的地方在于skill 是可以在不同会话、不同任务中被反复加载的独立单元。举一个例子。你希望 Agent 能读取网页并总结内容可以写一段 prompt 让它完成但每次都要重新描述执行细节而如果做成一个 skill你只需要定义它包含哪些步骤、调用哪些工具、输出哪种格式。之后 Agent 在任何任务里发现需要“读网页”时都会自动加载这个 skill 并按规范执行。从工程视角看skill 的设计目标有三个可复用、低耦合、易维护。它把通用能力从具体业务逻辑中剥离出来类似代码里的函数或服务。一个 Agent 可以有多个 skill比如“代码检索”“浏览器操作”“图表生成”它们在任务中按需组合。2.2 compact visual representations 指的什么紧凑视觉表示核心思想是用最少的结构化信息保留视觉对象中最关键的空间、形状和语义特征。它不一定是一张图而可以是一段 SVG、一个数据表格、一组坐标、一段树状结构或 Mermaid 风格描述。重点在于让 Agent 能理解让程序能消费让人能快速浏览。为什么不用位图因为位图是像素的集合没有内在语义边界。模型虽然能看但 Agent 在文本上下文里无法“选中一个区域”或“引用一个组件”。而紧凑表示把视觉信息从连续信号变成了离散结构比如 SVG 中的rect、text、path天然带有坐标和层次关系ASCII 架构图则用字符保留下模块边界和连接关系。换句话说/show-me这种 skill 在回答“怎么让 Agent 学会看图”时给的答案是不要直接让 Agent 看原图而是让它先完成一次视觉到结构的转换再基于结构去思考。2.3 为什么现在这类 skill 开始流行背后有一个趋势Agent 正在从“聊天玩具”走向“自动化执行系统”。当 Agent 需要操作浏览器、操作设计稿、自动生成文档或执行测试时它必须能够理解视觉环境。而目前大多数 Agent 的能力边界是文本生成视觉输入的成本和稳定性仍然不理想。因此把视觉问题转化为结构问题成为一种更经济的中间方案。从/show-me这个项目的命名和定位来看它把能力暴露成一条斜杠命令让 Agent 内部可以随时调用。这个交互模式本身也反映出 agent skill 的典型特征不需要用户手动切换工具而是在对话中自然触发。3. agent skill 与 MCP 的区别和关系关于 agent skill 和 MCP 的区别最近讨论热度很高。MCP 是 Model Context Protocol即模型上下文协议它为 AI 应用连接外部工具和数据源提供了一套标准化接口。很多开发者会问如果有了 MCP是不是就不需要 skill 了答案是否定的。两者解决的问题完全不在一个层面。MCP 是“管道”负责让模型能调用外部资源比如查数据库、读文件、请求接口而 skill 是“方法”负责定义模型应该以什么流程、什么格式完成一类任务。MCP 偏向基础设施skill 偏向行为编排。用一个比喻来理解MCP 相当于是给 Agent 安装了各种“接口插座”比如数据库插座、GitHub 插座、浏览器插座而 skill 则是“操作说明书”告诉 Agent 在什么场景下插哪个插座、操作顺序是什么、输出结果长什么样。没有 MCPskill 拿不到外部数据没有 skillMCP 只是零散的连接能力Agent 不知道什么时候该用、怎么组合。两者在实现上也有明显差异接口粒度MCP 通常定义 server、tool、resource 等标准对象聚焦于传输和调用协议skill 则更灵活可以是纯提示词也可以包含多个工具调用模板。执行方式MCP 的工具调用一般由模型根据 tool schema 动态发起skill 则往往以整体任务单元的形式被 Agent 框架加载可能一次性注入多轮指令和示例。复用层级一个 MCP server 可以被多个 Agent 和多个 skill 共用一个 skill 内部也可能调用多个 MCP tool。部署方式MCP server 是独立服务进程需要监听请求skill 更多是以配置文件、代码模块或提示词模板的方式嵌入 Agent 应用。表格对比如下维度agent skillMCP本质行为能力的结构化封装模型与外部工具/数据源之间的通信协议解决的核心问题Agent 如何高质量完成一类任务Agent 如何安全、标准地访问外部能力具体形态提示词模板、流程定义、工具调用规则、示例集Server、Tool、Resource、Schema运行载体Agent 框架内部加载独立进程或服务复用范围任务级、场景级系统级、组织级典型例子网页截图分析、代码评审、图表生成数据库查询服务、文件系统操作、浏览器控制服务实际项目里两者更多是配合关系。一个成熟 Agent 应用通常用 MCP 打通工具链再通过 skill 把工具链组织成可复用的业务能力。用 MCP 暴露“读取图片”再用 skill 定义“读取图片后如何生成紧凑视觉表示并辅助决策”这才是完整方案。4. 环境准备与前置条件讲解完概念后进入实操部分。由于/show-me这类 skill 本身属于 Agent 应用层能力不同的 Agent 框架接入方式有一定差异因此这里以通用思路演示不绑定特定平台版本号也以实际项目为准。4.1 运行环境操作系统Windows 10/11、macOS、主流 Linux 发行版均可。运行语言Python 3.9 或 Node.js 18二选一即可。Agent 框架建议选择支持自定义 skill 的框架如 LangChain、LlamaIndex、Dify、Coze或自行实现轻量调度。模型服务需要能够理解图像输入的视觉模型例如 OpenAI 的 GPT-4o 系列或支持视觉输入的本地模型。4.2 依赖安装如果使用 Python在项目目录下创建虚拟环境并安装依赖。python -m venv venv source venv/bin/activate # Windows 下使用 venv\Scripts\activate pip install openai python-dotenv如果使用 Node.js可以这样初始化项目。mkdir show-me-demo cd show-me-demo npm init -y npm install openai dotenv4.3 配置文件准备将模型服务的密钥写入.env文件注意不要提交到 Git 仓库。OPENAI_API_KEYyour-api-key-here OPENAI_BASE_URLhttps://api.openai.com/v1 VISION_MODELgpt-4o如果使用国内模型服务或代理中转只需修改OPENAI_BASE_URL和模型名代码无需大改。这个兼容性设计也是推荐大家采用 OpenAI 兼容接口的原因。5. 核心流程拆解从图像到紧凑视觉表示要让 Agent 完成“看图并输出紧凑视觉表示”的任务核心流程可以分为五个环节。每个环节都有明确的输入和输出可以分别调试。5.1 图像预处理第一步是读取并规范输入图像。无论输入是截图、照片还是设计稿建议统一处理为模型容易理解的格式。常见做法是压缩图片并转成 JPEG 或 PNG如果图像过大先做等比缩放。这一步能减少传输和推理时间。5.2 视觉理解将图像交给视觉模型让模型描述图像中最重要的结构信息。这种描述不是自然语言长文本而是带有明确结构的中间表示。此时需要设计好提示词明确告诉模型它是在为“后续 Agent 任务”提取信息而不是在写看图作文。5.3 结构生成让模型把中间表示转换为目标格式。比如要求输出 SVG、JSON 布局、树状结构或 ASCII 图。这一步是 /show-me 类 skill 的关键决定了输出是否能被机器消费。最稳妥的办法是在 skill 定义中给出输出模板用几个示例把格式“锁死”。5.4 校验与修正生成结果后需要做一轮基本校验。对于 SVG检查标签是否闭合对于 JSON检查是否可解析对于坐标列表检查是否越界。很多模型输出一次可能不完美这一步的价值在于避免坏结构进入下游任务。5.5 下游消费最终输出的紧凑表示可以用于多种用途作为 Agent 后续判断依据写入日志供调试交给渲染器还原为可视化结果或作为自动化测试的期望值。这一步决定技能的实际价值。下面是流程示意图的文本版方便你在设计中把握各环节依赖关系输入图片 ↓ 图像预处理缩放、编码 ↓ 视觉模型理解提取结构信息 ↓ 结构生成SVG / JSON / ASCII / 坐标表 ↓ 校验与修正格式检查非法则重试 ↓ 下游消费Agent 决策 / 日志 / 渲染 / 测试断言6. 完整示例与代码实现6.1 示例一定义 skill 的清单文件假设我们要实现一个名为show-me的 skill它负责“读取图像并生成紧凑的布局描述”。在支持自定义 skill 的框架中通常会有一个 manifest 文件描述 skill 的元信息和工具调用规则。以下是一个示例结构实际字段名需要根据你使用的 Agent 框架调整# 文件路径skills/show-me/manifest.yaml name: show-me description: 将输入图像转换为紧凑的视觉结构表示输出 SVG 或 JSON 布局。 version: 0.1.0 capabilities: - image_to_structure steps: - name: validate_input description: 校验输入图像是否存在并读取图像基本信息。 - name: analyze_layout description: 调用视觉模型分析图像中的主要组件、坐标和层级关系。 - name: generate_output description: 根据分析结果生成目标格式的紧凑视觉表示。 max_retries: 2 output_formats: - svg - json - ascii这个清单文件的核心价值在于它让 Agent 在任务规划阶段就知道这个 skill 能做什么、输出什么格式从而决定是否调用以及如何解析结果。6.2 示例二Python 调用视觉模型生成结构表示以下代码演示了如何调用视觉模型把一个本地图片转换为 JSON 布局结构。注意这不是某个框架的官方 API而是 OpenAI 兼容接口的通用写法。# 文件路径show_me_demo.py import os import base64 import json from dotenv import load_dotenv from openai import OpenAI load_dotenv() client OpenAI( api_keyos.getenv(OPENAI_API_KEY), base_urlos.getenv(OPENAI_BASE_URL), ) VISION_MODEL os.getenv(VISION_MODEL, gpt-4o) def encode_image_to_base64(image_path: str) - str: with open(image_path, rb) as f: return base64.b64encode(f.read()).decode(utf-8) def generate_layout_structure(image_path: str) - dict: base64_image encode_image_to_base64(image_path) response client.chat.completions.create( modelVISION_MODEL, messages[ { role: system, content: ( 你是一个视觉结构提取引擎。 你的任务是从图像中提取关键组件的位置、尺寸和层级关系。 只输出 JSON不要输出任何解释性文字。 ), }, { role: user, content: [ { type: image_url, image_url: { url: fdata:image/png;base64,{base64_image} }, }, { type: text, text: ( 请提取这张图片的视觉布局结构 输出格式为 JSON包含 components 数组每个元素包含 id, type, x, y, width, height, text。 ), }, ], }, ], temperature0.2, ) raw_content response.choices[0].message.content # 防止模型输出包含外层 Markdown 代码块 if raw_content.startswith(): raw_content raw_content.strip() if raw_content.startswith(json): raw_content raw_content[4:] return json.loads(raw_content) if __name__ __main__: result generate_layout_structure(example_dashboard.png) print(json.dumps(result, ensure_asciiFalse, indent2))关键逻辑说明系统提示词中明确要求“只输出 JSON”降低了解析成本。图片通过 base64 内联传给模型避免上传临时文件。温度设低是为了让模型输出更稳定。6.3 示例三将结构转换为 SVG 的脚本拿到 JSON 布局后如果想要渲染出一个近似原图的 SVG可以用一个简单脚本完成。这个脚本在这里的作用是演示“结构即数据”的消费方式。# 文件路径generate_svg.py import json import sys def render_svg(layout: dict, width: int 800, height: int 600) - str: svg_parts [ fsvg xmlnshttp://www.w3.org/2000/svg fwidth{width} height{height} fviewBox0 0 {width} {height} ] for idx, comp in enumerate(layout.get(components, [])): kind comp.get(type, rect) x comp.get(x, 0) y comp.get(y, 0) w comp.get(width, 100) h comp.get(height, 50) text comp.get(text, fComponent {idx}) if kind in (text, label): svg_parts.append( ftext x{x} y{y 20} font-size14{text}/text ) else: svg_parts.append( frect x{x} y{y} width{w} height{h} ffill#f0f0f0 stroke#333 stroke-width1/ ) svg_parts.append( ftext x{x 4} y{y 20} font-size12{text}/text ) svg_parts.append(/svg) return \n.join(svg_parts) if __name__ __main__: layout_json sys.argv[1] if len(sys.argv) 1 else layout.json with open(layout_json, r, encodingutf-8) as f: layout_data json.load(f) svg_content render_svg(layout_data) with open(output.svg, w, encodingutf-8) as f: f.write(svg_content) print(SVG 已生成output.svg)这样一条完整的链路就通了原图进入视觉模型模型输出 JSON 布局脚本再将 JSON 渲染成 SVG。Agent 在后续对话中可以直接读取并讨论 JSON 里每个组件的坐标和属性不再需要反复查看原图。7. 运行结果与效果验证7.1 预期输出运行示例二后控制台应该输出类似如下的 JSON 结构{ components: [ { id: 1, type: header, x: 20, y: 20, width: 760, height: 60, text: Dashboard }, { id: 2, type: chart, x: 40, y: 100, width: 450, height: 300, text: Sales Chart }, { id: 3, type: sidebar, x: 520, y: 100, width: 240, height: 400, text: Filter Panel } ] }如果这个结构能成功提取说明视觉模型已经正确理解了图片的布局层级。再运行示例三会生成一个可打开查看的output.svg文件。7.2 如何判断成功判断标准有三个JSON 能够被json.loads正确解析没有多了外层 Markdown 或多余文字。components里的坐标和尺寸都在图片有效范围内不存在负数或明显越界。text字段与图片里的主要文案基本一致没有出现偏离主题的幻觉文本。7.3 如果失败先看哪里常见的失败点集中在三处。第一图片过大或过宽导致 token 消耗异常可以先压缩图片。第二模型没有严格按 JSON 输出这通常是提示词约束不够需要在 system 消息里增加“禁止输出代码块标记”等限制。第三部分组件重叠或缺失说明模型对复杂图片的理解粒度不够这时可以调整温度、增加 few-shot 示例或者先让模型分区描述再合并。8. 常见问题与排查思路在实际接入/show-me类 skill 时我建议按下面这个表格做预案。问题现象可能原因排查方式解决方案模型输出了非 JSON 内容提示词约束不足查看原始响应内容在 system 消息中增加“只输出 JSON”和“禁止 Markdown 代码块”约束图片分析结果不稳定温度设置过高检查 temperature 参数将温度调至 0.1-0.3 区间输出坐标明显不准图片压缩后比例被改变对比传入图片尺寸和输出坐标范围在提示词中指定图像原始宽高或在压缩时保持宽高比长图分析 token 超限图像过大或信息过密查看请求 token 用量先缩放图片或改用分区分析策略Agent 没有触发 skillskill 描述与任务不匹配检查 skill 的 description 字段优化触发描述加入更多同义词和场景词SVG 渲染结果缺失部分组件JSON 中组件过少检查模型输出和原图差异增加生成组件数量的提示比如“不要忽略页脚和侧边栏”其中最容易出问题的是第一项。很多开发者给模型的提示词不够强硬导致模型生成了一堆解释文字和 Markdown 包裹代码无法直接解析。一个有效做法是在调用后增加一层格式清洗函数把首尾无关字符去掉再进入 JSON 解析。但治本的方法还是在提示词里把输出格式“锁死”多给一个反面示例效果会更好。9. 最佳实践与工程建议如果你的项目打算把/show-me这类视觉表示能力做进生产环境有几个工程层面的建议很值得参考。9.1 上下文隔离与摘要策略紧凑视觉表示也不是越详细越好。对于一个复杂架构图如果输出几百个组件节点上下文压力依然很大。更合理的方案是分层设计第一层输出全局概览只有 Agent 需要查看某个局部区域时再调用一次视觉模型提取局部细节。这个“按需细化”的策略能有效控制整体 token 消耗。9.2 输出结构先做 Schema 约束不要依赖模型“每次输出都恰好是想要的结构”。在 skill 定义阶段就给出 JSON Schema 或示例模板并在校验阶段使用 Pydantic、Zod 等工具做强类型校验。一旦校验失败触发自动重试或降级到纯文本描述模式不要让坏数据进入下游。9.3 与 MCP 工具的配合方式如果项目同时使用了 MCP server一个推荐做法是MCP 负责图片读取和文件保存/show-me这个 skill 负责图像分析和结构生成。MCP tool 的输出直接作为 skill 的输入skill 生成的 SVG 或 JSON 再通过 MCP 写回文件系统或数据库中。这样职责清晰后续替换模型或调整 skill 逻辑时互不影响。9.4 日志与可观测性每次调用视觉模型时建议记录输入图像哈希、缩放尺寸、输出 token 数、生成结构大小、校验结果等元信息。这在排查 Agent 行为异常时非常有用。一个常见场景是用户发现 Agent 某个决策不合理但不知道它到底“看到了什么”此时如果日志里保存了当时的 JSON 布局结构就能快速还原 Agent 的输入搞清楚是视觉理解错了还是后续规划错了。9.5 安全边界与合规提醒如果图片包含敏感信息比如用户隐私截图、内部系统界面必须考虑数据脱敏。调用外部视觉模型前先对图像进行模糊、裁剪或区域屏蔽或优先选择私有化部署的视觉模型。同时生成的结构化数据可能仍保留敏感文本保存日志时也需要注意权限控制。涉及生产环境的数据处理链路建议遵循最小权限原则只让必要的服务访问原始图像和结构数据。10. 总结与后续学习方向写到这里可以回顾一下这篇文章真正讲清楚了几件事第一/show-me这类 agent skill 的核心不是画画而是将视觉信息转化为紧凑、可消费的结构表示让 Agent 在后续任务里能以文本方式“引用”视觉元素。第二agent skill 和 MCP 不是替代关系而是从任务编排和通信协议两个层面互补工程架构上应该各司其职。第三实现一个完整链路需要图像预处理、模型调用、结构校验和下游渲染四部分配合任何一环都能独立调试和优化。如果你正在做 Agent 类产品下一步最值得尝试的是先用一个最小 demo 跑通“截图 → JSON 布局 → SVG 渲染”的流程然后把它封装成自定义 skill接一个真实业务场景比如 UI 自动回归测试或智能文档生成。跑通之后再考虑加入 MCP server 管理图片输入输出逐步完善成生产级能力。关于compact visual representations的更多细节比如不同类型图表的语义抽取策略、多模态模型的选择基准、以及如何在长上下文中做视觉信息的增量更新都值得继续深入。建议把这篇作为起点继续关注 Agent 工程化领域里 skill 与 MCP 的演进方向这类实践型设计会越来越频繁地出现在真实项目里。
返回列表