简介
本文件面向开发者,系统化说明 DouPHP 的 AI 图像生成功能。内容涵盖与多模型供应商(如通义万相、DALL·E、GPT-Image、CogView 等)的统一接入方式;任务调度、异步处理、结果缓存、质量评估、提示词工程、参数调优、批量生成、格式转换、存储管理与版权保护等关键技术点。文档以代码级视角解释数据流与控制流,并提供可落地的集成与排错建议。
项目结构
AI 图像生成功能横跨后台管理端、核心网关与配置层:
- 后台控制器与服务:负责应用编排、提示词组装、任务提交与入库。
- 核心网关:统一对接各驱动(OpenAI/DashScope/百度/火山等),屏蔽协议差异。
- 配置中心:集中管理提示词模板、尺寸归一化策略、素材限制等。
graph TB
subgraph "后台"
AC["AiController"]
GS["GenerateService"]
TS["TaskService"]
end
subgraph "核心"
AG["AiGateway"]
IF["ImageSizeNormalizer"]
DF["DriverFactory"]
end
subgraph "配置"
CFG["ai.php"]
end
AC --> GS
AC --> TS
GS --> AG
TS --> AG
AG --> DF
GS --> IF
CFG --> GS
CFG --> AG
核心组件
- 后台控制器 AiController:提供 AI 应用的列表、创建、编辑、删除与字段获取等页面能力,作为用户交互入口。
- 生成服务 GenerateService:实现 batch/fill/assist/translate 多种形态;对图像应用走文生图链路,完成提示词构建、尺寸归一化、参考图解析、任务提交与用量记录。
- 任务服务 TaskService:封装异步任务的提交、分页查询、删除等管理能力。
- 网关 AiGateway:统一解析模型/供应商/密钥,构造请求体与头,执行对话或图像生成,并处理结构化输出与异步任务。
- 尺寸归一化 ImageSizeNormalizer:将前端 WxH 尺寸映射到各模型合法取值,避免“尺寸导致失败”。
- 配置 ai.php:集中管理提示词模板、banner 风格与素材限制、图像尺寸策略等。
架构总览
整体流程分为两条主线:文本生成与图像生成。图像生成在 assist 形态下会进入文生图链路,支持同步直出与异步轮询两种模式,并通过统一的任务表进行状态追踪与结果展示。
sequenceDiagram
participant Admin as "管理员界面"
participant Ctrl as "AiController"
participant Gen as "GenerateService"
participant GW as "AiGateway"
participant DF as "DriverFactory"
participant Driver as "具体驱动(OpenAI/Qwen/百度/火山)"
participant Store as "任务存储/结果存储"
Admin->>Ctrl : 发起生成请求
Ctrl->>Gen : 调用 generateField/generateBatch
Gen->>GW : generateImage/submitAsyncTask
GW->>DF : 根据配置选择驱动
DF-->>GW : 返回驱动实例
GW->>Driver : 发送图像生成请求
Driver-->>GW : 返回URL或任务ID
GW->>Store : 记录任务行/结果(含过期时间)
GW-->>Gen : 返回{task_id,status,result}
Gen-->>Ctrl : 返回任务结果
Ctrl-->>Admin : 展示任务状态/结果
详细组件分析
生成服务(GenerateService)
- 职责:按应用形态组织提示词、校验输入、调用网关、记录用量、处理图像尺寸与参考图。
- 关键路径:
- 批量生成:compose → chatJson → importManager.import。
- 表单回填:compose → chatJson → 返回字段值。
- 辅助生成(文本/图像):文本直接 chat;图像则 buildImagePrompt → generateImage。
- 预览:仅组装消息或最终提示词,不下发模型。
- 图像提示词构建:
- 尺寸规划:极端比例自动切换为 16:9 基础尺寸,再经 ImageSizeNormalizer 映射到模型合法预设。
- 参考图解析:支持 data URI 与 .file 附件号,最多 4 张,单张上限可配。
- 成品裁切:target_size/gen_size 仅落任务 payload,系统不自动裁切,由管理员手动裁剪。
- 用量记录:每次调用均记录 usage 与上下文,便于成本核算与审计。
flowchart TD
Start(["开始"]) --> LoadApp["加载应用并校验"]
LoadApp --> IsImage{"是否图像应用?"}
IsImage -- 否 --> TextPath["组装消息 -> chat/chatJson"]
IsImage -- 是 --> BuildPrompt["构建图像提示词<br/>尺寸归一化/参考图解析"]
BuildPrompt --> CallGW["调用网关 generateImage"]
TextPath --> Record["记录用量"]
CallGW --> Record
Record --> Return(["返回结果/任务ID"])
任务服务(TaskService)
- 职责:按应用提交异步任务、分页查询任务列表、删除终态任务。
- 白名单透传:size/width/height/duration/resolution 等参数可安全透传给驱动。
- 列表增强:一次性补齐模型/供应商/管理员名称映射,便于模板渲染。
网关(AiGateway)
- 职责:解析模型/供应商/密钥,构造请求体与头,执行对话/图像生成,统一错误处理与用量提取。
- 图像生成:
- 同步驱动:若上游拒绝 size,自动重试一次不带 size 的请求,确保“尺寸不成为失败原因”。
- 异步驱动:提交任务并返回 task_id,前端轮询。
- 结果持久化:统一写入任务表,远程 URL 带过期时间提示。
- 结构化输出:chatJson 优先使用 response_format.json_schema,否则降级为 json_object + system 重述 schema。
尺寸归一化(ImageSizeNormalizer)
- 策略:range(范围型)与 presets(枚举型)两类;未登记模型返回空串,交由驱动使用默认尺寸。
- 原则:能大则大、先保宽高比再保面积;极端比例超出可达范围时钳到极限比例。
- 配置:通过 ai.php 的 image_size.policies 与 protocol_defaults 扩展新模型。
控制器(AiController)
- 职责:承载后台 AI 应用页面的路由与视图渲染,调用 ApplicationService 完成 CRUD。
- 与图像生成的关联:通过路由与视图触发 GenerateService 的生成接口,展示任务进度与结果。
依赖关系分析
- 控制器依赖服务:AiController → GenerateService / TaskService。
- 服务依赖网关:GenerateService / TaskService → AiGateway。
- 网关依赖工厂与驱动:AiGateway → DriverFactory → 具体驱动(OpenAI/Qwen/百度/火山)。
- 配置影响:ai.php 控制提示词、尺寸策略与素材限制,贯穿生成与网关。
classDiagram
class AiController {
+index()
+create()
+store()
+edit()
+update()
+destroy()
+getFields()
+action()
}
class GenerateService {
+generateBatch()
+generateForm()
+generateField()
+previewField()
+generateTranslate()
}
class TaskService {
+submit()
+getIndexPageData()
+findTask()
+delete()
}
class AiGateway {
+resolveConfig()
+chat()
+chatJson()
+generateImage()
+submitAsyncTask()
+pollAsyncTask()
}
class DriverFactory {
+make(config)
}
class ImageSizeNormalizer {
+normalize(modelCode, size, providerCode) string
}
AiController --> GenerateService : "调用"
AiController --> TaskService : "调用"
GenerateService --> AiGateway : "调用"
TaskService --> AiGateway : "调用"
AiGateway --> DriverFactory : "选择驱动"
GenerateService --> ImageSizeNormalizer : "尺寸归一化"
性能与成本优化
- 提示词工程
- 使用 ai.php 中的 prompts.system/instruction/labels 统一规范提示词,减少歧义与无效输出。
- 图像场景结合 banner_styles 与 material_mode 指令,提升构图与品牌一致性。
- 参数调优
- 尺寸归一化:通过 ImageSizeNormalizer 将 WxH 映射到模型合法取值,避免失败重试。
- 极端比例:自动切换 16:9 基础尺寸,降低模型拒识率。
- 参考图限制:material_max 与 upload_max_bytes 控制资源消耗。
- 批量生成
- 去重指纹:基于 admin/app/prompt/count/context 生成指纹,防止重复提交。
- 结构化输出:chatJson + JSON Schema 约束,减少后处理成本。
- 异步与缓存
- 异步驱动:分钟级任务通过 submitAsyncTask 提交,前端轮询,不阻塞请求。
- 结果过期:远程 URL 带 expires_at,客户端需及时下载或转存。
- 成本控制
- 用量记录:每次调用记录 prompt/completion/total tokens,便于统计与限流。
- 密钥熔断:连续失败达阈值自动排除候选密钥,降低无效调用。
- 存储与版权
- 本地化:对远程 URL 尽快下载到自有存储,避免外链失效与版权风险。
- 水印与元数据:可在后处理阶段添加水印与版权信息,保障商用合规。
故障排查指南
- 常见错误定位
- 无可用模型/密钥:检查 resolveConfig 返回值与 getAvailableKey 筛选条件。
- HTTP 非 200:查看日志中 http_code 与 error_msg,确认供应商端点与鉴权。
- JSON 解析失败:检查 chatJson 的 response_format 与 system 中 schema 重述。
- 图像生成失败:关注 generateImage 的尺寸拒绝重试逻辑与 async_only 分支。
- 排查步骤
- 确认应用状态与 placement 匹配。
- 检查提示词是否为空(图像场景尤其重要)。
- 核对尺寸是否符合模型策略(必要时去掉 size 重试)。
- 查看任务列表与任务详情,确认 status/result/expires_at。
- 日志与监控
- 关注 ai channel 的错误日志,包含 model_id、http_code、error 等关键字段。
- 结合 UsageRecorder 的用量记录,定位高成本调用。
结论
DouPHP 的 AI 图像生成功能以“应用-模型-驱动”的分层设计,实现了多供应商的统一接入与稳定运行。通过提示词工程、尺寸归一化、异步任务与用量记录,兼顾了生成质量、性能与成本。开发者可在此基础上快速扩展新模型与新场景,同时保证系统的可维护性与可扩展性。
附录:调用示例与最佳实践
- 调用图像生成 API(assist 形态)
- 入口:GenerateService::generateField
- 参数要点:appId、field、userPrompt、formSnapshot、currentModule、adminId、ip、size、contentAlign、banner
- 返回:文本应用返回正文;图像应用返回任务结果数组(含 task_id/status/result/expires_at)
- 参考路径:GenerateService.php:215-326
- 提交异步任务(独立入口)
- 入口:TaskService::submit
- 白名单透传:size/width/height/duration/resolution
- 返回:{task_id, status}
- 参考路径:TaskService.php:70-105
- 处理生成结果
- 同步直出:AiGateway::generateImage 返回已记录的任务行,status=succeeded,result.urls 为图片地址。
- 异步轮询:AiGateway::pollAsyncTask 获取任务状态与结果。
- 参考路径:AiGateway.php:600-693, AiGateway.php:730-733
- 图像后处理
- 尺寸裁切:按 target_size 与 band_ratio 进行裁切(系统不自动裁切)。
- 格式转换:根据业务需求转换为 WebP/JPG/PNG,注意压缩与清晰度平衡。
- 水印与元数据:添加版权信息与元数据,满足商用合规。
- 最佳实践
- 提示词:使用 ai.php 的 prompts 模板,保持风格一致。
- 尺寸:优先使用 ImageSizeNormalizer 映射后的尺寸,避免失败。
- 参考图:控制数量与大小,避免带宽与内存压力。
- 成本:结合用量记录与密钥熔断,合理选择模型与供应商。
- 存储:尽快下载远程 URL 到自有存储,设置合理的过期与清理策略。