写技术文章时,我花在配图上的时间有时并不比正文少:封面要概括主题,正文插图要对应段落,生成后还可能需要调整标题、比例或局部元素。过去的做法是逐段整理提示词,再分别生成和修改图片,这次我尝试把这些步骤放进一个工具里。
这个工具叫「博文视觉生成器」。上传 Markdown 文档后,可以运行“AI 智能规划配图”,也可以单独选择全文或某个段落,生成封面或正文插图。
这个项目的文本模型使用 GLM5.3,通过蓝耘元生代接入;视觉生成和图片编辑使用 Sense U1.5 Lite。本文叙述模型名称时统一写作“GLM5.3”,在配置和真实请求中则使用控制台给出的模型 ID:glm-5.3。
一、项目结果与调用链路
《博文视觉生成器》会先让大模型理解全文并生成配图计划,再创建若干生图任务。每个任务先调用语言模型生成视觉指令,再调用 Sense U1.5 Lite 生成封面或插图。对于已生成或已有的图片,还可以继续微调。
这次使用 Codex 开发项目,并通过 CC Switch 管理和切换模型服务。

图1 项目最终效果
项目使用 Vue 3 + Vite 开发,是一个不含业务后端的纯前端应用。界面分成左右两块:左边是博文文档,支持上传、编辑、预览以及按内容块选择段落;右边是视觉创作区,可选择封面或插图、视觉风格与画面比例。
整个调用链路如下:
#mermaid-svg-CpFPa67HrQmhVu1L{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-CpFPa67HrQmhVu1L .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-CpFPa67HrQmhVu1L .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-CpFPa67HrQmhVu1L .error-icon{fill:#552222;}#mermaid-svg-CpFPa67HrQmhVu1L .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-CpFPa67HrQmhVu1L .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-CpFPa67HrQmhVu1L .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-CpFPa67HrQmhVu1L .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-CpFPa67HrQmhVu1L .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-CpFPa67HrQmhVu1L .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-CpFPa67HrQmhVu1L .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-CpFPa67HrQmhVu1L .marker{fill:#333333;stroke:#333333;}#mermaid-svg-CpFPa67HrQmhVu1L .marker.cross{stroke:#333333;}#mermaid-svg-CpFPa67HrQmhVu1L svg{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-CpFPa67HrQmhVu1L p{margin:0;}#mermaid-svg-CpFPa67HrQmhVu1L .label{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;color:#333;}#mermaid-svg-CpFPa67HrQmhVu1L .cluster-label text{fill:#333;}#mermaid-svg-CpFPa67HrQmhVu1L .cluster-label span{color:#333;}#mermaid-svg-CpFPa67HrQmhVu1L .cluster-label span p{background-color:transparent;}#mermaid-svg-CpFPa67HrQmhVu1L .label text,#mermaid-svg-CpFPa67HrQmhVu1L span{fill:#333;color:#333;}#mermaid-svg-CpFPa67HrQmhVu1L .node rect,#mermaid-svg-CpFPa67HrQmhVu1L .node circle,#mermaid-svg-CpFPa67HrQmhVu1L .node ellipse,#mermaid-svg-CpFPa67HrQmhVu1L .node polygon,#mermaid-svg-CpFPa67HrQmhVu1L .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-CpFPa67HrQmhVu1L .rough-node .label text,#mermaid-svg-CpFPa67HrQmhVu1L .node .label text,#mermaid-svg-CpFPa67HrQmhVu1L .image-shape .label,#mermaid-svg-CpFPa67HrQmhVu1L .icon-shape .label{text-anchor:middle;}#mermaid-svg-CpFPa67HrQmhVu1L .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-CpFPa67HrQmhVu1L .rough-node .label,#mermaid-svg-CpFPa67HrQmhVu1L .node .label,#mermaid-svg-CpFPa67HrQmhVu1L .image-shape .label,#mermaid-svg-CpFPa67HrQmhVu1L .icon-shape .label{text-align:center;}#mermaid-svg-CpFPa67HrQmhVu1L .node.clickable{cursor:pointer;}#mermaid-svg-CpFPa67HrQmhVu1L .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-CpFPa67HrQmhVu1L .arrowheadPath{fill:#333333;}#mermaid-svg-CpFPa67HrQmhVu1L .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-CpFPa67HrQmhVu1L .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-CpFPa67HrQmhVu1L .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-CpFPa67HrQmhVu1L .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-CpFPa67HrQmhVu1L .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-CpFPa67HrQmhVu1L .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-CpFPa67HrQmhVu1L .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-CpFPa67HrQmhVu1L .cluster text{fill:#333;}#mermaid-svg-CpFPa67HrQmhVu1L .cluster span{color:#333;}#mermaid-svg-CpFPa67HrQmhVu1L div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-CpFPa67HrQmhVu1L .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-CpFPa67HrQmhVu1L rect.text{fill:none;stroke-width:0;}#mermaid-svg-CpFPa67HrQmhVu1L .icon-shape,#mermaid-svg-CpFPa67HrQmhVu1L .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-CpFPa67HrQmhVu1L .icon-shape p,#mermaid-svg-CpFPa67HrQmhVu1L .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-CpFPa67HrQmhVu1L .icon-shape .label rect,#mermaid-svg-CpFPa67HrQmhVu1L .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-CpFPa67HrQmhVu1L .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-CpFPa67HrQmhVu1L .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-CpFPa67HrQmhVu1L :root{–mermaid-font-family:\”trebuchet ms\”,verdana,arial,sans-serif;}
Markdown 全文或选中段落
蓝耘元生代 · GLM5.3
理解内容、抽取主题与信息层级生成视觉指令
商汤 · Sense U1.5 Lite
根据视觉指令生成封面或正文插图
图片编辑器
上传或复用生成结果继续通过自然语言改图
二、开发环境与 CC Switch 配置
2.1 模型服务的选型条件
选择模型服务时,我先核对接入方式、模型字段和用量查询方式,模型列表则用于确认后续是否方便做对照测试。
这个项目既要在 Codex 中开发,也要在前端调用文本模型分析长文章,因此接口是否容易接入、模型参数是否清楚,会直接影响开发和排错效率。
本项目接入蓝耘 MaaS。开始编码前,我检查了以下四项配置:
接口文档提供了 OpenAI 兼容调用示例。现有请求层可以保留,接入时需要替换 base_url、api_key 和模型 ID。

图2 蓝耘接口文档
模型列表给出了模型类型、上下文长度、供应商和 API 入口。我先确认上下文长度是否能覆盖长文任务,再复制控制台中的实际调用 ID。
Kimi、Qwen 等文本模型可以使用同一类兼容接口。后续做对照测试时,主要调整模型 ID 和提示词,不需要改动业务流程。
API Key 可以按项目创建,资源包页面记录剩余量和使用量。遇到鉴权或额度问题时,我会先检查这两个入口。

图3 蓝耘用量监控
上述接口和模型字段以 MaaS 控制台中的接口文档与模型列表页面为准。
本次测试使用 GLM5.3,任务包括编码协作、Markdown 长文理解和结构化视觉策划。发起请求时,模型字段填写 glm-5.3。

图4 蓝耘模型列表
2.2 Codex 与 CC Switch 的配置关系
我日常经常使用 Codex 处理代码,但使用额度偶尔会见底,因此会通过 CC Switch 切换其他模型服务。
CC Switch 可以保存多个供应商配置,并在界面中切换 Provider。选择配置后,它会更新 Codex 当前使用的模型、端点和认证信息,因此切换时不用手工反复编辑配置文件。
CC Switch 的核心是维护 Codex 配置。Codex 使用 ~/.codex/config.toml 保存 Provider、模型与端点设置,API Key 则由相应的认证配置管理。对于只提供 OpenAI Chat Completions 接口的第三方服务,需要启用本地路由,把 Codex 的 Responses 请求转换为上游支持的格式。
2.3 创建项目专用 API Key
本次测试在 MaaS 控制台的 API Key 页面创建密钥。
本次测试为项目单独创建 API Key,测试结束后可以停用。这样处理泄露、401 或额度异常时,不会牵连其他项目的密钥。

图5 创建API Key
2.4 在 CC Switch 中配置 GLM5.3 Provider
打开 CC Switch,切换到 Codex 页面,点击新增 Provider,选择“自定义”。需要填的字段如下:
| Provider 名称 | 蓝耘-GLM5.3 | 仅用于自己识别 |
| Base URL | 控制台提供的 OpenAI 兼容基础地址 | 不是控制台网页地址 |
| API Key | 刚创建的项目专用 Key | 不提交到仓库,不放截图里 |
| 模型 | glm-5.3 | 控制台显示的实际调用 ID |
| 接口格式 | 按接口文档选择 | 如果上游只有 Chat Completions,需要打开本地路由 |
这里有一个容易混淆的点:是否需要打开 CC Switch 的本地路由,不取决于模型叫不叫 GLM,而取决于上游接口格式。
- 如果端点原生支持 Codex 所用的 Responses 兼容格式,可以直接按 Provider 配置使用。
- 如果端点只提供 OpenAI Chat Completions 兼容接口,则在 CC Switch 的“设置 → 路由”中启动本地路由,并在可路由应用中启用 Codex。此时本地路由负责协议转换。
我的配置顺序如下:
不要手工把真实 Key 写进文章里的 config.toml 示例。CC Switch 切换后可以检查当前的 ~/.codex/config.toml:model_provider、model 和 base_url 应该已经变成刚启用的 Provider。密钥不要贴到文章、终端录屏或 Git 提交记录里。

图6 CC Switch配置
保存配置后,我先进行接口连通性测试。

图7 接口连通测试
2.5 用 Codex 验证开发模型是否切换成功

图8 Codex模型验证
切换 Provider 后重新打开 Codex,给一个足够具体但不消耗太多额度的任务,例如:
阅读当前 Vue 项目的目录结构,说明将 Markdown 文档拆成“全文”和“段落”两种生成范围时,状态应该放在哪个组件,并给出修改建议。不要直接改文件。
这一步不评测模型分数,只验证三个结果:Codex 能否响应、模型名是否来自当前 Provider,以及项目上下文能否被读取。

图9 Codex理解项目
三、创建项目
3.1 创建并启动项目

图10 输入初始Prompt
这个项目从零开始开发。我先用一条基础 Prompt 生成项目框架,再通过多轮对话逐步补充功能。
最初的 Prompt 只描述整体方向,后续再补充页面布局、并行任务、图片编辑和错误重试等需求。这也是我常用的开发方式:先确认大方向,再逐项微调。

图11 追加开发Prompt
项目使用 Vue 3 + Vite 开发。markdown-it 负责把文档转换为 HTML,dompurify 负责清理渲染结果,避免将上传 Markdown 中不可信的 HTML 直接插入页面。图片生成和编辑请求统一放在 src/services,页面组件只处理状态和交互。
工程目录为 md-visual-studio。

图12 项目目录结构
3.2 在页面中配置模型
项目启动后,点击右上角“模型配置”打开设置弹窗。文本模型部分填写服务地址、接口路径、模型 ID glm-5.3 和项目专用 API Key;图像模型部分填写服务地址、生图路径 /images/generations、编辑路径 /images/edits、模型 ID 和访问密钥。
保存后,配置写入当前浏览器的本地存储,页面顶部会同步显示两组接口的配置状态。整个过程都在页面弹窗中完成,不需要修改项目配置文件。
四、核心实现
4.1 让 GLM5.3 先做视觉策划,而不是直接让生图模型读全文
文章往往很长,直接整篇交给图像模型,得到的画面容易只抓住几个表面关键词。我的处理方式是把“理解文章”和“生成图片”拆开。
上传 Markdown 后,项目会提取标题和内容块;用户可以选择全文,也可以点击某个段落。随后 createImagePrompt 把选中的文本、图片用途、画面比例和风格发给语言模型。请求中的 model 来自页面配置,本项目实际发送的是 glm-5.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。
在这一步中,GLM5.3 把原文整理成可传给图像模型的视觉简报。输出内容包含画面主题、信息层级、构图和文字约束,而不是一条宽泛的“科技风图片”要求。
4.2 把 U1.5 Lite 的生图和改图收敛成同一个图片工作流
右侧创作区没有把“智能生成”和“图片编辑”硬切成两个页面。用户生成图片后,可以点击“编辑图片”直接进入近全屏编辑器;也可以先点击“编辑已有图片”上传一张本地图片。
编辑器处理了三个细节:
文生图请求使用顶层 prompt,核心结构如下:
const payload = {
model,
prompt,
n: 1,
size: editSizeByRatio[ratio] || 'auto',
output_format: 'png',
response_format: 'b64_json',
watermark: true,
prompt_extend: true,
}
图片编辑走 /images/edits,原图放进 images,自然语言修改要求仍放在顶层 prompt:
const payload = {
model,
images: [{ image_url: imageUrl }],
prompt: instruction,
n: 1,
size: editSizeByRatio[ratio] || 'auto',
response_format: 'b64_json',
watermark: true,
prompt_extend: true,
}
前端不负责给图片二次排字,只把视觉指令、原图和比例交给模型。图片中的标题和技术名词与画面一起生成,避免浏览器叠字与原图风格不一致。
五、实际问题与处理方式
页面做出来后,真正花时间排查的是三个问题:浏览器跨域、批量任务并发,以及生图接口偶发失败。它们不算复杂,但不处理好,工具就只能偶尔生成一张图,很难连续使用。
5.1 本地页面直连接口时触发 CORS 限制
一开始,页面从 http://localhost:5173 直接请求图像接口,浏览器控制台随即报出跨域错误。这并不是 localhost 不能调用 AI,而是浏览器的同源策略在起作用:页面和模型接口的协议、域名或端口不同,接口又没有放行当前来源,请求还没到业务处理阶段就被浏览器拦下了。
项目用的是 Vite,开发阶段可以加一层同源代理。浏览器请求本站的 /api/sensenova,Vite 开发服务器再把它转发给目标接口:
const sensenovaProxy = {
target: 'https://token.sensenova.cn',
changeOrigin: true,
rewrite: (path) => path.replace(/^\\/api\\/sensenova/, ''),
}
export default defineConfig({
server: {
proxy: {
'/api/sensenova': sensenovaProxy,
},
},
})
在请求层中,如果识别到目标服务地址,就把浏览器实际请求地址改写为同源代理路径:
if (target.origin === 'https://token.sensenova.cn') {
return `/api/sensenova${target.pathname}${target.search}`
}
修改后,浏览器发出的请求与本地页面同源,跨域转发由 Vite 完成。重新测试时,生图和改图接口均能返回结果。
这套代理只在 Vite 的开发和预览服务中生效,打包出来的静态文件不会自带代理能力。要公开部署,服务器仍需配置同名反向代理,或者由后端代调模型接口。页面保存在 localStorage 中的 API Key 也无法真正隐藏,因此这个版本只适合本机测试或受控演示。
5.2 全篇配图从逐个等待改为并行任务
第一版一次只能处理一张图,前一项结束后才会开始下一项。“AI 智能策划全篇配图”通常会产生一张封面和多张正文插图,串行执行时,几次模型调用的耗时会叠在一起,等起来很慢。
我又给 Codex 中使用的 GLM5.3 补了一条 Prompt,大意是:
将智能配图方案改成独立任务并行执行。应用方案后立即创建全部任务卡片,
每个任务分别维护提示词生成、生图、完成和失败状态;单个任务失败不能阻塞其他任务。
实现时没有在循环里逐项 await,而是先为每条建议创建任务,再立即调用 executeTask。简化后的代码如下:
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)
})
每张图单独维护 prompting、generating、completed 和 failed 状态。哪张先完成就先显示;其中一张报错,其他任务照常运行。
智能策划目前只推荐少量关键配图,直接并行已经够用。如果以后允许一次生成几十张图,还要加并发上限和等待队列,避免短时间内发出太多请求。
5.3 接口偶发报错时保留任务并支持重试
生图接口并不总能一次成功。测试时我碰到过网络中断、服务端报错、响应超时,也遇到过请求返回成功但程序没有解析出图片的情况。如果失败后直接移除卡片,错误原因看不到,段落、比例和风格也得重新选择。
所以我没有删除失败任务,而是把状态改成 failed,将错误信息留在卡片上,并显示“重试”和“重新下发”按钮:
async function executeTask(task) {
task.status = 'prompting'
task.error = ''
try {
task.prompt = await createImagePrompt(/* 当前任务参数 */)
task.status = 'generating'
task.imageUrl = (await generateImage(/* 当前视觉指令 */)).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)
}
点击重试后,文章内容、图片类型、风格和比例都会沿用原任务,不用再填一遍。现在采用的是整条链路重跑,也就是重新生成视觉指令,再调用生图接口。这样两个阶段的错误都能处理。后面如果要减少重复调用,可以缓存已经生成成功的视觉指令,只重试生图接口。
六、效果实测
6.1 上传 Markdown 文章
测试时,我上传了一篇包含多个章节、操作步骤和技术名词的 Markdown 文章。程序读取一级标题,并统计字符数、文件大小和内容块数量,我用这些信息确认文件是否读取完整。

图13 上传Markdown
界面分为上、中、下三部分。顶部放项目名称、模型状态和配置入口;中间左边是 Markdown 文档,右边是视觉生成控制台;底部集中显示生图任务。文档区可以在“编辑”和“预览”之间切换,改完原文后能立即检查标题、列表和代码块的渲染结果。
这篇文章的标题和内容块都识别正确。选择“文章全文”可以生成封面;切换到“选中段落”,再在预览区点选一个或多个内容块,可以生成对应的正文插图。原文、参数和结果都显示在当前页面,不需要在不同工具之间复制段落。
6.2 AI 智能策划全篇配图
点击“AI 智能策划全篇配图”后,GLM5.3 会通读文章,挑出适合配图的位置。它不会给每段都放一张图,而是优先处理封面、核心流程、参数对比和操作重点,同时给出标题、理由及对应段落。

图14 全文配图方案
确认方案后,页面一次创建所有任务。每项任务都记下标题、用途、比例、风格和目标段落,然后调用语言模型生成视觉指令,再交给图像接口处理。几张图会同时生成,不再一张接一张地等待。

图15 配图并行生成
任务卡片会显示当前阶段和等待时间。图片完成后直接出现在卡片里,还可以展开查看语言模型生成的视觉指令。如果结果偏离原文,可以据此判断问题出在文章理解还是生图环节。

图16 配图生成完成
这次生成的封面抓住了文章主题,正文插图也能对应到所选段落,没有变成泛化的科技背景图。并行任务中即使有一项失败,其他任务仍会继续,已完成的图片也会保留。
6.3 图片编辑
图片生成后,可以点击任务卡片中的“微调”继续编辑,也可以另行上传一张图片。编辑时只要用自然语言说明改哪里,不用重写整条生图提示词。

图17 图片编辑窗口
这次我要求模型把画面右侧的一台平板改成两台,分别表示安卓平板和苹果 iPad,同时保留标题、电脑主体、配色和整体构图。前端没有用 Canvas 覆盖元素,也没有在本地重新排字,只负责把原图和修改要求交给 Sense U1.5 Lite。

图18 图片编辑结果
每次编辑都会生成一个新版本,原图仍然保留。左侧的版本列表可以来回切换,用于比较修改前后的差异,再选择下载或继续调整。主体已经符合要求、只需替换设备或局部文字时,我会使用编辑接口,而不是重新生成整张图片。
6.4 配图回填与文章导出
图片完成后,可以逐张插入对应段落,也可以点击“一键插入到文章”统一处理。封面放在文章标题附近,正文插图根据任务中保存的原始段落定位;匹配不到时则追加到文末。

图19 插入并导出文章
导出文件会在原名称后加上“配图版”,不会覆盖原始 Markdown。整理投稿文件时,我把 Markdown 和下载的原图放在同一目录下,图片集中放进 images 子目录:
1-单测–开学季平板远程控制电脑实测:ToDesk让iPad安卓平板秒变生产力工具-配图版
├── 1-单测–开学季平板远程控制电脑实测:ToDesk让iPad安卓平板秒变生产力工具-配图版.md
└── images
├── iPad远程控制电脑:ToDesk实测,平板秒变生产力工具-1788140637816.png
├── 出门前检查:电脑状态与安全设置-1788140635804.png
├── 二次微调修图版本-1788140632987.png
├── 双指缩放:解决Windows小按钮操作难题-1788140636451.png
├── 远程打开WPS:原文件与格式完整保留-1788140635165.png
└── 远程桌面连接:iPad操作Windows电脑-1788140637078.png

图20 导出文章预览
重新打开导出的文章,封面和正文插图都在预期位置,原来的标题、段落和代码块也没有被改乱。Markdown 上传、全篇配图、并行生图、自然语言改图和文章导出这几步都跑通了。
七、测试结论与限制
项目中的文本模型通过蓝耘 MaaS 接入,对应两个调用环节:
- 开发阶段:我通过 Codex + CC Switch 完成 Vue 组件拆分、接口边界设计和配置排错。
- 运行阶段:GLM5.3 把全文或段落转换成结构化、受原文约束的图像指令,再把任务交给 U1.5 Lite。
U1.5 Lite 负责图像生成与编辑。文本理解和视觉生成使用两组独立接口,出现问题时可以分别查看语言模型输出和生图接口响应。
目前完成的是一个可运行的 MVP,仍有继续完善的空间。下一步我准备使用后端代理保护长期密钥,并加入持久化生成记录、提示词对比和调用日志。
调用记录也能用于比较不同文本模型在“长文理解 → 视觉指令”任务中的实际差异。
