news 2026/9/26 17:01:44

Go+AI Agent实战:一张商品图生成整套电商详情页

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Go+AI Agent实战:一张商品图生成整套电商详情页

1. 为什么我盯上了"一张商品图生成整套详情页"这件事

做电商的朋友应该都有体会,详情页是个磨人的活儿。一张主图拍完,运营要写卖点文案、设计要排版、美工要抠图换背景、最后还要拼成一套符合平台规范的详情页长图。一个 SKU 走完这套流程,快的话半天,慢的话两三天,SKU 一多,人力成本直接爆炸。

我最早的想法很朴素:能不能让 AI 把"写文案"和"排版"这两步自动化?后来发现市面上的工具要么是纯文案生成(生成完还得手动排版),要么是纯设计工具(模板套用,文案还得自己填),中间那道"从图到成品"的缝一直没人缝上。于是我就琢磨着用 Go 搭一条 AI Agent 流水线,把整条链路串起来:输入一张商品图,输出一整套可以直接用的详情页素材。

这条流水线涉及几个核心关键词:Go、AI Agent、Wails、Vue3、GLM-4.6V。Go 负责后端调度和 Agent 编排,Wails 把 Go 和 Vue3 打包成一个桌面应用,Vue3 做前端交互界面,GLM-4.6V 这个多模态模型负责"看图说话"——识别商品、提取卖点、生成文案。整套东西跑下来,从上传图片到拿到详情页,大概两三分钟。

这篇文章我会把整条流水线的设计思路、Agent 编排逻辑、Wails 集成踩的坑、GLM-4.6V 的调用细节全部摊开讲。适合两类人看:一是想用 Go 做 AI Agent 应用开发但不知道从哪下手的,二是做电商工具、想了解多模态模型怎么落地到具体业务场景的。代码和配置我会尽量给全,能抄作业的地方直接抄。

先说清楚一个概念,很多人搞不清AI Agent 和 LLM 的区别。LLM(大语言模型)是"大脑",你问它答,它本身不会主动做事;AI Agent 是"大脑 + 手脚 + 记忆",它能自己决定调用什么工具、按什么顺序执行、失败了怎么重试。我这条流水线里,GLM-4.6V 是那个大脑,Go 写的调度器是手脚,中间的任务状态管理是记忆。理解了这层关系,后面的设计就顺了。

2. 整条流水线的骨架:Agent 到底分几步干活

2.1 把"生成详情页"拆成四个可独立执行的 Agent

一开始我想用一个超级 Prompt 让模型一步到位,结果发现根本不可控——模型要么漏掉卖点,要么排版乱套,而且一旦中间某步出错,整个流程得重来。后来我改成"分而治之",把任务拆成四个职责单一的 Agent:

Agent 名称职责输入输出
视觉理解 Agent识别商品类别、颜色、材质、场景商品原图结构化商品描述 JSON
卖点提炼 Agent基于商品描述生成营销卖点商品描述 JSON5-8 条卖点文案
文案生成 Agent生成标题、副标题、详情段落卖点列表完整文案包
排版组装 Agent按模板把文案和图片拼成详情页文案包 + 原图详情页长图

这么拆的好处是每个 Agent 的 Prompt 都能写得非常聚焦,输出格式也好约束。比如视觉理解 Agent 我只让它输出 JSON,不让它写任何自然语言段落,这样下游解析起来零歧义。

2.2 为什么用 Go 做编排而不是 Python

很多人做 AI 应用第一反应是 Python,生态确实好。但我选 Go 有几个实在的理由:第一,这条流水线要打包成桌面应用给运营用,Go 编译出来是单个二进制,Wails 直接能嵌,Python 打包成 exe 那个体积和启动速度你懂的;第二,Agent 编排本质是并发调度,Go 的 goroutine 写起来比 Python 的 asyncio 顺手太多;第三,我要调多个模型接口,Go 的 HTTP 客户端和超时控制更干净。

具体到编排层,我用了一个简单的 DAG(有向无环图)结构。每个 Agent 是一个节点,节点之间有依赖关系。视觉理解是根节点,卖点提炼依赖它,文案生成依赖卖点提炼,排版组装依赖文案生成。用 Go 实现就是一个带 channel 的调度器:

type AgentNode struct { Name string Run func(ctx context.Context, input map[string]any) (map[string]any, error) Depends []string } type Pipeline struct { nodes map[string]*AgentNode done map[string]chan map[string]any }

每个节点跑完把结果塞进自己的 channel,下游节点从依赖的 channel 里取数据。这样天然支持并行——比如以后我想加一个"竞品分析 Agent"和"卖点提炼 Agent"并行跑,改依赖关系就行,不用动调度逻辑。

2.3 任务状态怎么存:别小看这一步

Agent 流水线最怕的就是"跑到一半挂了,不知道跑到哪了"。我一开始图省事把状态放内存里,结果应用一崩全丢,用户得从头再来。后来改成用 SQLite 落盘,每个 Agent 的执行状态、输入、输出、耗时都记一张表:

CREATE TABLE agent_runs ( id INTEGER PRIMARY KEY, task_id TEXT, agent_name TEXT, status TEXT, -- pending/running/success/failed input_json TEXT, output_json TEXT, error_msg TEXT, started_at DATETIME, finished_at DATETIME );

有了这张表,断点续跑就简单了——重新执行时先查哪些节点已经 success,直接跳过。这个设计在调试阶段帮了我大忙,某个 Agent 输出不对,我直接看表里的 output_json 就知道问题出在哪,不用加一堆日志重新跑。

提示:状态落盘别用 JSON 文件,并发写会出问题。SQLite 开 WAL 模式,单机场景完全够用,比上 Redis 省事。

3. GLM-4.6V 怎么用才不浪费:多模态调用的实战细节

3.1 视觉理解 Agent 的 Prompt 设计

GLM-4.6V 是这条流水线的核心,它决定了后面所有环节的质量。我踩的第一个坑就是 Prompt 写得太"开放",比如"请描述这张商品图",模型会给你写一段散文,什么"画面中呈现出一件精美的...",这种输出下游根本没法解析。

正确的做法是强约束输出格式。我最终的 Prompt 是这样的:

你是一个电商商品分析助手。请分析这张商品图片,严格按以下 JSON 格式输出,不要输出任何其他内容: { "category": "商品类目", "color": ["主色", "辅色"], "material": "材质推测", "style": "风格标签", "scene": "使用场景", "target_user": "目标人群", "key_features": ["外观特征1", "外观特征2"] }

关键是最后那句"不要输出任何其他内容"。即便这样,模型偶尔还是会加个"好的,以下是分析结果:"的前缀。所以我在 Go 侧做了解析容错——用正则先提取第一个{到最后一个}之间的内容,再反序列化。这个容错逻辑看起来土,但实测比任何"请严格输出 JSON"的咒语都管用。

3.2 图片怎么传:base64 还是 URL

GLM-4.6V 支持两种图片传入方式:base64 编码和图片 URL。我两种都试过,结论是本地图片用 base64,网络图片用 URL。base64 的坑在于体积——一张 2MB 的图编码后接近 2.7MB,请求体一大,超时概率直线上升。我的处理是在 Go 侧先压缩:把图片长边压到 1024px,质量降到 85%,这样一张图通常能压到 200KB 以内,识别效果几乎没损失。

func compressImage(src string) ([]byte, error) { img, err := imaging.Open(src) if err != nil { return nil, err } // 长边限制 1024 img = imaging.Fit(img, 1024, 1024, imaging.Lanczos) var buf bytes.Buffer err = imaging.Encode(&buf, img, imaging.JPEG, imaging.JPEGQuality(85)) return buf.Bytes(), err }

这里用的是github.com/disintegration/imaging,轻量好用。压缩这步千万别省,我做过对比,不压缩的请求失败率大概 8%,压缩后降到 1% 以下。

3.3 多模态模型的"幻觉"怎么防

多模态模型有个通病:你问它材质,它看图猜不出来也会硬编一个。比如一件纯棉 T 恤,它可能说成"涤纶混纺"。这种幻觉在电商场景是致命的,写进详情页就是虚假宣传。

我的应对策略是区分"看得见的"和"猜的"。Prompt 里明确要求:颜色、外观特征这类肉眼可见的必须准确;材质、成分这类看不见的,如果无法确定就填"未知",不要编。同时在 Go 侧加了一层校验——如果material字段是"未知",文案生成 Agent 就跳过材质相关的卖点,不硬写。

这个设计思路其实适用于所有多模态落地场景:让模型只做它擅长的事,不确定的部分交给规则兜底。指望模型百分百准确是不现实的,工程上的价值在于把它的不确定性控制在可接受范围内。

4. Wails + Vue3 把流水线装进桌面应用

4.1 为什么是 Wails 而不是 Electron

Electron 打包出来动辄一两百 MB,启动还慢。Wails 的思路是"Go 做后端 + 系统 WebView 做前端",打包出来通常 10-20MB,启动秒开。对于我这种"后端逻辑重、前端只是操作界面"的场景,Wails 简直量身定做。

Wails 的核心机制是绑定:你在 Go 里定义一个 struct,把方法暴露出去,前端 Vue3 里就能直接await调用,像调本地函数一样。比如我的流水线入口:

type App struct { ctx context.Context pipeline *Pipeline } func (a *App) GenerateDetailPage(imagePath string) (string, error) { return a.pipeline.Run(a.ctx, imagePath) }

前端就这么调:

import { GenerateDetailPage } from '../wailsjs/go/main/App' const result = await GenerateDetailPage('/path/to/image.jpg')

没有 HTTP 接口、没有跨域、没有序列化烦恼,数据直接在进程内传递。这是 Wails 相比"Go 起个 HTTP 服务 + 前端 fetch"最大的优势。

4.2 Vue3 前端的状态管理:别把 Agent 进度搞丢

流水线跑起来要两三分钟,用户得能看到进度。我在 Vue3 侧用 Pinia 管理任务状态,每个 Agent 的状态变化通过 Wails 的 Events 机制从 Go 推送到前端:

// Go 侧推送事件 runtime.EventsEmit(a.ctx, "agent:progress", map[string]any{ "agent": "视觉理解", "status": "running", "progress": 25, })
// Vue3 侧监听 import { EventsOn } from '../wailsjs/runtime/runtime' EventsOn('agent:progress', (data) => { taskStore.updateAgentStatus(data.agent, data.status, data.progress) })

这里有个坑:Wails 的事件是异步的,如果前端组件卸载了但事件还在推,会报错。我的做法是在onUnmounted里把监听器取消掉,或者用 Pinia 的 store 承接事件,组件只读 store,这样组件卸载也不影响。

4.3 打包时最容易翻车的几个点

Wails 打包我踩的坑能写一篇。第一个是WebView2 依赖,Windows 上如果用户系统没装 WebView2 Runtime,应用直接白屏。解决办法是在安装包里带上 WebView2 的引导安装,或者检测到缺失时提示用户。第二个是资源路径,开发时图片路径是相对路径,打包后工作目录变了,得用os.Executable()拿到二进制位置再拼绝对路径。第三个是图标和版本信息,Wails 的wails.json里配置,别等打包完才发现图标是默认的。

注意:Wails 打包前一定要在干净环境测一遍,尤其是没装过开发环境的机器。我遇到过开发机跑得好好的,换台机器就白屏,最后发现是 WebView2 版本太老。

5. 从"能跑"到"好用":那些只有真跑起来才知道的事

5.1 并发调用模型接口的限流

流水线里四个 Agent 串行跑,但每个 Agent 内部可能有多张图要处理(比如一个商品有主图、细节图、场景图)。如果无脑并发,很容易触发模型接口的 QPS 限制。我在 Go 侧加了个简单的令牌桶限流:

limiter := rate.NewLimiter(rate.Limit(5), 10) // 每秒5个,突发10个 func callModel(ctx context.Context, req Request) (Response, error) { if err := limiter.Wait(ctx); err != nil { return Response{}, err } // 实际调用 }

用golang.org/x/time/rate就行,几行代码解决。限流阈值要根据你实际购买的接口配额调,别照抄我的 5。

5.2 失败重试的"度"怎么把握

模型接口偶尔超时、偶尔返回格式错误,重试是必须的。但重试不能无脑重试——我见过有人写个for i := 0; i < 10; i++死循环重试,结果接口挂了直接把配额刷爆。

我的策略是指数退避 + 最大次数 + 区分错误类型。超时、5xx 这类可重试,重试间隔 1s、2s、4s;格式解析错误这类不可重试,直接失败让上游处理。最大重试 3 次,超过就标记该 Agent 失败,走降级逻辑(比如视觉理解失败就用默认模板文案)。

func retryWithBackoff(fn func() error, maxRetries int) error { for i := 0; i < maxRetries; i++ { err := fn() if err == nil { return nil } if !isRetryable(err) { return err } time.Sleep(time.Duration(1<<i) * time.Second) } return fmt.Errorf("重试 %d 次后仍失败", maxRetries) }

5.3 成本控制:别让流水线变成烧钱机器

多模态模型按 token 计费,图片也占 token。一条流水线跑下来,如果图片不压缩、Prompt 不精简,成本能差好几倍。我做了几件事:图片压缩(前面说过)、Prompt 复用(把不变的指令部分做成常量,只拼可变部分)、结果缓存(同一张图算过的视觉理解结果存下来,重复上传直接读缓存)。

缓存这块用图片的 MD5 做 key,存 SQLite。实测下来,运营反复调整文案时,视觉理解这步基本都命中缓存,省了一大笔。

5.4 输出质量的人工兜底

再好的模型也有翻车的时候。我在前端加了个"人工审核"环节——流水线跑完不直接导出,而是把生成的文案和排版展示出来,运营可以逐条编辑、替换、删除,确认无误再导出。这个设计看起来是"AI 不够智能"的妥协,但实际上极大提升了可用性。运营反馈说,有了这个环节,他们敢用了,因为知道最终把关的还是自己。

6. 这套架构还能往哪扩

跑通这条流水线之后,我发现这套"Go 编排 + 多模态 Agent + Wails 桌面端"的架构其实很通用。往小了说,把视觉理解 Agent 换成"文档解析 Agent",就能做合同摘要工具;把排版组装 Agent 换成"PPT 生成 Agent",就能做自动做汇报材料。往大了说,Agent 之间的依赖关系可以更复杂,加个"质量评分 Agent"做自动质检,加个"多方案生成 Agent"一次出三版让用户选。

我最近在试的一个方向是把 Agent 做成可插拔的——每个 Agent 定义成接口,用户可以在配置里自由组合。这样同一套壳子,换个 Agent 组合就是另一个产品。Go 的接口机制做这个天然合适:

type Agent interface { Name() string Depends() []string Execute(ctx context.Context, input map[string]any) (map[string]any, error) }

只要实现这个接口,就能塞进流水线。这个设计我还在打磨,等稳定了再单独写一篇。

最后分享一个我踩了很久才想明白的点:AI Agent 项目的难点从来不在模型调用,而在工程化。模型接口谁都会调,但怎么让整条链路稳定、可观测、可恢复、成本可控,这才是真正拉开差距的地方。我这条流水线里,真正花时间的代码是状态管理、重试、限流、缓存这些"不性感"的部分,模型调用反而只占很小一块。如果你也在做类似的东西,别一上来就纠结用哪个模型,先把工程骨架搭扎实,模型随时能换,骨架换起来可就伤筋动骨了。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/26 17:01:04

HyperDown网盘下载加速:绕开限速的原理与实操指南

1. 为什么需要HyperDown&#xff1a;网盘限速问题的技术拆解作为一个常年和各种大文件、资源包、压缩档打交道的下载重度用户&#xff0c;你一定对百度网盘那个“下载速度几十KB/s”的经典画面不陌生。尤其是在没有开通会员的情况下&#xff0c;一个2GB的学习资料包能拖上好几个…

作者头像 李华
网站建设 2026/9/26 17:00:50

嵌入式Linux基础

第1章 Linux是一种性能优良、源码公开、多用户、多任务操作系统&#xff0c;目前主要运用在大型服务器领域、网络处理应用和嵌入式系统。为了加强在嵌入式系统领域的优势&#xff0c;Linux 2.6已经在内核中加入了提高中断性能和调度响应时间的改进&#xff0c;加入了对多种微控…

作者头像 李华
网站建设 2026/9/26 17:00:47

Nexus vs Hadess:制品管理工具选型与容器镜像仓库对比

1. 先别急着比工具&#xff1a;制品管理工具到底在管什么"制品管理工具"这几个字听起来很后端&#xff0c;实际上天天跟前端、后端、运维、测试都打交道。我之前在一家公司同时跑着 Java、Node、Python 三条业务线&#xff0c;第一周就发现&#xff1a;Jenkins 构建完…

作者头像 李华
网站建设 2026/9/26 16:59:21

SSM+Django混合架构:订餐管理系统全栈实战与调试指南

1. 为什么选订餐管理系统&#xff1a;一个能打通全栈的项目选题 每年毕业季和课程设计高峰期&#xff0c;我都能在技术社区看到大量关于“做什么选题”的求助帖。我的建议一直很明确&#xff1a; 选一个业务闭环完整、技术栈覆盖全面、演示效果直观的系统 。订餐管理系统恰好…

作者头像 李华
网站建设 2026/9/26 16:56:25

从零开始用Docker Compose部署Cloudreve,打造你的私人云盘

最近好几个朋友跑来问我&#xff0c;说网盘空间越来越少&#xff0c;下载还限速&#xff0c;想把文件放在一个真正属于自己的私人云盘里。其实这件事真没有想象中那么高门槛&#xff1a;你不需要专门买一台昂贵的NAS&#xff0c;只要手头有一台能跑Docker的Linux机器&#xff0…

作者头像 李华
网站建设 2026/9/26 16:56:13

Jev:给AI编程助手装一个决策层,让Claude Code和Codex先想再做

最近调 AI Coding Agent 调得比较多&#xff0c;Claude Code 和 Codex 这两个命令行工具给我的感觉是&#xff1a;下限很高&#xff0c;但上限全靠“你能不能把任务说清楚”。你跟它说“帮我重构一下登录模块”&#xff0c;它真可能把整个文件给你重写一遍&#xff1b;你跟它说…

作者头像 李华