第一次读到《大象万镜》里“雾散柴门见酒旗,山家日午始开扉”这两句时,我盯着屏幕愣了一会儿。不是震惊于AI能写古体诗——那早就不稀奇了——而是这两句带着一种很少见的“日常感”。以前我批量产AI古诗,得到的多半是“苍山”“白鹤”“幽谷”的排列组合,一眼就能闻出机油气。后来我们小组内部做诗歌整理实验,把《大象万镜》当作一个长期的合集项目来经营,这两句成了我反复琢磨的样本。这篇文章主要写给三类人看:一是正在做AI文学创作工具、被生成内容“空泛感”困扰的开发者;二是业余写古诗、好奇模型怎么工作的创作者;三是单纯想理解“AI作诗质量高低到底差在哪”的读者。我会从这两句诗切入,拆解《大象万镜》背后的意象库、主题控场、格律约束、质量筛选与人工改写全流程,尽量把能直接复用的方法和参数都交代清楚。1. “雾散柴门见酒旗”到底好在哪里:先做一次逐层拆解1.1 画面里的时间与空间:雾、柴门、酒旗是怎么咬合的先看第一句。“雾散”是一个时间状语,也是一个视觉条件的切换。雾气退去,视野从模糊转向清晰,在这条清晰的视线末端,出现的是“柴门”和“酒旗”。这里有个很关键的层次:柴门是近景,酒旗可以是远景,也可以挂在柴门旁边。无论是哪种,句子都天然安排了一个由近及远、由静态到动态的空间关系。“酒旗”这个物象特别值得说。它不是孤立的装饰物,而是一个商业信号,暗示附近有人家、有村店、有能坐下来喝一杯的地方。中国古代村落里的酒旗常常挂在道旁、桥头、柴门不远的位置。所以“雾散柴门见酒旗”一句,不只是在写景,还在写“人”,写人的活动痕迹。第二句“山家日午始开扉”则把时间又往后推了一步。日午已经是正午,雾气早该散尽了,而这个山间人家这个时候才开门。这个“始”字用得很有余味,既说明山家的生活节奏与城镇不同,不必天不亮就开张,也给读者留下了想象空间:门里的人刚吃完午饭?还是一直在睡?或者是在等一位约定好午后到访的客人?两句连起来,从清晨雾散到日午开门,时间轴上有一个自然的推进。这种推进不靠“朝”“暮”之类的标签直接点明,而是通过光线、湿度和动作来体现。AI生成的句子最怕逻辑断裂,这两句却恰恰在时间与空间上咬合得很紧。1.2 为什么机器写惯了的句子,偏偏这里少了“塑料味”我以前测试过很多生成模型,它们写出来的古诗最明显的共同问题是:名词密度高、动词敷衍、情绪标签前置。比如随手就能生成“孤舟远水寒江暮,独客青山老树秋”,看起来每个词都符合古诗审美,但凑在一起却像一副没有骨架的古风壁纸。原因是模型在高概率空间里打转,高频意象“孤舟”“老树”“寒江”互相组合,概率很高,读者也眼熟,但句子之间没有实际视线,没有人,没有时间。“雾散柴门见酒旗”不一样。它里面最见功力的一个字是“见”。这个动词不是凭空出现的,它隐含了一个观察者。“雾散”之后“见”,说明有人在这个时间点注视外头。你甚至可以脑补出一个早上起来推开窗户或走到院子里的人,看见雾气退开,远处酒旗渐渐清楚。这个“见”把原本纯风景的句子变成了有叙事的句子。相比之下,很多AI候选句子喜欢用“掩”“隐”“映”,因为这类动词非常“安全”。但“掩”会让柴门挡住酒旗,逻辑上反而说不通;“隐”与“见”相比,缺少了观察者主动获取信息的动作;“映”则太强调色彩反光,放在清晨雾气里并不合理。AI无法自动理解这些细微差别,但当一个句子刚好绕开了这些陷阱,它就会有那么一点“人味”。1.3 若按近体诗的标尺量一量,它其实站在古体一边有读者可能会问:这两句能算严格的近体诗吗?我按普通话粗测了一下平仄。“雾散柴门见酒旗”大约是“仄仄平平仄仄平”,“山家日午始开扉”大约是“平平仄仄仄平平”,单看平仄骨架,确实接近七言律句的交替节奏。但如果按近体诗的规则,首句平收通常要求首句入韵,“旗”和“扉”在平水韵里也不是同一韵部。因此这两句更像古体联句的吟咏方式,保留格律的气息,但不走近体诗的严格韵部流程。这其实给我一个提示:如果AI强行把这两句改写成标准的近体绝句前两句,大概率会牺牲“日午始开扉”这种松散、日常的节奏。诗歌不是格律测试题,格律是骨架,气才是血肉。这一点在后续的工程化处理里非常重要,我们不能让格律约束反过来杀死语感和叙事性。2. 《大象万镜》背后的生成管线:意象库和主题控场是两条腿2.1 先有物象,再谈诗意:意象标签库怎么搭《大象万镜》这个项目名里有个“镜”字,我挺喜欢这个隐喻:AI像一面镜子,把语料里的意象碎片映照出来,再由人决定哪些碎片值得摆在一起。为了让镜子映照出足够丰富的意象,我们最先做的事情不是调模型,而是搭意象库。我们收集了数千首唐以来的古体诗与近体诗文本,把诗里出现的名物名词都抽出来,按物象类别、光线条件、动静状态、温度感、情绪色彩做标签。以“酒旗”为例,它的标签大概是:类别:市井/商业物象动态:可摆动、可悬挂光线提示:适合晨光、薄雾、日暮声音提示:旗动无声,但能暗示人声情绪色彩:烟火气、温暖、招待感常见位置:村口、道旁、桥头、柴门侧这套标签不是为了给文学研究者写注释,而是为了让模型的采样有方向。模型本身没有“柴门旁边要有酒旗”的概念,它只学统计。我们把这些标签作为条件输入,让模型在生成时优先选择与当前场景匹配的意象词。如果只做这一步,效果仍然有限。因为模型还是会偷懒,在候选词里挑概率最高的。真正管用的是把意象库和主题控场结合起来。2.2 主题控场:不让模型一开口就是“江海”“孤舟”自由生成模式下,模型最容易落进高频意象的引力井。你让它写山村,它给你“孤村”“老树”“寒鸦”;你让它写清晨,它给你“晓风”“残月”“霜天”。这些词不是错,而是被用过太多次,失去了具体感。《大象万镜》的做法是提前给模型一个“场景摘要”,要求生成前先拆出地点、时间、天气、人物状态四个维度。比如针对这两句诗,场景摘要会是:地点:山中村落,柴门附近时间:清晨到正午之间天气:雾散转晴人物状态:没有急务,从容这四个维度会转化成一组主题向量,和模型内部的隐状态做加法。说白了就是给模型设限:你的想象空间是这座山村,别飞到江海边去。这个约束不需要太强,太强会生成出类似“柴门雾散酒旗风”这种被模板钉死的句子,太弱则会回到“江海孤舟”的老路。实际测试里,我们花在调整主题控制强度上的时间,远多于微调模型本身。控制太强,模型像填空;控制太弱,模型像说胡话。最终找到一个相对舒服的区间:场景摘要里的名词直接出现在句子的概率较高,但动词和形容词仍由模型自由发挥。这样既保证物象不跑偏,也给“见”“始”这类动词留出空间。2.3 场景锚点输入:以“雾散柴门见酒旗”为样例一个可以直接抄作业的流程是这样的:先让模型根据场景摘要生成二十个候选意象组合,再人工挑出五到八个锚点词,最后把锚点词作为前置约束重新生成诗句。“雾散柴门见酒旗”这组句子,如果拆开看,锚点词就是“雾散”“柴门”“酒旗”“日午”“开扉”。有意思的是,模型并没有自己把“雾散”和“见”连起来,这个“见”更像是在多次采样中出现的高质量偶然。所以我们把锚点词输入后,不会要求模型必须把每个词都用上,而是要求至少覆盖两个,剩余的词位留白。这样模型有足够的自由度去尝试“见”“闻”“隔”“挂”之类的动词。大量候选句里,你才能真正捞出“雾散柴门见酒旗”这种带着目光的句子。3. 格律是硬约束:AI产古诗最麻烦的一关3.1 普通话的平仄不等于古代韵书,映射表比模型参数更关键很多刚接触这个领域的人以为,只要让模型学会“一三五不论、二四六分明”,就能生成合规的格律诗。真正做起来才发现,普通话读音和古代韵书之间存在大量差异。同一个字,在普通话里是平声,在平水韵里可能是仄声;在不同语境下还可能多音多韵。如果只用现代汉语拼音做平仄规则,生成的句子常常会在懂格律的人面前露馅。我们的做法是给模型额外接两套表:一套是常用字古今平仄对照表,另一套是韵部表。生成时每个候选汉字都要先查表,确定它在当前语法位置上的声调归属,再判断是否与前后字构成交替节奏。这个过程听起来繁复,但编码实现并不复杂,核心是一个查询逻辑。这个环节里最容易踩的坑是:过于相信对照表,把每个字都当成固定平仄。实际上不少字在古诗里存在可平可仄的用法,需要结合具体的词性和语义来判断。我们的方案是保留一个“可平可仄”白名单,在格律校验遇到这类字时,不直接判死刑,而是降低权重。这样既照顾了格律,又不会误杀好句子。3.2 押韵约束的三种实现:重采样、受限解码、韵律分支押韵是AI写古诗的另一个大关。早期我们用的是“先生成、后检查”的方式,几十首里偶尔有一首押韵完美,大部分都押得不伦不类。后来尝试了三种更有效的办法,按实现难度从低到高排:第一种是重采样。先在无约束条件下生成候选句,用韵脚检查器扫描,把不符合当前韵部的候选丢弃,重新生成。好处是简单,坏处是浪费算力,而且模型可能为了迁就韵脚,把整句语义带偏。第二种是受限解码。在每一步选词时,如果当前句是偶数句且已经走到了句末字的位置,就只允许模型从目标韵部的候选字里选。这种方式能让韵脚百分之百契合韵部表,但需要提前确定整首诗押哪个韵,不能中途换。第三种是在微调阶段增加韵律分支。训练模型时把韵脚一致性作为辅助损失函数的一部分,让模型从统计上学会在句末自然地选择同韵字。这个方案效果最顺,但需要额外的数据和训练资源。我们在《大象万镜》里主要用受限解码,配合一个很小的重采样兜底。有一个值得说的细节:如果你的目标是古代韵部,却用现代语音模型做中途采样,两者会经常打架。比如“斜”这个字,普通话读xié,古韵里却常押xiá。我们最后把韵部映射表和现代拼音都放进约束函数,优先按古韵字表判定,但允许现代读者能接受的邻韵通押。传统和可读性之间需要找平衡,不能一味复古。3.3 对仗的弱约束实现:词性序列对齐与结构惩罚律诗中间两联需要对仗,AI也很容易在这里露出破绽。常见问题是“天对地”这种名词对名词没问题,但动词位置各说各话,或者上下句的字数节奏错位。我们采用了一个相对轻量的“词性序列对齐”方案:先给上句做分词和词性标注,得到一个序列,比如“名词-动词-名词-动词-名词”之类的结构;下句生成时,要求词性序列尽量与上句对齐,但不要求每个词的具体词义相对。这样既能形成工整结构,又避免了“必须柳对花、燕对莺”的机械感。在beam search解码时,我们还给“结构惩罚项”加了一个判断:如果下句的词性序列与上句的编辑距离超过阈值,这条候选的分数就下调。这个惩罚项不直接修改词汇,只影响排序,所以很少产生生硬感。实测下来,诗句的对仗合规率明显上升,同时保留了一些有趣的词义错位——对仗最迷人的地方本来就不在完全对应,而在于对应中的那一点偏转。3.4 一个可落地的生成流程配置示例统一整理一下《大象万镜》里比较常用的生成配置,你可以直接复制作为起点:gen_config = { "temperature": 0.9, "top_p": 0.92, "repetition_penalty": 1.2, "num_return_sequences": 40, "max_length": 32 } def apply_rhyme_penalty(logits, candidate_ids, target_rhyme_set): # 仅对偶数句句末位置生效 for i in range(len(logits)): if candidate_ids[i] in target_rhyme_set: logits[i] += 2.0 return logits def apply_structure_penalty(sequence, upper_seq): # 计算词性序列编辑距离,距离越大,分数越低 dist = edit_distance(pos_tags(sequence), pos_tags(upper_seq)) return -0.3 * dist温度0.9是为了让句子不那么保守,top_p取0.92是为了砍掉小概率的离谱词。重复惩罚1.2看起来不大,但在七言短句里已经足够让“青山”“白水”这类词不那么容易反复出现。40条候选是后来固定的量级,太少捞不出好句子,太多筛选成本太高。4. 质量关:AI诗集里最后能留下什么,靠的是筛选与改写4.1 六个一票否决的“塑料味”特征生成模型给我们提供了海量候选,但能不能收进《大象万镜》,不是我一个人说了算。我们逐渐形成了一套一票否决式的筛选标准,凡踩中任意一条,直接淘汰:第一,名词堆叠成菜谱。一整句全是“青山”“落日”“孤烟”“瘦马”之类的名物排列,缺少动词或动词空洞,这种句子没有时间,也没有人的动作。第二,情绪透支。开头第一句就“愁”“怨”“断肠”“泪满衣”,情绪完全没有铺垫。真正有感染力的诗往往是情绪从动作里渗出来的,而不是贴标签。第三,典故空转。出现“仲宣”“王粲”之类词,但全诗并没有与之对应的新情境。典故成了装饰贴片,读者只会觉得晦涩。第四,季节、时序、方位互相矛盾。比如前一句还在“盛夏”,后一句突然飘雪;“柴门”在山村,下一句却跑到“渡口”去。人类读者可能只是觉得别扭,但我们直接把这类句子判定为逻辑事故。第五,全篇同一句型。四句如果每一句都是“名词-动词-名词-名词”的结构,读起来像排比练习,缺少节奏变化。好诗每句的重音位置和语法功能应当有起伏。第六,用词出现微观语义错位。比如“酒旗”旁边配上“键盘”“代码”这类现代词汇会明显违和,但有些更隐蔽的错位更致命——用“艳阳”写清晨雾散后的光线,就比“晴光”少了含蓄。“艳”这个字的情绪浓度太高,容易让整个画面失真。4.2 盲测启发:什么时候AI诗句“装得像”了我们做过一次内部盲测,把AI生成的句子和古人的句子混在一起,请一群熟悉古诗的读者选出“更像原创”的十句。结果没有特别崩溃,也没有特别惊喜:一部分AI句子与古人句子得票几乎持平,有个别AI句子甚至因为用词古朴而高票中选。这给了我一个挺重要的启发:AI诗句能不能骗过人是次要问题。关键是,当读者看不出它是不是AI写的时候,这诗句可能已经不再被当成“AI产物”来评价了。真正高质感的AI古诗,靠的是恰如其分的场景细节、逻辑一致的动作和一个能让人代入的视线。技术不差的情况下,读者在意的是画面能不能成立。但盲测也暴露了明显问题:AI句子一旦超过两联,也就是四句以上,立刻会因为“句与句之间缺少递进”而穿帮。单看一联确实可以很漂亮,但四句连在一起,往往只是四个独立画面的重复排列。所以我们后来基本不追求整首四句直接可用的AI作品,而是把精力放在“一联精品”上——让AI负责提供一两句好诗,人负责把它们组装成真正的诗。4.3 AI出候选,人做终审:改写“雾散柴门见酒旗”的真实走查“雾散柴门见酒旗,山家日午始开扉”这句,严格说不是一次生成出来的,而是经过了一轮手工走查。当时AI给出的候选里有“雾散柴门挂酒旗”“雾散柴门掩酒旗”“雾散柴门见酒旗”等多条变体。“挂酒旗”是纯静态描写,信息量少;“掩酒旗”在逻辑上有硬伤——雾气散尽后,柴门真的会掩住酒旗吗?如果酒旗矮、柴门高,可能能掩住,但更常见的情况是柴门掩不住挂在门边高杆上的旗子。而且“掩”字给读者的感觉是“看不到”,与“雾散”之后视野应当变清晰的方向相反。我们最后选了“见”。这个字的优势在于:它把镜头交给了一双眼睛,让整句从“风景照”变成了“看风景的行为”。在第二句中,我们也把AI原本生成的“山家午日始开扉”调整成“山家日午始开扉”,因为“午日”更多指正午的太阳,偏重物象;“日午”则是时间状态,直接指示“到正午了”,与前面“雾散”形成清晨到正午的时间推进。这个过程里,AI提供了意象碎片和多种动词选择,人负责判断逻辑方向、情绪浓度和节奏。这是《大象万镜》里每一首能看作品的都会经历的路程——模型不负责定稿,只负责把可能成立的世界铺开来。5. 做完这本AI诗集,我的几条认知修正5.1 AI的价值是海量候选,人的价值是判断与意外两年前我认为AI写诗最重要的是模型够不够大、语料够不够多。做完《大象万镜》之后,我的判断变了。模型当然要足够好,但最稀缺的其实是“筛选意志”。同样的四十条候选,有人只能留下“青山”“白水”的俗句,有人能捞出“雾散柴门见酒旗”这样的组合。这种差异不来自算力,来自对诗歌意图的理解。AI擅长提供海量“近乎合理”的碎片,但它不擅长选择为什么要在这一刻看这条景色。《大象万镜》这个名字本身带着一点自嘲:我们试图造一面映照万象的镜子,但镜子并不决定看哪里。最终决定看哪里的是人。5.2 三个能让产出质量明显上升的操作细节如果你也要做类似的AI古诗实验,有三个细节我认为是最值得先试的。第一,生成前先列场景锚点,而不是直接写命题。给模型“请写一首关于山村的诗”这种指令,会得到最平均的答案。先让它列出五个具体物象,再据物象作句,得到的句子会更有可追踪的质感。第二,多序列融合比单次生成高产。先生成四句作为一组,再把不同组的精华句抽出来,重新作为起始文本给模型润色重排。这相当于让模型自己当编辑,把“偶得”变成“可复用流程”。第三,句末字约束一定要放在解码阶段,不要放在后处理。后处理阶段发现韵脚不对,返工代价很大;而在解码阶段直接通过在句末位置调整候选池概率,几乎不影响其他位置的流畅度,是性价比最高的格律控制手段。5.3 关于AI写诗边界的一句实在话做完《大象万镜》,我最大的体会是:AI写诗最难的从来不是格律、典故或意象,而是“意图的起点”。模型可以让两句诗在一瞬间成立,却无法决定“为什么要写”。雾散柴门见酒旗,是人替它定下了一道目光;山家日午始开扉,是目光落到了一个动作上。让模型生成转瞬即逝的碎片,让人把这些碎片变成注视,这可能就是AI与人协作写诗时,最舒服也最不容易被替代的状态。
第一次读到《大象万镜》里“雾散柴门见酒旗,山家日午始开扉”这两句时,我盯着屏幕愣了一会儿。不是震惊于AI能写古体诗——那早就不稀奇了——而是这两句带着一种很少见的“日常感”。以前我批量产AI古诗,得到的多半是“苍山”“白鹤”“幽谷”的排列组合,一眼就能闻出机油气。后来我们小组内部做诗歌整理实验,把《大象万镜》当作一个长期的合集项目来经营,这两句成了我反复琢磨的样本。这篇文章主要写给三类人看:一是正在做AI文学创作工具、被生成内容“空泛感”困扰的开发者;二是业余写古诗、好奇模型怎么工作的创作者;三是单纯想理解“AI作诗质量高低到底差在哪”的读者。我会从这两句诗切入,拆解《大象万镜》背后的意象库、主题控场、格律约束、质量筛选与人工改写全流程,尽量把能直接复用的方法和参数都交代清楚。1. “雾散柴门见酒旗”到底好在哪里:先做一次逐层拆解1.1 画面里的时间与空间:雾、柴门、酒旗是怎么咬合的先看第一句。“雾散”是一个时间状语,也是一个视觉条件的切换。雾气退去,视野从模糊转向清晰,在这条清晰的视线末端,出现的是“柴门”和“酒旗”。这里有个很关键的层次:柴门是近景,酒旗可以是远景,也可以挂在柴门旁边。无论是哪种,句子都天然安排了一个由近及远、由静态到动态的空间关系。“酒旗”这个物象特别值得说。它不是孤立的装饰物,而是一个商业信号,暗示附近有人家、有村店、有能坐下来喝一杯的地方。中国古代村落里的酒旗常常挂在道旁、桥头、柴门不远的位置。所以“雾散柴门见酒旗”一句,不只是在写景,还在写“人”,写人的活动痕迹。第二句“山家日午始开扉”则把时间又往后推了一步。日午已经是正午,雾气早该散尽了,而这个山间人家这个时候才开门。这个“始”字用得很有余味,既说明山家的生活节奏与城镇不同,不必天不亮就开张,也给读者留下了想象空间:门里的人刚吃完午饭?还是一直在睡?或者是在等一位约定好午后到访的客人?两句连起来,从清晨雾散到日午开门,时间轴上有一个自然的推进。这种推进不靠“朝”“暮”之类的标签直接点明,而是通过光线、湿度和动作来体现。AI生成的句子最怕逻辑断裂,这两句却恰恰在时间与空间上咬合得很紧。1.2 为什么机器写惯了的句子,偏偏这里少了“塑料味”我以前测试过很多生成模型,它们写出来的古诗最明显的共同问题是:名词密度高、动词敷衍、情绪标签前置。比如随手就能生成“孤舟远水寒江暮,独客青山老树秋”,看起来每个词都符合古诗审美,但凑在一起却像一副没有骨架的古风壁纸。原因是模型在高概率空间里打转,高频意象“孤舟”“老树”“寒江”互相组合,概率很高,读者也眼熟,但句子之间没有实际视线,没有人,没有时间。“雾散柴门见酒旗”不一样。它里面最见功力的一个字是“见”。这个动词不是凭空出现的,它隐含了一个观察者。“雾散”之后“见”,说明有人在这个时间点注视外头。你甚至可以脑补出一个早上起来推开窗户或走到院子里的人,看见雾气退开,远处酒旗渐渐清楚。这个“见”把原本纯风景的句子变成了有叙事的句子。相比之下,很多AI候选句子喜欢用“掩”“隐”“映”,因为这类动词非常“安全”。但“掩”会让柴门挡住酒旗,逻辑上反而说不通;“隐”与“见”相比,缺少了观察者主动获取信息的动作;“映”则太强调色彩反光,放在清晨雾气里并不合理。AI无法自动理解这些细微差别,但当一个句子刚好绕开了这些陷阱,它就会有那么一点“人味”。1.3 若按近体诗的标尺量一量,它其实站在古体一边有读者可能会问:这两句能算严格的近体诗吗?我按普通话粗测了一下平仄。“雾散柴门见酒旗”大约是“仄仄平平仄仄平”,“山家日午始开扉”大约是“平平仄仄仄平平”,单看平仄骨架,确实接近七言律句的交替节奏。但如果按近体诗的规则,首句平收通常要求首句入韵,“旗”和“扉”在平水韵里也不是同一韵部。因此这两句更像古体联句的吟咏方式,保留格律的气息,但不走近体诗的严格韵部流程。这其实给我一个提示:如果AI强行把这两句改写成标准的近体绝句前两句,大概率会牺牲“日午始开扉”这种松散、日常的节奏。诗歌不是格律测试题,格律是骨架,气才是血肉。这一点在后续的工程化处理里非常重要,我们不能让格律约束反过来杀死语感和叙事性。2. 《大象万镜》背后的生成管线:意象库和主题控场是两条腿2.1 先有物象,再谈诗意:意象标签库怎么搭《大象万镜》这个项目名里有个“镜”字,我挺喜欢这个隐喻:AI像一面镜子,把语料里的意象碎片映照出来,再由人决定哪些碎片值得摆在一起。为了让镜子映照出足够丰富的意象,我们最先做的事情不是调模型,而是搭意象库。我们收集了数千首唐以来的古体诗与近体诗文本,把诗里出现的名物名词都抽出来,按物象类别、光线条件、动静状态、温度感、情绪色彩做标签。以“酒旗”为例,它的标签大概是:类别:市井/商业物象动态:可摆动、可悬挂光线提示:适合晨光、薄雾、日暮声音提示:旗动无声,但能暗示人声情绪色彩:烟火气、温暖、招待感常见位置:村口、道旁、桥头、柴门侧这套标签不是为了给文学研究者写注释,而是为了让模型的采样有方向。模型本身没有“柴门旁边要有酒旗”的概念,它只学统计。我们把这些标签作为条件输入,让模型在生成时优先选择与当前场景匹配的意象词。如果只做这一步,效果仍然有限。因为模型还是会偷懒,在候选词里挑概率最高的。真正管用的是把意象库和主题控场结合起来。2.2 主题控场:不让模型一开口就是“江海”“孤舟”自由生成模式下,模型最容易落进高频意象的引力井。你让它写山村,它给你“孤村”“老树”“寒鸦”;你让它写清晨,它给你“晓风”“残月”“霜天”。这些词不是错,而是被用过太多次,失去了具体感。《大象万镜》的做法是提前给模型一个“场景摘要”,要求生成前先拆出地点、时间、天气、人物状态四个维度。比如针对这两句诗,场景摘要会是:地点:山中村落,柴门附近时间:清晨到正午之间天气:雾散转晴人物状态:没有急务,从容这四个维度会转化成一组主题向量,和模型内部的隐状态做加法。说白了就是给模型设限:你的想象空间是这座山村,别飞到江海边去。这个约束不需要太强,太强会生成出类似“柴门雾散酒旗风”这种被模板钉死的句子,太弱则会回到“江海孤舟”的老路。实际测试里,我们花在调整主题控制强度上的时间,远多于微调模型本身。控制太强,模型像填空;控制太弱,模型像说胡话。最终找到一个相对舒服的区间:场景摘要里的名词直接出现在句子的概率较高,但动词和形容词仍由模型自由发挥。这样既保证物象不跑偏,也给“见”“始”这类动词留出空间。2.3 场景锚点输入:以“雾散柴门见酒旗”为样例一个可以直接抄作业的流程是这样的:先让模型根据场景摘要生成二十个候选意象组合,再人工挑出五到八个锚点词,最后把锚点词作为前置约束重新生成诗句。“雾散柴门见酒旗”这组句子,如果拆开看,锚点词就是“雾散”“柴门”“酒旗”“日午”“开扉”。有意思的是,模型并没有自己把“雾散”和“见”连起来,这个“见”更像是在多次采样中出现的高质量偶然。所以我们把锚点词输入后,不会要求模型必须把每个词都用上,而是要求至少覆盖两个,剩余的词位留白。这样模型有足够的自由度去尝试“见”“闻”“隔”“挂”之类的动词。大量候选句里,你才能真正捞出“雾散柴门见酒旗”这种带着目光的句子。3. 格律是硬约束:AI产古诗最麻烦的一关3.1 普通话的平仄不等于古代韵书,映射表比模型参数更关键很多刚接触这个领域的人以为,只要让模型学会“一三五不论、二四六分明”,就能生成合规的格律诗。真正做起来才发现,普通话读音和古代韵书之间存在大量差异。同一个字,在普通话里是平声,在平水韵里可能是仄声;在不同语境下还可能多音多韵。如果只用现代汉语拼音做平仄规则,生成的句子常常会在懂格律的人面前露馅。我们的做法是给模型额外接两套表:一套是常用字古今平仄对照表,另一套是韵部表。生成时每个候选汉字都要先查表,确定它在当前语法位置上的声调归属,再判断是否与前后字构成交替节奏。这个过程听起来繁复,但编码实现并不复杂,核心是一个查询逻辑。这个环节里最容易踩的坑是:过于相信对照表,把每个字都当成固定平仄。实际上不少字在古诗里存在可平可仄的用法,需要结合具体的词性和语义来判断。我们的方案是保留一个“可平可仄”白名单,在格律校验遇到这类字时,不直接判死刑,而是降低权重。这样既照顾了格律,又不会误杀好句子。3.2 押韵约束的三种实现:重采样、受限解码、韵律分支押韵是AI写古诗的另一个大关。早期我们用的是“先生成、后检查”的方式,几十首里偶尔有一首押韵完美,大部分都押得不伦不类。后来尝试了三种更有效的办法,按实现难度从低到高排:第一种是重采样。先在无约束条件下生成候选句,用韵脚检查器扫描,把不符合当前韵部的候选丢弃,重新生成。好处是简单,坏处是浪费算力,而且模型可能为了迁就韵脚,把整句语义带偏。第二种是受限解码。在每一步选词时,如果当前句是偶数句且已经走到了句末字的位置,就只允许模型从目标韵部的候选字里选。这种方式能让韵脚百分之百契合韵部表,但需要提前确定整首诗押哪个韵,不能中途换。第三种是在微调阶段增加韵律分支。训练模型时把韵脚一致性作为辅助损失函数的一部分,让模型从统计上学会在句末自然地选择同韵字。这个方案效果最顺,但需要额外的数据和训练资源。我们在《大象万镜》里主要用受限解码,配合一个很小的重采样兜底。有一个值得说的细节:如果你的目标是古代韵部,却用现代语音模型做中途采样,两者会经常打架。比如“斜”这个字,普通话读xié,古韵里却常押xiá。我们最后把韵部映射表和现代拼音都放进约束函数,优先按古韵字表判定,但允许现代读者能接受的邻韵通押。传统和可读性之间需要找平衡,不能一味复古。3.3 对仗的弱约束实现:词性序列对齐与结构惩罚律诗中间两联需要对仗,AI也很容易在这里露出破绽。常见问题是“天对地”这种名词对名词没问题,但动词位置各说各话,或者上下句的字数节奏错位。我们采用了一个相对轻量的“词性序列对齐”方案:先给上句做分词和词性标注,得到一个序列,比如“名词-动词-名词-动词-名词”之类的结构;下句生成时,要求词性序列尽量与上句对齐,但不要求每个词的具体词义相对。这样既能形成工整结构,又避免了“必须柳对花、燕对莺”的机械感。在beam search解码时,我们还给“结构惩罚项”加了一个判断:如果下句的词性序列与上句的编辑距离超过阈值,这条候选的分数就下调。这个惩罚项不直接修改词汇,只影响排序,所以很少产生生硬感。实测下来,诗句的对仗合规率明显上升,同时保留了一些有趣的词义错位——对仗最迷人的地方本来就不在完全对应,而在于对应中的那一点偏转。3.4 一个可落地的生成流程配置示例统一整理一下《大象万镜》里比较常用的生成配置,你可以直接复制作为起点:gen_config = { "temperature": 0.9, "top_p": 0.92, "repetition_penalty": 1.2, "num_return_sequences": 40, "max_length": 32 } def apply_rhyme_penalty(logits, candidate_ids, target_rhyme_set): # 仅对偶数句句末位置生效 for i in range(len(logits)): if candidate_ids[i] in target_rhyme_set: logits[i] += 2.0 return logits def apply_structure_penalty(sequence, upper_seq): # 计算词性序列编辑距离,距离越大,分数越低 dist = edit_distance(pos_tags(sequence), pos_tags(upper_seq)) return -0.3 * dist温度0.9是为了让句子不那么保守,top_p取0.92是为了砍掉小概率的离谱词。重复惩罚1.2看起来不大,但在七言短句里已经足够让“青山”“白水”这类词不那么容易反复出现。40条候选是后来固定的量级,太少捞不出好句子,太多筛选成本太高。4. 质量关:AI诗集里最后能留下什么,靠的是筛选与改写4.1 六个一票否决的“塑料味”特征生成模型给我们提供了海量候选,但能不能收进《大象万镜》,不是我一个人说了算。我们逐渐形成了一套一票否决式的筛选标准,凡踩中任意一条,直接淘汰:第一,名词堆叠成菜谱。一整句全是“青山”“落日”“孤烟”“瘦马”之类的名物排列,缺少动词或动词空洞,这种句子没有时间,也没有人的动作。第二,情绪透支。开头第一句就“愁”“怨”“断肠”“泪满衣”,情绪完全没有铺垫。真正有感染力的诗往往是情绪从动作里渗出来的,而不是贴标签。第三,典故空转。出现“仲宣”“王粲”之类词,但全诗并没有与之对应的新情境。典故成了装饰贴片,读者只会觉得晦涩。第四,季节、时序、方位互相矛盾。比如前一句还在“盛夏”,后一句突然飘雪;“柴门”在山村,下一句却跑到“渡口”去。人类读者可能只是觉得别扭,但我们直接把这类句子判定为逻辑事故。第五,全篇同一句型。四句如果每一句都是“名词-动词-名词-名词”的结构,读起来像排比练习,缺少节奏变化。好诗每句的重音位置和语法功能应当有起伏。第六,用词出现微观语义错位。比如“酒旗”旁边配上“键盘”“代码”这类现代词汇会明显违和,但有些更隐蔽的错位更致命——用“艳阳”写清晨雾散后的光线,就比“晴光”少了含蓄。“艳”这个字的情绪浓度太高,容易让整个画面失真。4.2 盲测启发:什么时候AI诗句“装得像”了我们做过一次内部盲测,把AI生成的句子和古人的句子混在一起,请一群熟悉古诗的读者选出“更像原创”的十句。结果没有特别崩溃,也没有特别惊喜:一部分AI句子与古人句子得票几乎持平,有个别AI句子甚至因为用词古朴而高票中选。这给了我一个挺重要的启发:AI诗句能不能骗过人是次要问题。关键是,当读者看不出它是不是AI写的时候,这诗句可能已经不再被当成“AI产物”来评价了。真正高质感的AI古诗,靠的是恰如其分的场景细节、逻辑一致的动作和一个能让人代入的视线。技术不差的情况下,读者在意的是画面能不能成立。但盲测也暴露了明显问题:AI句子一旦超过两联,也就是四句以上,立刻会因为“句与句之间缺少递进”而穿帮。单看一联确实可以很漂亮,但四句连在一起,往往只是四个独立画面的重复排列。所以我们后来基本不追求整首四句直接可用的AI作品,而是把精力放在“一联精品”上——让AI负责提供一两句好诗,人负责把它们组装成真正的诗。4.3 AI出候选,人做终审:改写“雾散柴门见酒旗”的真实走查“雾散柴门见酒旗,山家日午始开扉”这句,严格说不是一次生成出来的,而是经过了一轮手工走查。当时AI给出的候选里有“雾散柴门挂酒旗”“雾散柴门掩酒旗”“雾散柴门见酒旗”等多条变体。“挂酒旗”是纯静态描写,信息量少;“掩酒旗”在逻辑上有硬伤——雾气散尽后,柴门真的会掩住酒旗吗?如果酒旗矮、柴门高,可能能掩住,但更常见的情况是柴门掩不住挂在门边高杆上的旗子。而且“掩”字给读者的感觉是“看不到”,与“雾散”之后视野应当变清晰的方向相反。我们最后选了“见”。这个字的优势在于:它把镜头交给了一双眼睛,让整句从“风景照”变成了“看风景的行为”。在第二句中,我们也把AI原本生成的“山家午日始开扉”调整成“山家日午始开扉”,因为“午日”更多指正午的太阳,偏重物象;“日午”则是时间状态,直接指示“到正午了”,与前面“雾散”形成清晨到正午的时间推进。这个过程里,AI提供了意象碎片和多种动词选择,人负责判断逻辑方向、情绪浓度和节奏。这是《大象万镜》里每一首能看作品的都会经历的路程——模型不负责定稿,只负责把可能成立的世界铺开来。5. 做完这本AI诗集,我的几条认知修正5.1 AI的价值是海量候选,人的价值是判断与意外两年前我认为AI写诗最重要的是模型够不够大、语料够不够多。做完《大象万镜》之后,我的判断变了。模型当然要足够好,但最稀缺的其实是“筛选意志”。同样的四十条候选,有人只能留下“青山”“白水”的俗句,有人能捞出“雾散柴门见酒旗”这样的组合。这种差异不来自算力,来自对诗歌意图的理解。AI擅长提供海量“近乎合理”的碎片,但它不擅长选择为什么要在这一刻看这条景色。《大象万镜》这个名字本身带着一点自嘲:我们试图造一面映照万象的镜子,但镜子并不决定看哪里。最终决定看哪里的是人。5.2 三个能让产出质量明显上升的操作细节如果你也要做类似的AI古诗实验,有三个细节我认为是最值得先试的。第一,生成前先列场景锚点,而不是直接写命题。给模型“请写一首关于山村的诗”这种指令,会得到最平均的答案。先让它列出五个具体物象,再据物象作句,得到的句子会更有可追踪的质感。第二,多序列融合比单次生成高产。先生成四句作为一组,再把不同组的精华句抽出来,重新作为起始文本给模型润色重排。这相当于让模型自己当编辑,把“偶得”变成“可复用流程”。第三,句末字约束一定要放在解码阶段,不要放在后处理。后处理阶段发现韵脚不对,返工代价很大;而在解码阶段直接通过在句末位置调整候选池概率,几乎不影响其他位置的流畅度,是性价比最高的格律控制手段。5.3 关于AI写诗边界的一句实在话做完《大象万镜》,我最大的体会是:AI写诗最难的从来不是格律、典故或意象,而是“意图的起点”。模型可以让两句诗在一瞬间成立,却无法决定“为什么要写”。雾散柴门见酒旗,是人替它定下了一道目光;山家日午始开扉,是目光落到了一个动作上。让模型生成转瞬即逝的碎片,让人把这些碎片变成注视,这可能就是AI与人协作写诗时,最舒服也最不容易被替代的状态。