ARTICLE · INTELLIGENCE

战地情报 · 详情页

来自尧图项目组的一线实战观察与深度解析

提示词工程实战:从三层结构到Midjourney参数与回归测试

提示词工程实战:从三层结构到Midjourney参数与回归测试

简介:这份指南围绕AI艺术与ChatGPT的提示工程展开,面向初学者与进阶创作者,帮助理解提示构成、主题与修饰符的作用,并讨论负提示、零提示与对话式提示的适用边界,同时把迭代式细化、ReAct提示等策略用于图像生成和对话式应用。内容以提示工程基础、负提示与零提示、技能进阶、AI艺术提示设计、对话式提示工程、语言与意象的力量等章节为主线,拆解主体、修饰符、变体与负面提示等要素,并配有应用案例与示例提示,便于从基础概念到工具实操形成较完整的路径。资源包为1个PDF文件,约2.31MB,轻量便携,适合按章节阅读与查阅。已有69人学习,对希望提升提示精度、减少试错的读者有参考价值。可从中获得提示结构拆解、优化思路与工具实践示例,用于AI绘画和对话交互场景。

1. 一份把提示词当工程文档拆的指南,适合谁

前阵子帮人看一屏 Midjourney 出图,同一条提示词,一个人跑出来是灰蒙蒙的水泥森林,另一个人跑出来是晨雾里的玻璃温室。模型版本一样,参数一样,差别全在提示词写得够不够「可执行」。这份《AI 艺术与 ChatGPT 提示工程指南》走的就是这条路:把提示词当成可拆解、可复用、可回归验证的工程对象,而不是碰运气的咒语。全书从主体提示、修饰符、固化词这些基础构件讲起,一路推到 ReAct 提示、迭代式细化,以及 Midjourney 与 Leonardo 的画面控制。它适合两类人:刚上手 AI 绘画和对话模型、想摆脱「随便写写」的从业者;以及已经在用但输出飘忽、需要一套收敛方法的设计与产品岗。

2. 提示词的三层结构:主体、修饰符、固化词怎么叠

一条提示写崩,八成不是模型不行,而是三层结构里有一层缺了或者混在一起。指南第一章把提示拆成主体、修饰符、固化词,再加上变体提示和负提示,这个分法看着朴素,落到实操里非常省事——因为它给了你一个「哪一层出问题就改哪一层」的定位坐标,而不是每次出图不对就整条重写。

2.1 主体提示先定焦点,不然后面全是白写

主体可以是人、地点或物,任何构成提示核心的东西。定义主体这一步要做三件事:说清这次要产出什么、想清谁会看这张图、挑出能落地的关键词。第三件事最容易被跳过,也最容易翻车。

关键词的判断标准只有一条:这个词能不能被画出来、被验收。「氛围感」不行,「霓虹灯在积水里的倒影」行;「高级」不行,「低饱和、大留白、单一光源」行。处理大体量素材时这一点更明显,模糊词会让模型在几十个方向里随机挑一个,你要复现的时候完全无从下手。

受众这一层常被忽略。给电商详情页做主图,主体周围必须留出文案位;做概念设定,主体就得留出想象空间。同一个「未来城市」,两种用途的提示写法不应该是同一套。

写法提示片段问题改法
模糊一个漂亮的未来城市「漂亮」不可执行玻璃幕墙、空中连廊、黄昏侧光
多主体城市、飞船、人物、宠物权重互相抢只留城市,其余降权或进负提示
抽象有故事感无法翻译成画面半开的门、地上的长影、逆光剪影

语言精确度对结果的影响是指数级的,不是线性的。含糊的描述会让模型在语义空间里做一次大范围随机采样,精确的描述把采样范围压到一个窄区间,这才是「稳定出图」的真正来源。

2.2 修饰符负责给方向和质感

修饰符是加在提示里的额外词或短语,用来提供上下文、清晰度、具体性。它的作用不是「让提示变长」,而是把主体的表现方向收窄。指南里的例子很直白:把「全球变暖」改成「全球变暖的成因与解决方案」,输出就从泛泛而谈变成有结构的分析;把「健康饮食」改成「简单可操作的饮食建议」,输出就从科普变成能落地的清单。

落到图像上,修饰符我一般分四个维度来配,每个维度挑一到两个,总数压在 3 到 5 个:

  • 风格:cinematic photography、flat illustration、risograph print
  • 材质质感:film grain、matte plastic、brushed metal
  • 视角镜头:low angle、wide lens、macro shot
  • 情绪光线:overcast、tungsten warm、cold fluorescent

超过 5 个修饰符,边际收益迅速衰减,甚至会互相稀释——「柔光」和「硬光」同时写,模型会给你一个既不通透也不锐利的中间态。经验值是:一条提示里出现两个以上互相矛盾的修饰符,这条提示基本就废了。

修饰符还有一个很实用的用法,就是给输出「加人味」。同一段机器生成的文案,加上「用口语、举一个具体场景、别用行业黑话」这类修饰,可读性会立刻不一样。这不算玄学,本质是把你的偏好翻译成了模型能对齐的约束。

2.3 固化词把「感觉」压成硬约束

指南里提到的 solidifier,我习惯叫固化词。它和修饰符的区别在于:修饰符是「往哪个方向走」,固化词是「必须满足什么」。前者影响风格,后者影响可验收性。

文本场景下,固化词是输出格式、段落数、字数区间、必须包含的字段、禁止出现的表达。图像场景下,固化词是画幅比例、媒介、光照方案、构图法则、主体占比、留白位置、渲染方式。

一条固化词写得好的提示,标志很明确:拿到结果之后你能逐条打勾。比如电商主图的固化词可以写成——1:1 画幅、主体占画面 60%、留白集中在左上角、纯色背景、画面内无文字、无人物。这六条里任何一条不满足,就是这次生成失败,不需要再争论「好不好看」。

提示:固化词写在修饰符之后、参数之前。位置靠后,模型对它的遵循度通常更高一些,尤其是格式类约束。

2.4 用一段代码把三层拼起来

手写提示写到几十条之后,靠脑子记结构一定会乱。我一般用一个小的组装器把这四层固定下来,改动时只动对应字段,不碰整条字符串。

# prompt_layers.py # 把一条提示拆成四层,方便逐层调参、逐层留档 from dataclasses import dataclass, field from typing import List @dataclass class PromptSpec: subject: str # 唯一主焦点,一句话说清 modifiers: List[str] = field(default_factory=list) # 3~5 个,分维度挑 solidifiers: List[str] = field(default_factory=list) # 必须可验收的硬约束 negatives: List[str] = field(default_factory=list) # 只写要排除的名词 def render(self, sep: str = ", ") -> str: parts = [self.subject] parts += self.modifiers parts += self.solidifiers text = sep.join(p.strip() for p in parts if p.strip()) if self.negatives: # 负提示单独成段,避免和正向词混排后被模型当成描画对象 text += f" --no {', '.join(self.negatives)}" return text if __name__ == "__main__": spec = PromptSpec( subject="雨夜的旧城区十字路口,便利店灯牌亮着", modifiers=["湿沥青反光", "低机位视角", "青橙对比"], solidifiers=["16:9 画幅", "广角镜头", "无人物出镜", "左侧留白"], negatives=["文字", "水印", "过曝"], ) print(spec.render())

这段代码没什么技术含量,价值全在结构上。subject是唯一主焦点,写两个以上就相当于放弃了焦点控制;modifiers用列表而不是长字符串,是为了逼自己按维度挑选,而不是想到什么加什么;solidifiers和negatives分开存,是因为它们的修改时机完全不同——前两层在探索阶段反复动,后两层一般在收敛阶段才定稿。

render()里的sep参数值得单独说一句。Midjourney 这类工具用逗号分隔最稳,但有些工具对换行更敏感,把分隔符做成参数就不用改代码。负提示单独拼--no段,是因为负向词一旦和正向描述混在同一个逗号序列里,很容易被模型当成「要画的东西」,这个坑后面还会再提一次。

2.5 零提示与负提示:什么时候用,什么时候别用

零提示就是不给示例、不给上下文,直接下指令。优点是快,缺点是完全不可控。我的用法是把它当探测工具:同一个问题连问五次,看模型往哪些方向偏,偏出来的那些方向就是你需要补约束的地方。它不适合做正式产出,但很适合做第一轮摸底。

负提示是写你要排除的东西。这里最常见的错误是把它写成否定句——「不要模糊」「不要有噪点」「不要出现文字」。不少模型对否定结构的处理并不理想,容易把「模糊」「噪点」拆成关键词反而强化。正确写法是只写名词,一词一条,放进独立的负提示字段。

错误写法问题建议写法
不要模糊否定句被拆词,「模糊」反被强化模糊
画面里不要有水印和文字句子太长,权重被稀释水印, 文字
别太暗也别过曝双向否定,模型无法解析欠曝, 过曝

3. ReAct 提示与迭代式细化:让输出从「能看」到「能用」

出图能看和能用之间隔着一整套收敛流程。指南把 ReAct 提示和迭代式细化放在一起讲,逻辑是通的:ReAct 解决「过程可追溯」,迭代细化解决「结果可复现」。前者管多步推理,后者管单条提示的打磨节奏,两个工具配合起来,才谈得上把 AI 输出纳入工程流程。

3.1 ReAct 的三个字段:思考、行动、观察

ReAct 的思路是把模型的回答拆成三段:先写思考(Reasoning),再决定做什么动作(Acting),拿到观察结果(Observation)之后进入下一轮。它的价值不在于「让模型更聪明」,而在于把一次性憋答案变成了可检查的过程链。

在只有对话模型的场景里,动作可以是列提纲、拆子问题、换个角度重述、交叉自查。真正的硬约束只有一条:观察结果必须来自外部,不能由模型自己编。这条约束不落实,ReAct 就会退化成一段看起来很专业、实际上全是编的推理表演。

我一般会在提示里显式规定三段格式,并且要求每一轮结束时输出「本轮结论一句话」。轮次上限设 4 轮,超过基本就是在原地打转,继续下去只会把上下文越堆越乱。

3.2 迭代式细化的四轮收敛法

迭代细化的核心不是「多改几次」,而是「每次只改一个变量,并且留快照」。改三个变量然后发现效果变差,你根本不知道是哪个改坏的,只能整条回退,前面几轮的收获全丢。

轮次本轮只改观察指标停止条件
R1主体与构图主体是否唯一、位置比例是否合理主体识别无误
R2风格与质感风格词是否真的体现在画面上连续两张稳定命中
R3细节与负向瑕疵是否减少、有没有引入新瑕疵瑕疵不再新增
R4参数与固化词画幅、光照、留白是否逐条达标能逐条打勾

四轮跑完还没收敛,通常不是提示的问题,而是主体本身选错了——比如要求一个模型画出它训练数据里几乎没有的东西。这时候继续磨提示是浪费时间,换方案更快。

每一轮结束后要留快照,内容包括:完整提示词文本、参数、生成工具、本轮改了什么、一句话结论。这条记录后来会救你很多次,尤其是隔了一周客户说「还是上一版好」的时候。

3.3 一个可跑的 ReAct 循环骨架

真正要防的是模型自己填观察字段。下面这段代码不负责调模型,只负责在结构上卡住这个漏洞。

# react_trace.py # 只做结构约束:每轮必须落 thought / action / observation 三字段 from dataclasses import dataclass from typing import List, Optional @dataclass class Round: thought: str action: str observation: Optional[str] = None # 必须由外部工具或人填,模型不得自填 def close(self, observation: str) -> "Round": if not observation or observation.strip() == "": raise ValueError("观察结果为空,本轮不成立") self.observation = observation return self def check(trace: List[Round]) -> bool: for i, r in enumerate(trace, start=1): if r.observation is None: raise RuntimeError(f"第 {i} 轮缺少观察结果,推理链断裂") return True

close()是整个骨架的关键。它把「填观察结果」变成一个必须显式调用的动作,而调用方是外部脚本或者你自己,不是模型。模型只能产出thought和action,observation空着,链条就不完整,check()直接报错。

check()放在提交前跑一遍,作用类似黑匣子——出问题时能一眼看出断在第几轮。轮次上限建议写在调用层,不要写进Round结构里,这样换任务时不用改数据结构。

3.4 对话式提示工程:把多轮当状态机

多轮对话最大的问题是上下文漂移。聊到第十轮,模型对你最初定的格式要求已经记不清了,输出开始走样。解决办法不是每次重发一遍全部要求,而是设一个锚点段落,隔几轮重述一次。

# anchor.py ANCHOR = """角色:{role} 目标:{goal} 输出格式:{format} 硬约束:{constraints} 禁止:{forbidden} 回答前先用一句话复述上述要求,再开始作答。"""

role写清楚模型扮演什么,goal一句话说清这次任务的终点,format必须具体到字段名或段落结构,constraints放字数、条数、必须覆盖的点,forbidden放不要出现的表达和不要展开的方向。

最后那句「回答前先复述」是个低成本自检。模型复述错了,说明它理解偏了,这时候纠正的成本远低于等它输出完一大段再回滚。

4. Midjourney 与 Leonardo:把语言意象翻译成画面参数

文本提示和绘画提示的差别,不在词汇量,而在「有没有物理约束」。文字可以写「他很孤独」,画面必须写成「一个人坐在长桌尽头,头顶一盏灯,其余座位空着」。指南里专门用一章讲语言与意象,讲的就是这个翻译过程。这一章把翻译过程拆成可操作的段落结构、参数表和工具差异。

4.1 Midjourney 提示的分段写法

我把 Midjourney 提示固定成六段:主体、场景、风格媒介、光照、镜头构图、参数。顺序固定下来之后,出问题时能快速定位是哪一段拖后腿。

# mj_prompt.py def mj_prompt(subject, scene, style, light, camera, params=""): body = ", ".join(x.strip() for x in [subject, scene, style, light, camera] if x.strip()) return f"{body} {params}".strip() print(mj_prompt( subject="a rain-soaked crossroads at night", scene="old town street, a convenience store sign glowing", style="cinematic photography, fine film grain", light="mixed cyan and orange light, reflections on wet asphalt", camera="low angle, wide lens, deep depth of field", params="--ar 16:9 --no text, watermark --stylize 200", ))

subject和scene分开写,是因为它们的修改频率完全不同:主体定了基本不动,场景可以反复换。style控制在两到三个词,多了会互相打架。light是图像提示里性价比最高的一段,光源方向、色温、反射介质这三件事写清楚,画面质感能上一个台阶。camera负责空间关系,低机位加广角会天然带出压迫感。

params单独抽出来,是为了让参数和描述解耦。同一套描述换不同画幅做 A/B,只改这一个参数就行。

4.2 参数与权重:几个常用项的边界

参数/语法作用常用取值注意
--ar画幅比例1:1、16:9、9:16改了画幅,主体位置要重调
--no排除元素名词列表只写名词,别写句子
--stylize风格化强度0–1000,常用 100–400调太高会盖掉主体细节
--chaos结果多样性0–100调高之后基本不可复现
::分段权重主体2::背景::1权重差超过 3 倍容易失衡

--stylize是最容易被滥用的一个。很多人出图不够「有感觉」就一路往上加,结果主体被风格彻底淹没,人脸糊成一团。我的习惯是从 200 附近起步,需要更写实就往下压,需要更插画化再往上加,一次调 100,不跳档。

::权重语法的用法是给每一段单独标权。写a red car::2, city street::1表示车的权重是街道的两倍。这个语法很有效,但差距不能拉太开,主体2对背景0.5已经接近极限,再大就容易出现结构崩坏。

--chaos在探索阶段有用,能一次给你四种完全不同的构图,帮你找方向。但一旦进入收敛阶段就必须归零,否则你永远拿不到第二张一样的图,迭代细化的前提直接没了。

4.3 Leonardo 的负提示与引导强度

Leonardo 的面板结构和 Midjourney 差别不小,最直观的一点是它有独立的负提示输入框,不用挤在参数里写--no。做需要精确排除的活(比如不能出现文字、不能出现多余手指),这一点比命令行参数好用得多。

几个参数的实际手感:

Guidance Scale 控制提示词对生成结果的约束强度。偏低画面松散、不贴提示,偏高会僵硬、色彩发死、细节过度锐化。常见做法是先取中间值出一张,然后上下各走一步,看哪一侧更接近目标,不要一次跨太大。

Image Guidance 是垫图强度。垫太高等于在描图,风格被参考图完全锁死;垫太低等于没垫,白费一张好参考。这个参数和参考图的构图复杂度强相关,抽象参考可以垫高,复杂参考要压低。

Prompt Magic 会对提示做一次自动增强。好处是短提示也能出细节,坏处是你对画面的控制权被分走了一部分。做需要稳定复现的商业图时我一般会关掉它,宁可自己把提示写长。

注意:不同工具对同一个语义的处理方式并不一致,同一套提示在 Midjourney 和 Leonardo 上跑出来的差异,经常比调参数的差异还大。换工具时不要直接搬参数,只搬描述层。

4.4 语言与意象:抽象词怎么落到视觉词

这是整本书里我觉得最实用的一节。抽象词不能直接进提示,必须先翻译成画面元素。

抽象描述落不到画面的原因可执行的视觉词
高级感无对应视觉特征低饱和、大留白、单一光源、哑光材质
科技感语义太宽泛冷白光、玻璃反射、几何线条、无尘表面
治愈情绪词暖色温、柔焦、晨光斜射、织物纹理
压抑情绪词顶光、窄画幅、深灰调、封闭构图
未来时间概念无缝曲面、悬浮结构、冷色补光

翻译的时候有个小技巧:先问自己「如果只能用一张照片证明这个词,我会拍什么」。答不上来,说明这个词还没被翻译完。

中英混写这件事也值得说清楚。中文负责组织语义和逻辑关系,英文负责提供视觉关键词,原因是主流绘图模型的训练语料里英文视觉词密度更高,同一个概念用英文往往命中更准。但两段要分开写,不要一句中文里塞三个英文词,那样容易在分词阶段被切碎,风格词直接失效。

5. 避坑与排查:五类翻车现场的记录

下面这五条是实打实踩过的,按现象、原因、解决三段来写。顺序大致按出现频率排,前两条几乎每个新手都会撞上。

5.1 主体越写越长,画面反而发散

现象:提示词写到八十字,出图里元素一堆,但没有一个能当视觉中心。

原因:多个主体挤在同一层级抢权重,模型只能平均分配注意力,结果每个都画了一半。修饰符堆太多也会造成同样效果——每个词都在争夺「这条提示到底在说什么」的解释权。

解决:一条提示只保留一个主焦点,其余降权到::0.5以下,或者干脆移进负提示。写完先数一遍,主语超过两个就砍。修饰符按维度挑,同一维度只留一个。

5.2 负提示写成了正面句子

现象:明明写了「不要模糊、不要噪点」,出来的图反而更糊更脏。

原因:否定结构在部分模型里会被拆成关键词,「模糊」「噪点」作为高频视觉词被保留下来,否定词本身被丢弃。写负提示等于在给画面加元素。

解决:负提示只写名词,一词一条,放进独立字段。写完自查一遍,凡是带「不要」「别」「避免」的,全部删掉前缀重写。

5.3 ReAct 里模型「假装」查了资料

现象:推理链写得很完整,每一步都有小结论,但引用的数据、日期、来源全都对不上。

原因:观察字段是模型自己生成的。没有外部输入的情况下,模型会把「可能长这样」的结果当成事实填进去,整条链看起来无懈可击,实际上从第一步就是编的。

解决:在结构上堵死这条路。观察字段留空,由外部脚本或人工填写,填完再进入下一轮。链条断在哪一轮,一眼就能看出来。

5.4 迭代细化越改越糊

现象:改了七八轮,画面离最初那版越来越远,也说不上哪里不对。

原因:每轮改多个变量,加上没有留快照,出问题之后无法定位,只能继续往前改,误差一路累积。

解决:一次只改一个变量,其余全部冻结。每轮存一份完整记录:提示文本、参数、改了什么、结论。改坏了直接回滚到上一版快照,不要试图在坏版本上修复。

5.5 中英混写导致关键词被吃掉

现象:中文描述里嵌了几个英文风格词,出来的图完全看不出那些风格。

原因:中英混排时标点用得乱,英文词被长中文句包住,在分词阶段就被稀释掉了。多个英文词连写也会互相干扰。

解决:中文一段、英文一段,用明确的分隔符断开;英文视觉词两到三个一组,不要连成一长串。改完对比一次纯英文版,确认风格词是否真的生效。

6. 台账与回归测试:把一次成功变成可复现

做到这一步,单条提示已经能稳定出结果了。真正拉开差距的是下一步:把成功的那些提示变成可复用的资产。

我在项目里会建一张提示词台账,字段不多但每条都填:编号、用途、完整提示文本、参数、工具与版本、迭代轮次、当时的结论、缩略图路径。填的时候别嫌烦,隔两周再回头看,没有台账的提示词基本等于丢了,你只能凭记忆重写,而重写出来的东西一定和原来不一样。

台账之上再做一层回归测试。做法很土但有效:从台账里挑出十条核心提示,每次换工具版本、换参数、换模型,都把这十条跑一遍,把结果和旧图并排看。指标不用复杂,三档就够——主体是否还在、风格是否还在、瑕疵是否新增。三项里有两项退化,就说明这次变更不能上生产。

检查项判定标准处理
主体保持主焦点位置、比例、识别度不变退化则回退参数
风格保持色调、质感、光线方向一致退化则回退风格词
瑕疵不新增文字、多余肢体、结构错乱未增加新增则补负提示

这套流程还有个副作用,就是能治好「凭感觉调参」的毛病。以前改参数全靠手气,有了基线对比之后,你会很快发现很多参数其实一直在做无用功,真正影响结果的只有两三个。

还有个小技巧值得单独拎出来:把台账里的提示词按「场景」而不是按「工具」归档。同一套描述层,在 Midjourney 上可能换个参数就能用,在 Leonardo 上可能只需要调整引导强度。按工具归档会让这些复用机会全部沉底。

提示:回归测试的样本量不必大,十条足够,但必须固定。样本一变,前后就没有可比性了。

从那以后我每次接新的出图需求,都强制先建一个空台账,第一条记录一定是在需求确认当天写下的,哪怕当时提示词还是半成品。这个习惯救过我两次——客户中途改需求,我能翻出三周前哪一版最接近他最后想要的效果,直接回滚加微调,而不是从零再来一遍。希望帮到你。

本文还有配套的精品资源,点击获取

RELATED READING

延伸阅读

更多一线实战笔记与深度复盘,助您持续精进