# 《WaLiOffice - AI Agent 智能办公平台》第3-8节:图像生成——API调用与多Key轮询
作者:小傅哥
博客:https://bugstack.cn (opens new window)
沉淀、分享、成长,让自己和他人都能有所收获!😄
大家好,我是技术UP主小傅哥。
前面的工具都是“文字内容生成”——Markdown、Word、Excel、图表,LLM 直接生成就行。图片完全不同:LLM 写字很强,画图不行,必须调用专业的图像生成模型 API。从这节开始连续三节做图像生成:本节讲文生图的完整链路 + 多 Key 轮询基础设施,3-9 讲图生图与附件理解。
image_prompt 工具的链路是:
用户需求 → LLM 规划 3 套风格提示词 → 逐张调用 Agnes Image API → 多图返回前端画廊
难点有三个:提示词工程(LLM 产出的不是图片而是“提示词”,提示词质量决定图片质量)、多 Key 轮询(图片 API 限流严,单 Key 容易触发 QPS 上限)、失败兜底(一次生成几十秒,全挂了怎么给用户交代)。
另外一个工程决策要先讲清楚:3 张图是串行生成的,不是并发。每张图 10-60 秒,串行 3 张要等 1-3 分钟——所以每张图生成前后都推 state_update(“正在生成第 2 / 3 张图片(赛博科技)...”),用实时进度换等待焦虑。为什么不并发?3 个并发请求打同一个 Key 池,限流风险翻三倍,且失败重试逻辑会复杂一倍。先跑通,再优化——并发化留给读者作业。
# 一、本章诉求
- 掌握图像提示词工程:文生图六段式结构(主体+场景+风格+光照+构图+质量)、图生图四段式(修改+新风格+增删+保留)
- 理解 AgnesCredentials 多 Key 基础设施:Key 列表解析(逗号分隔)、round-robin 游标、
ordered_keys全量有序返回 - 掌握两层重试机制:外层
generate_agnes_image两次尝试(间隔 2s)+ 内层post_json_url按序换 Key(401/403/429/5xx 触发) - 实现输出规格推断:根据 topic 关键词推断 size 和 ratio(海报 2:3、头像素材 1:1、默认 3:2)
- 掌握兜底链:3 套提示词全失败 → 简化提示词重试 → 仍失败才报错
- 理解产物结构:
kind: "image"的 images/variants 双字段设计与前端画廊渲染
# 二、流程设计
# 2.1 文生图完整链路

用户:"帮我生成一张科技感产品海报"
↓
① call():topic 校验、styles 提取
scene_guide = infer_scene_guide(topic) // 商业/科技/活动/默认
output_spec = infer_image_output_spec(topic) // 海报→2:3,头像→1:1,默认→3:2
image_inputs = collect_image_inputs() // 无参考图 → 文生图
↓
② ctx.send("state_update"):正在为《xx》生成高质量出图提示词...
↓
③ 规划 LLM:生成 ImagePromptPlan
{ title, description, prompts: [{style, prompt} × 3] }
↓
④ resolve_image_credentials() → AgnesCredentials { base_url, api_keys[] }
endpoint = base_url + "/v1/images/generations"
↓
⑤ for (index, variant) in variants(串行,每张):
state_update("正在生成第 N / 3 张图片(风格)...")
request_body = { model, prompt, size: "1K", ratio, extra_body: { response_format: "url" } }
generate_agnes_image()
└─ post_json_url():ordered_keys 轮询 Key → 401/403/429/5xx 换下一个 Key
└─ 失败 → sleep(2s) → 再来一轮(外层 2 次尝试)
成功:url 或 b64_json → generated_images/variants
失败:failed_variants 记录 → continue
↓
⑥ 全失败兜底:简化提示词("Create a clear, high quality image...")再试一次
↓
⑦ ToolArtifact { kind: "image" }
content = { type, title, description, prompt, image_size, image_ratio,
generation_mode, reference_image_count, images[], variants[], provider, model }
↓
chat.rs 落盘首图 → 前端 ImageArtifact 画廊渲染
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31

