
图像生成视频Image-to-VideoI2V这两年发展非常快随手给一张参考图就能把它变成一段动态视频。但真正在项目里用起来的时候很多同学都会遇到同一个问题生成出来的视频和参考图“不听话”——要么主体特征变了要么构图和参考图完全对不上要么第一帧还算像几秒之后就完全“放飞自我”。这种情况业内一般称为Adherence不足也就是视频内容对参考图的“遵循度”“保真度”不够。为了调高这个一致性很多人只能一遍遍改提示词、调参数、重新跑典型的“抽卡式试错”耗时且不可控。本文不是单纯介绍某个模型而是从一个更工程化的角度出发梳理Agentic Optimization智能体优化在 Image-to-Video Adherence 问题上的应用思路。读完你可以理解Image-to-Video 的 Adherence 到底是什么为什么难解决。传统试错的痛点在哪里Agentic Optimization 为什么更适合这个问题。如何设计一个“生成-评估-优化”的自动化闭环并给出可运行的 Python 原型。如何量化视频对参考图的遵循度以及工程落地时的坑与最佳实践。适合对扩散模型、视频生成有一定基础但想进一步把生成质量“工程化”的读者如果你正准备做视频生成相关评测、自动化质检或者 AIGC 工具链这篇应该能帮你打开思路。1. 背景与核心概念1.1 Image-to-Video 是什么Image-to-Video 是指给定一张或若干张参考图像结合文本提示词或运动条件生成一段与参考图内容一致的视频。典型应用场景包括电商商品动态展示给定商品图生成不同角度的展示视频。角色动画与数字人给定角色立绘生成说话或动作视频。短视频素材制作一张静图扩展成可投放的视频素材。影视分镜预演从分镜图生成动态预览。和 Text-to-Video纯文本生成视频相比Image-to-Video 多了一个“参考图条件”。这也是它更难的地方模型不仅要理解文本语义还要严格保持参考图中的主体身份、外观、姿态、构图和风格。1.2 Adherence遵循度到底指什么Adherence 直译是“遵循、坚持”在 I2V 任务里可以拆成几个层面层面含义示例身份一致性主体人物/物体“还是同一个”人脸五官、商品颜色不能变外观一致性服装、质感、纹理、色调保持衣服花纹、材质的明暗关系构图一致性画面布局、主体位置、景别保持参考图主体在左侧视频不能跑到右侧语义一致性关键语义元素不丢失参考图里有杯子视频里不能凭空消失运动合理性动态过程自然不违背物理规律人物转身时形体不畸变很多同学只把 Adherence 理解为“第一帧像不像参考图”这是不够的。真正困难的是在后续帧中持续保持一致性。因为视频模型在生成后续帧时既要依赖参考图条件又要保持运动流畅这两者本质上存在张力。1.3 为什么传统试错难以解决 Adherence 问题先看一段典型的人工调参过程第 1 次输入参考图 “一只戴帽子的狗在草地奔跑” 结果第一帧像第二秒狗的脸开始变形。 第 2 次把“戴帽子”改到提示词最前面CFG 从 7 调到 9。 结果狗是像了但草地变成了水泥地。 第 3 次换一个 seed构图全变了主体位置偏右。 ……这种试错有几个致命问题搜索空间巨大。提示词、负向提示词、CFG、帧数、分辨率、seed、运动强度……组合起来是几十万个候选。反馈延迟且主观。每个结果要人工看视频、判断哪里不对效率低。经验难以复用。这次调好的参数换一张参考图、换一个 prompt 就失效了。失败原因不透明。只知道“不对”不知道是“语义理解错了”还是“外观漂移了”。1.4 Agentic Optimization 的基本思想Agentic Optimization简单理解就是让一个由大语言模型LLM驱动的智能体代替人类去做“生成-评估-反思-改进”的循环。它和普通的自动调参网格搜索、贝叶斯优化最大的区别在于网格搜索只关心参数数值不理解“为什么效果差”。Agent 能结合视觉评估结果用语言总结失败原因再据此主动修改提示词和参数。比如人眼看完视频说“狗脸在第三秒开始变形同时背景从草地变成水泥地”Agent 就能推理出“需要在负向提示词中加入‘face distortion, background change’并且降低 motion 强度”而不是随机试探。这就是标题里“Beyond Trial-and-Error”的含义从“盲目的反复试错”走向“有分析、有记忆、有策略的自动化优化”。2. Agentic Optimization 的核心设计2.1 三大模块一个最小的 Agentic Optimization 系统至少包含三个模块生成器Generator - 根据参考图 当前配置生成视频 评估器Evaluator - 量化视频对参考图的 Adherence并给出诊断信息 优化器Oracle/Agent - 根据评估结果决定下一轮参数怎么改很多资料会把第三块叫Optimizer但在 Agent 语境下我更愿意叫它Agent因为它不只是“算一个新参数”而是具备分析和决策能力的智能体。2.2 优化循环整个流程可以概括为下图文字版初始化候选配置 ↓ 生成视频 G(cfg_i) ↓ 评估 Adherence 得分 S_i 诊断文本 D_i ↓ 是否达标 / 预算是否用完 是 - 输出最优配置与视频 否 - Agent 根据 (cfg_i, S_i, D_i) 生成新的候选配置 cfg_{i1} ↓ 回到“生成视频”步骤这里的关键设计点有三个评估器不能只给一个分数还要给“哪里不好”的可解释信息否则 Agent 无从优化。Agent 必须看到历史记录而不是只根据当前一轮结果做决定否则会来回震荡。候选配置之间要有差异性避免 Agent 反复生成相似的无效方案。2.3 与其他自动优化方法的对比方法搜索方式是否理解语义失败是否积累经验适用场景网格搜索 / 随机搜索枚举参数组合否否参数少、目标函数便宜贝叶斯优化基于历史得分建模否部分目标函数可连续参数维度低强化学习RL奖励驱动的策略学习部分是需要大量采样、训练成本高Agentic OptimizationLLM 推理 工具调用是是对话记忆参数空间大、失败原因多样、需要解释性对于 I2V 这样的生成任务单次生成成本高秒级到分钟级且失败模式非常多样化Agentic Optimization 的优势就很明显它能用较少的迭代次数找到“语义上正确”的改进方向。3. 环境准备与版本说明本文的示例代码以 Python 3.10 为例核心依赖如下torch2.0 diffusers0.27 transformers4.35 opencv-python pillow numpy imageio如果要用 CLIP 做评估还需要安装accelerate注意不同的视频生成模型其 pipeline 名称、参数名、返回结构差异很大。示例代码会采用“接口封装”的方式编写目的不是绑定某个具体模型而是让你学会搭一套可替换的优化框架。实际接入时只需要改掉I2VGenerator.generate()的内部实现。建议项目结构如下agentic_i2v/ ├── config.py # 配置数据结构 ├── generator.py # 视频生成封装 ├── evaluator.py # Adherence 评估 ├── agent.py # LLM Agent 优化器 ├── main.py # 主循环 └── outputs/ # 结果输出目录4. 设计一个最小可运行的 Agentic Optimization 原型下面我们逐步实现一个简单但完整的优化循环。请特别注意代码中的模型加载方式属于“示意写法”实际请结合你本地可访问的视频生成模型调整。4.1 定义配置数据结构优化器要搜索的“参数空间”首先需要被结构化。这里把每一轮生成所需的全部信息放进一个 dataclass# config.py from dataclasses import dataclass, field from typing import Optional dataclass class GenConfig: 一轮视频生成的完整配置。 prompt: str negative_prompt: str num_frames: int 24 height: int 512 width: int 512 fps: int 8 cfg_scale: float 7.0 motion_scale: float 1.0 seed: int 42 # 用于记录候选来源方便追溯 round_id: int 0 parent_id: Optional[int] None def to_text(self) - str: 把配置转成 Agent 可读的文本描述。 return ( fPrompt: {self.prompt}\n fNegative Prompt: {self.negative_prompt}\n fCFG: {self.cfg_scale}, Motion: {self.motion_scale}, fFrames: {self.num_frames}, FPS: {self.fps}, Seed: {self.seed} )to_text()方法很重要因为 LLM Agent 需要通过文本形式“读懂”上一轮做了什么。4.2 视频生成器封装接下来封装视频生成器。考虑到不同模型的接口差异这里统一对外暴露generate(init_image, cfg)返回一个 PIL 帧列表# generator.py import torch from PIL import Image from config import GenConfig class I2VGenerator: 视频生成器封装。 这里以 diffusers 风格的 pipeline 为例。 实际接入其他模型时只需要保持 generate() 的签名不变。 def __init__(self, model_id: str, device: str cuda): self.device device self.model_id model_id self.pipeline None self._load_pipeline() def _load_pipeline(self): # 示例加载视频扩散模型具体 API 以库版本为准 from diffusers import AutoPipelineForText2Video self.pipeline AutoPipelineForText2Video.from_pretrained( self.model_id, torch_dtypetorch.float16, variantfp16, ).to(self.device) def generate(self, init_image: Image.Image, cfg: GenConfig): 根据参考图和配置生成视频帧列表。 if self.pipeline is None: raise RuntimeError(pipeline 未初始化) # 生成视频帧。不同模型的入参不同这里示例按常见参数编写。 result self.pipeline( promptcfg.prompt, negative_promptcfg.negative_prompt, imageinit_image, # 部分 I2V 模型使用 image 参数 num_framescfg.num_frames, heightcfg.height, widthcfg.width, fpscfg.fps, guidance_scalecfg.cfg_scale, generatortorch.Generator(deviceself.device).manual_seed(cfg.seed), ) # 返回类型可能是 [PIL Frames] 或视频张量需要按实际结果归一化 frames result.frames[0] return frames核心思路是把模型差异封装在 generate() 内部。这样评估器、Agent 上层代码完全不需要关心你是用了开源模型还是商业 API。4.3 Adherence 评估器评估器要同时输出两部分内容数值得分可量化、可比较。诊断文本给 Agent 看的失败分析。这里先给出一个基于 CLIP 的简化版本计算视频帧与参考图的余弦相似度# evaluator.py import torch import torch.nn.functional as F import numpy as np from PIL import Image from transformers import CLIPProcessor, CLIPModel class AdherenceEvaluator: 计算视频帧与参考图之间的 CLIP 相似度。 def __init__(self, model_name: str openai/clip-vit-base-patch32, device: str cuda): self.device device self.model CLIPModel.from_pretrained(model_name).to(device).eval() self.processor CLIPProcessor.from_pretrained(model_name) def _embed(self, images): inputs self.processor(imagesimages, return_tensorspt).to(self.device) with torch.no_grad(): features self.model.get_image_features(**inputs) return F.normalize(features, dim-1) def score(self, init_image: Image.Image, frames) - dict: 返回一个包含分数与诊断文本的字典。 # 1. 参考图嵌入 ref_emb self._embed([init_image])[0] # 2. 所有视频帧嵌入 frame_embs self._embed(frames) # 3. 逐帧相似度 per_frame_sim (frame_embs ref_emb).cpu().numpy() # 4. 统计信息 first_sim float(per_frame_sim[0]) mean_sim float(per_frame_sim.mean()) min_sim float(per_frame_sim.min()) max_sim float(per_frame_sim.max()) # 5. 生成诊断文本 if min_sim mean_sim - 0.05: diagnosis 视频后半段与参考图一致性明显下降可能存在外观漂移。 elif mean_sim 0.8: diagnosis 整体一致性偏低建议优化提示词或增强图像条件权重。 else: diagnosis 整体一致性较好可尝试提升运动幅度。 # 注意CLIP 相似度的绝对阈值跟模型有关 # 上面阈值仅作示例实际需要根据你的数据重新标定 return { first_sim: first_sim, mean_sim: mean_sim, min_sim: min_sim, max_sim: max_sim, per_frame_sim: per_frame_sim, diagnosis: diagnosis, }这个评估器虽然简单但它已经比“给一个总分”前进了一步它给出了“后半段一致性下降”这样的诊断信息Agent 才能据此调整负向提示词或 motion 参数。4.4 LLM Agent 优化器Agent 是整个系统的“大脑”。这里我用一个通用的LLMClient抽象方便你接入任意支持 Chat Completion 的模型服务# agent.py import json from typing import List from config import GenConfig class LLMClient: 统一封装外部大模型 API这里只给出接口示意。 def __init__(self, api_key: str , base_url: str , model: str your-model): self.api_key api_key self.base_url base_url self.model model def chat(self, messages: List[dict], temperature: float 0.7) - str: # 实际实现调用你的 LLM API解析返回文本 # 这里不绑定具体厂商读者按自己的环境实现即可 raise NotImplementedError(请按你的 LLM 服务商实现 chat() 方法) class AgenticOptimizer: 基于 LLM 的优化器根据历史评估结果生成新的生成配置。 def __init__(self, llm_client: LLMClient): self.llm llm_client def propose(self, history: List[dict], search_space: dict) - GenConfig: 根据历史记录生成一个新配置。 # 1. 构造历史摘要 history_text for i, h in enumerate(history): history_text ( f第 {i 1} 轮配置:\n{h[config_text]}\n f得分: mean_sim{h[score][mean_sim]:.3f}, fmin_sim{h[score][min_sim]:.3f}\n f诊断: {h[score][diagnosis]}\n\n ) messages [ { role: system, content: ( 你是一个视频生成参数优化专家。你负责根据历史生成结果 调整提示词和生成参数以提升视频对参考图的遵循度。 注意只输出 JSON不要输出其他文字。 ), }, { role: user, content: ( f以下是历史生成记录\n{history_text}\n f可调整的参数范围\n{json.dumps(search_space, ensure_asciiFalse)}\n 请输出新一轮的 JSON 配置字段包括 prompt, negative_prompt, cfg_scale, motion_scale, seed ), }, ] response self.llm.chat(messages, temperature0.8) # 2. 解析 JSON 并转为 GenConfig data json.loads(response) return GenConfig( promptdata[prompt], negative_promptdata.get(negative_prompt, ), cfg_scalefloat(data[cfg_scale]), motion_scalefloat(data[motion_scale]), seedint(data.get(seed, 42)), round_idlen(history) 1, )这里有一个容易被忽略的设计Agent 看到的不是“原始视频”而是经过评估器压缩后的“分数 诊断文本”。这样做的好处是省 token、减少噪声并且让决策更聚焦。4.5 主循环最后是主循环。它负责把生成、评估、优化串起来并控制预算# main.py import json import os from PIL import Image from config import GenConfig from generator import I2VGenerator from evaluator import AdherenceEvaluator from agent import AgenticOptimizer, LLMClient def run_optimization( init_image_path: str, base_prompt: str, max_rounds: int 5, output_dir: str outputs, ): os.makedirs(output_dir, exist_okTrue) init_image Image.open(init_image_path).convert(RGB) # 初始化组件 generator I2VGenerator(model_idyour-awesome-i2v-model) evaluator AdherenceEvaluator() llm_client LLMClient() # 需要实现 chat() agent AgenticOptimizer(llm_clientllm_client) search_space { cfg_scale: [5.0, 12.0], motion_scale: [0.5, 1.5], seed: 任意整数, } history [] best_config None best_score -1.0 # 第一轮使用初始配置 current_cfg GenConfig(promptbase_prompt, round_id1) for round_idx in range(1, max_rounds 1): print(f[Round {round_idx}] 生成视频...) frames generator.generate(init_image, current_cfg) print(f[Round {round_idx}] 评估一致性...) score evaluator.score(init_image, frames) # 保存中间结果 frames[0].save( os.path.join(output_dir, fround_{round_idx}_first_frame.png) ) # 记录历史 history.append({ config_text: current_cfg.to_text(), score: score, frames: frames, # 工程中建议只存路径避免内存占用 }) print( f[Round {round_idx}] mean_sim{score[mean_sim]:.3f}, fmin_sim{score[min_sim]:.3f} ) # 更新最优结果 if score[mean_sim] best_score: best_score score[mean_sim] best_config current_cfg # 达到阈值则提前终止 if score[mean_sim] 0.92: print(达标提前终止优化。) break if round_idx max_rounds: break print(f[Round {round_idx}] Agent 分析并生成新配置...) current_cfg agent.propose(history, search_space) # 输出最优配置 print( 优化完成 ) print(f最优 mean_sim: {best_score:.4f}) print(f最优配置:\n{best_config.to_text()}) with open(os.path.join(output_dir, best_config.json), w, encodingutf-8) as f: json.dump(best_config.__dict__, f, ensure_asciiFalse, indent2) if __name__ __main__: run_optimization( init_image_pathassets/sample.png, base_prompta dog running on the grass, max_rounds5, )到这里一个完整的 “Agentic Optimization for Image-to-Video Adherence” 最小原型就成型了。它的结构非常清晰生成器、评估器、Agent 三者解耦任何一环都可以替换。比如你把 CLIP 评估换成视频专用评估模型或者把阈值逻辑换成更复杂的规则都不需要改动主循环。5. 评估指标设计如何量化 Adherence评估器是整个优化闭环的“指挥棒”。如果指标选错了Agent 优化得再好也没用。这里展开讲一讲常用的 Adherence 评估方式。5.1 第一帧与全程相似度最简单也最常用的做法是用 CLIP 或 SigLIP 等视觉模型的 embedding计算参考图与视频帧的余弦相似度。per_frame_sim[i] cosine(embed(init_image), embed(frame_i))然后统计first_sim第一帧相似度反映“初始条件是否对齐”。mean_sim全程平均反映整体保真度。min_sim最差帧反映是否出现严重漂移。std_sim相似度波动波动越大说明稳定性越差。建议同时关注mean_sim和min_sim。只看均值可能漏掉“后半段突然崩坏”的问题。5.2 人脸身份相似度如果参考图含人物建议增加人脸身份相似度评估。常见方案是使用 FaceNet、InsightFace 或 ArcFace 提取人脸 embedding然后计算余弦相似度。这类指标对“换脸”“身份漂移”非常敏感比 CLIP 更细粒度。要注意的是只有检测到人脸时才计算否则会拉低均值。5.3 构图与结构相似度数值相似度解决不了“位置对不对”“布局是否一致”的问题。可以用SSIM结构相似性逐帧与参考图比较结构。IoU如果任务有分割掩码可以比较主体区域的交并比。关键点距离如果任务是人体动作可以用姿态关键点计算平均距离。这类指标一般用于特定领域的强约束场景。比如电商商品图主体必须在画面中央那么一个“中心偏移量”指标就比 CLIP 更有用。5.4 时间一致性Adherence 不只是“每一帧像参考图”还包括“视频是否自然连续”。常见做法是计算相邻帧的光流误差或感知相似度temporal_score 1 - mean(cosine(frame_i, frame_{i1}))但这里有一个误区时间一致性太高可能意味着视频“不动了”。所以通常要结合运动强度指标如光流平均幅度一起看。5.5 多指标组合实际工程中推荐把多个指标加权组合成一个综合分同时保留各维度明细adherence_score w1 * clip_sim w2 * face_sim w3 * layout_sim w4 * temporal_sim权重根据业务场景标定。人物口播类任务face_sim权重拉高商品展示类任务layout_sim和clip_sim权重要高一些。在给 Agent 的提示词里不要只给综合分要把各维度分数都传进去。这样 Agent 才能判断“这轮失败是身份漂移还是布局改变”从而采取不同的修复策略。6. 常见问题与排查思路问题现象常见原因排查与解决方案Agent 每轮生成的配置几乎一样历史信息不足或 LLM 输出被温度参数限制把完整历史记录传入调高 temperature加入“与上一轮不同的要求”LLM 返回的不是合法 JSON提示词约束不够或模型输出被截断在 system 提示中强制只输出 JSON增加重试与解析兜底优化几轮后得分不升反降只看单轮最优缺少“保底策略”记录历史最优配置下一轮配置如果评分低于历史最优回退或加扰动评估分数和肉眼观感不一致单一 CLIP 指标无法覆盖复杂语义加入人脸、结构、运动等维度人工抽检标注建立小规模评测集生成耗时太长优化轮次不够视频生成本身昂贵评估也在排队降低视频帧数做快速验证两阶段策略低分辨率搜索 高分辨率精调Agent 修改了超出范围的参数没有在提示词中声明参数边界在 search_space 中明确类型与范围解析后做 clamp 校验同一 prompt 反复生成结果差异大seed 未固定或采样器本身随机性高固定 seed或固定一组 seed 做多次生成取平均这里重点说一下“回退策略”。工程上不要无条件信任 Agent 的每一次提议。我建议在循环里维护一个best_config每轮生成后和新配置对比。如果新配置连续两轮都没有超过历史最优就强制让 Agent 参考“历史最佳配置”重新提议而不是继续在次优区域打转。7. 最佳实践与工程建议7.1 把评估器和生成器做成可插拔接口这是整个方案能否长期演进的关键。今天你用开源模型明天可能换成商业 API今天你用 CLIP明天可能换成视频理解大模型。只要接口不变上层 Agent 和主循环几乎不用改。7.2 建立小规模评测集不要只调单张图单张图的优化结果很容易过拟合。建议准备 2050 张有代表性的参考图覆盖不同主体类型人物、商品、动物、不同光照、不同构图。每次优化改动先在评测集上跑一遍看平均分是否提升。7.3 分阶段优化视频生成成本高建议采用两阶段策略阶段一低分辨率 / 少帧数 / 快速验证搜索 prompt 与主要参数。 阶段二确定最优区间后用高分辨率 / 完整帧数精调。这能显著节省计算资源。7.4 日志与可追溯性每一轮生成至少记录完整配置参数。各维度评估分数。诊断文本。首帧输出路径。Agent 本轮输出的原始文本与解析后结果。有了完整日志你才能复盘“为什么第 3 轮得分大涨”“为什么 Agent 开始乱改参数”。7.5 注意安全与合规边界Image-to-Video 涉及人脸、肖像、商品版权等敏感内容。工程落地时要注意对参考图做内容审核过滤违规内容。人脸生成必须获得当事人授权避免深度伪造风险。涉及品牌商品的视频生成确认是否有版权限制。评估与优化系统只用于合法合规的创作场景。7.6 控制 LLM 调用成本每轮优化都要调用 LLM成本虽低但也要控制。常见做法每轮只把“最近 3~5 轮”的历史记录传给 Agent而不是全部历史。汇总历史时用“分数最高的配置”和“最近一轮配置”作为重点。对 Agent 返回的配置做结构化解析节省输出 token。8. 总结与学习路线这篇文章围绕Agentic Optimization在Image-to-Video Adherence问题上的应用从概念到原型实现做了完整梳理。核心收获可以归纳为三点Adherence 是一个多维问题不能只看首帧像不像还要关注身份、外观、构图、语义、运动等多个维度。Agentic Optimization 的核心是“生成-评估-反思-改进”闭环它比网格搜索和人工试错更适合参数空间大、失败原因语义化的生成任务。评估器是整个系统的指挥棒多维可解释的评估结果是 Agent 做出有效决策的前提。下一步你可以从这几个方向继续深入把评估器从 CLIP 升级为视频理解模型加入时间维度的语义一致性判断。用更强的人脸/姿态专用模型替换通用视觉模型做细分场景优化。在 Agent 中加入“工具调用”让它不仅能改参数还能自动执行更复杂的操作比如局部重绘、插帧后处理。尝试把优化结果沉淀为“经验库”下次遇到类似参考图时直接复用最优配置。AIGC 生成的质量问题本质上是一个“用更高阶的智能去驾驭生成模型”的问题。Agentic Optimization 提供了一条可行的路径让机器替你分析失败、制定策略、迭代验证把人力从无休止的试错中解放出来。如果你正在做视频生成相关的工具链或质量评测系统建议先跑通本文的最小闭环再逐步接入业务指标。动手试一试你会发现“抽卡式调参”并不是唯一的路。