
写技术文章时,配图常常很费时间——封面要概括主题,正文插图要对准段落,生成后还可能要改标题、比例或局部元素。
工具概览
这个工具暂命名为“博文视觉生成器”。上传 Markdown 后,可以运行“AI 智能规划配图”,也可以单独选全文或某段,生成封面或正文插图。
- 文本模型 :通过蓝耘 MaaS 接入 GLM5.3(控制台模型 ID 为
glm-5.3),负责理解文章、抽取主题与信息层级并生成视觉指令; - 视觉模型 :图像生成和编辑使用 Sense U1.5 Lite。

项目用 Vue 3 + Vite 开发,是纯前端、无业务后端。界面左右两栏:左边是博文文档区(上传、编辑、预览、选段),右边是视觉创作区(选封面/插图、风格与比例)。
整体调用链路如下:
Markdown 全文或选中段落
蓝耘MaaS · GLM5.3
理解内容、抽取主题与信息层级
生成视觉指令

商汤 · Sense U1.5 Lite
根据视觉指令生成封面或正文插图
图片编辑器
上传或复用生成结果
继续通过自然语言改图
一、模型服务选型与接入配置

1.1 选型考虑
项目在 Codex 里开发,前端又要调文本模型啃长文,所以接入方式、模型参数清晰度与排错便利性成了主要考量。蓝耘 MaaS 提供 OpenAI 兼容接口,能复用现有请求层,只换 base_url、api_key 与模型 ID 即可。
接入前我核对了这几个配置项:
- 接口协议 :文档给了 OpenAI 兼容调用示例。
- 模型字段 :确认上下文长度能否覆盖长文,并记下实际调用 ID glm-5.3。
- 模型切换方式 :同类兼容接口方便后续做对照测试。
- 密钥与用量查询 :API Key 按项目创建,资源包页可看剩余量。
图1 蓝耘接口文档

图2 蓝耘用量监控
图3 蓝耘模型列表
1.2 Codex 与 CC Switch 配置
日常用 Codex 偶尔额度见底,要靠 CC Switch 切到别的模型服务。CC Switch 能存多个供应商配置,在界面里切 Provider,顺手更新 Codex 的模型、端点与认证,不用手改配置文件。
Codex 用 ~/.codex/config.toml 存 Provider、模型与端点。对只给 OpenAI Chat Completions 的第三方服务,要开本地路由,把 Codex 的 Responses 请求转成上游支持的格式。

1.3 创建项目专用API Key
在 MaaS 控制台建一个仅限本项目的 API Key,确认模型 ID 是 glm-5.3,并核对 OpenAI 兼容基础地址。独立密钥便于隔离问题,测试完可停用。
图4 创建API Key
1.4 在CC Switch中配置Provider
CC Switch 里新增自定义 Provider,关键字段如下:

| CC Switch 字段 | 应填写的内容 | 说明 |
|---|---|---|
| Provider 名称 | 蓝耘-GLM5.3 |
仅用于识别 |
| Base URL | 控制台提供的OpenAI兼容基础地址 | 不是控制台网页地址 |
| API Key | 项目专用Key | 不提交到仓库 |
| 模型 | glm-5.3 |
实际调用ID |
| 接口格式 | 按接口文档选择 | 若只有Chat Completions,需打开本地路由 |
注意:开不开本地路由看上游接口格式,不看模型名。配完保存启用,检查 ~/.codex/config.toml 确认 model_provider、model、base_url 已更新。
图5 CC Switch配置
配置后进行连通性测试,确保接口可用。
图6 接口连通测试

1.5 验证Codex模型切换
切完 Provider 重开 Codex,给个不怎么费额度的具体任务,比如读 Vue 项目目录结构并给状态管理建议,验证 Codex 能否响应、模型名是否来自当前 Provider、项目上下文能否读取。
图7 Codex模型验证
图8 Codex理解项目
二、项目创建与初始化

2.1 创建项目
先用初始 Prompt 生成 Vue 3 + Vite 框架,后续多轮对话补页面布局、并行任务、图片编辑与错误重试。markdown-it 把 Markdown 转 HTML,dompurify 清理结果;生图与编辑请求统一放 src/services,页面组件只管状态与交互。
图9 输入初始Prompt
图10 追加开发Prompt
图11 项目目录结构

2.2 页面模型配置
右上角“模型配置”弹窗填写文本模型与图像模型的服务地址、接口路径、模型 ID 和 API Key;保存后写进 localStorage,页面顶部显示配置状态。
三、核心实现
3.1 文本模型做视觉策划,而非直接生图
直接让图像模型读全文,容易只抓到表面关键词。所以把“理解文章”和“生成图片”两步拆开:上传 Markdown 后提取标题与内容块,用户选全文或段落,再由 createImagePrompt 把选中内容、用途、比例和风格发给 GLM5.3 生成视觉指令。

核心调用(简化,省略错误处理):
const payload = {
model,
messages: [
{ role: 'system', content: visualDirectorPrompt },
{
role: 'user',
content: `请根据以下${scopeName}生成一条${targetName}指令。
文章标题:${documentTitle}
画面比例:${ratio}
视觉风格:${style}
--- 内容开始 ---
${source}
--- 内容结束 ---`,
},
],
temperature: 0.45,
stream: false,
}
visualDirectorPrompt 约束了输出:封面概括全文、插图解释段落;图中文字(标题、数字、技术名词)交给图像模型生成;只留一个主标题与不超过三项核心信息;描述构图、层级、配色与留白;不编造原文没有的事实;最终只返图像指令,不带解释或 JSON。

3.2 统一生图和改图工作流
右侧创作区没有把“智能生成”和“图片编辑”硬拆成两个页面。生成后可点“编辑图片”进入近全屏编辑器,也能先“编辑已有图片”上传本地图。
编辑器保留图片版本列表,编辑指令只说“要改什么”,比如“背景换成浅色网格,保留中间标题和流程结构”。编辑时把当前图片、修改要求与输出比例一起发过去。
文生图请求:
const payload = {
model,
prompt,
n: 1,
size: editSizeByRatio[ratio] || 'auto',
output_format: 'png',
response_format: 'b64_json',
watermark: true,
prompt_extend: true,
}

图片编辑请求(/images/edits):
const payload = {
model,
images: [{ image_url: imageUrl }],
prompt: instruction,
n: 1,
size: editSizeByRatio[ratio] || 'auto',
response_format: 'b64_json',
watermark: true,
prompt_extend: true,
}
前端不负责二次排字,视觉指令、原图和比例交给模型,标题与技术名词与画面一同生成。
四、实际遇到的问题与处理
4.1 本地开发CORS限制

页面直接请求图像接口会触发跨域错误,用 Vite 代理解决:
const sensenovaProxy = {
target: '
changeOrigin: true,
rewrite: (path) => path.replace(/^\/api\/sensenova/, ''),
}
export default defineConfig({
server: {
proxy: {
'/api/sensenova': sensenovaProxy,
},
},
})
请求层将目标地址改写为同源代理路径:
if (target.origin === ') {
return `/api/sensenova${target.pathname}${target.search}`
}

修改后生图和改图接口正常。注意此代理仅开发预览有效,公开部署需服务端配置反向代理或后端代调。
4.2 并行任务提升效率
最初一次只能处理一张图,整篇配图很慢。后来改成独立任务并行:先为每条建议建任务,立刻调用 executeTask,每个任务各自维护 prompting、generating、completed、failed 状态。
taskList.forEach((item) => {
const newTask = {
id: `task-${Date.now()}-${Math.random().toString(36).slice(2, 7)}`,
title: item.title,
status: 'pending',
}
tasks.value.unshift(newTask)
executeTask(newTask)
})

单个任务失败不阻塞别的。当前配图量小,直接并行够用;要大规模生成,后续可加并发上限与等待队列。
4.3 失败任务保留与重试
生图接口偶尔会网络中断或服务端报错。失败后不删任务,而是置为 failed 状态并给出错误信息,同时提供“重试”和“重新下发”按钮。
async function executeTask(task) {
task.status = 'prompting'
task.error = ''
try {
task.prompt = await createImagePrompt()
task.status = 'generating'
task.imageUrl = (await generateImage(task.prompt)).imageUrl
task.status = 'completed'
} catch (error) {
task.status = 'failed'
task.error = toErrorMessage(error)
}
}
function retryTask(taskId) {
const task = tasks.value.find(item => item.id === taskId)
if (task) executeTask(task)
}

重试沿用原文、类型、风格与比例,不用重填。目前整条链路重跑,后续可缓存已成功的视觉指令,只重试生图阶段。
五、效果实测
5.1 上传Markdown
上传含多章节、操作步骤与技术名词的 Markdown,程序能正确读出一级标题、字符数、文件大小与内容块数量。
图12 上传Markdown

界面分区清晰:顶部项目名和配置入口;中间左文档右视觉控制台;底部生图任务列表。文档区可在编辑和预览间切换。
5.2 AI智能策划全篇配图
点“AI 智能策划全篇配图”后,GLM5.3 通读全文,优先处理封面、核心流程、参数对比与操作重点,给出标题、理由及对应段落。
图13 全文配图方案
确认方案后,并行创建所有任务,每项任务独立生成视觉指令并调用图像接口。

图14 配图并行生成
任务卡片显示当前阶段和等待时间,图片完成后直接展示,并可展开查看视觉指令。
图15 配图生成完成
这次生成的封面与正文插图都能对应主题与具体段落,没退化成泛化背景图;并行任务里个别失败也不影响其余。
5.3 图片编辑
点击任务卡片中的“微调”或另行上传图片,用自然语言说明修改要求,无需重写整条生图提示词。
图16 图片编辑窗口
例如要求将画面右侧的平板改成两台(安卓平板和iPad),同时保留标题、电脑主体、配色和整体构图。
图17 图片编辑结果
每次编辑生成新版本,原图保留,版本列表可来回切换比较。
5.4 配图回填与导出
图片可逐张插到对应段落,或点“一键插入到文章”统一处理。封面放标题附近,正文插图按任务保存的段落定位,匹配不到就追加到文末。
图18 插入并导出文章
导出文件在原名后加“配图版”,不覆盖原始 Markdown;图片集中放进 images 子目录。
图19 导出文章预览
重新打开导出的文章,封面和正文插图位置正确,原标题、段落和代码块未被改动。
六、总结与后续方向
本项目用蓝耘 MaaS 接入 GLM5.3 作文本模型,既在开发阶段(Codex 协作)也在运行阶段(把全文/段落转成结构化图像指令)使用;图像生成与编辑交给 Sense U1.5 Lite。两组接口独立,便于分别排查。
当前版本是一个可运行的 MVP,后续计划包括:用后端代理保护长期密钥、持久化生成记录与提示词对比、以及用调用记录比较不同文本模型在“长文理解→视觉指令”任务上的表现差异。
- 使用后端代理保护长期密钥;
- 持久化生成记录、提示词对比和调用日志;
- 利用调用记录比较不同文本模型在“长文理解→视觉指令”任务中的表现差异。

评论0