
版权与内容来源声明本文为原创整理。文中涉及官方文档、开源仓库、论文与公开报道的内容均在附表 A 中标注来源引用官方原文保持原样不作改写。文中命令、版本号与界面截图以本文成文时的实测/核验结果为准标注「待验证」的部分请以你本地环境实际输出为判断依据。本文不推荐任何不合规的软件获取方式也不对任何收益结果作承诺。转载请注明出处。第 1 章 为什么「两次跑不一样」在投研里是硬伤1.1 投研的默认习惯就是「可复核」在券商研究所、基金公司做投研的人有一件事是刻进肌肉记忆的任何一个结论都要能回答「这个数从哪来、口径是什么、什么时候取的、谁复核过」。一份底稿之所以重要不在于写得好看而在于三个月后有人问同一个问题你能把当时的路径原样再走一遍。关键词是原样。不是「差不多」也不是「我记得当时是这样」。1.2 但大模型服务默认不是台账把大模型接进这条链路第一个冲突就出现了模型服务默认不是台账。模型生成文字时并不是从「唯一正确答案」里取一个而是在一个概率分布上逐字抽样。所谓采样参数人话控制「抽签」有多随机的几个旋钮就是用来调这个抽样过程的。放开一点同样的输入每次措辞都不同收紧一点差异会变小但通常不会归零。所以「同一份财报摘要昨天跑出来的措辞和今天不一样」这不一定是哪里配错了而是默认行为。这一点必须先接受后面所有工程动作才有意义。1.3 本文只解决一个问题这篇不讨论「怎么让模型更聪明」也不讨论提示词怎么写得更漂亮。只回答一件事同一个输入连续跑两次输出差异有多大哪些环节必须锁死哪些可以放开。后面每一节都会落到一个能直接动手的判据上哪个参数固定、怎么验证两次是不是一致、留痕到底该存什么。第 2 章 先读厂商原文可复现这件事官方给得比想象中少2.1 OpenAIseed 是「尽力而为」并且写明不保证很多人第一次接触「可复现」是因为看到了seed人话给抽样器指定一个随机数起点让随机过程变成可重复的伪随机过程这个参数。但把官方原文读一遍会发现承诺比想象中小得多。截至 2026-10-14OpenAI Python SDK 官方仓库中该字段的说明原文仍然是This feature is in Beta. If specified, our system will make a best effort to sample deterministically, such that repeated requests with the same seed and parameters should return the same result. Determinism is not guaranteed, and you should refer to the system_fingerprint response parameter to monitor changes in the backend.三段话各带一层信息这是 Beta 特性只是 best effort尽力而为determinism is not guaranteed不保证确定性。同一份说明还指向system_fingerprint人话一个代表后端配置的指纹字符串用来看后端是否发生了可能影响确定性的变化。同一份官方文档里temperature 的原文是「between 0 and 2」并建议「altering this or top_p but not both」。也就是说把 temperature 调成 0官方给的是「更聚焦」不是「一定相同」。这里有一个流传很广但需要谨慎的说法社区讨论帖非官方文档未经官方确认中有人称 seed 已被弃用。本文成文时的核验结果是口径不一致——官方仓库里该字段的说明文字仍是「Beta」未见 Deprecated 字样而同厂商其他官方产物Go 版参考页、OpenAPI 规格把这个字段渲染成了 Deprecated。这条以待验证处理请以你自己打开官方参考页时的实际标注为准。2.2 Anthropic采样参数在 Claude 4.7 及以后非默认值直接报错Anthropic 这边的变化更彻底。官方模型弃用页在「API 参数弃用」一节写得很直接temperature、top_p、top_k 已弃用Claude Opus 4.7 及更高版本在 Claude 4.7 及更高版本的模型以及 Claude Mythos Preview 上设置为非默认值时返回 400 错误替代方式是省略这些参数改用提示引导模型行为。官方 Messages API 页面同样是这个口径这三个采样参数在 Claude 4.7 及更高版本上不受支持设置成非默认值会返回 400 错误建议改为用提示引导模型行为。官方发布说明还记录了另一件事Python SDK 的 v1.02026-08-20 发布已经把这套参数从 Messages 方法签名里移除。对投研场景来说这条信息有两层含义。第一层你不能把「调 temperature」当成跨厂商通用的手段同一段代码换个模型就可能直接报鉴权之外的参数错误。第二层模型厂商正在把「引导方式」从参数旋钮挪到提示词与结构化输出上工程上更该顺势把约束写进提示和程序里而不是飘在几个浮点数上。2.3 口径本身在漂所以每次都要现场复核把这几点合起来看结论很清楚参数状态是会过期的。所以本文所有涉及参数可设范围、默认值、报错行为的表述都写明「截至 2026-10-14」你隔一段时间再读请回到官方 reference 重核一遍。接口temperaturetop_pseed本文核验方式OpenAI Chat Completions仍可设置范围 0–2官方建议与 top_p 二选一仍可设置官方建议与 temperature 二选一官方仓库源文件说明仍为 Beta另有官方产物渲染为 Deprecated待验证官方开源仓库源文件可直连读取官方参考页原文经检索索引取得规格文件中字段定义段本机未取到Anthropic MessagesClaude 4.7 及更高版本设为非默认值返回 400同上未见该参数官方文档域名本机直连被地区限制拦截返回地区不可用页改用检索索引取得官方页面原文说明本机直连platform.openai.com返回 403docs.anthropic.com与platform.claude.com跳转地区不可用页。上表因此不是「直连抓取」而是「官方域名被拦后以官方开源仓库源文件 检索索引取得的官方页面原文」交叉核对核验方式同样记入附表 A。第 3 章 拆开不确定性哪些必须锁死哪些可以放开3.1 别把三类不确定性混成一类工程上最容易犯的错是把「输出不一样」全归因给采样随机性。实际至少有三类来源第一类采样随机性模型在概率分布上抽签。这类靠固定参数能压小但按厂商原文压不到零。第二类后端与基础设施漂移官方模型 ID 与版本管理文档写得很明确——对于特定 ID模型权重是固定的但围绕模型的服务基础设施请求路由器、安全分类器、采样逻辑等组件可能随时间变化偶尔即使模型 ID 与权重未变基础设施更新也可能在可观察行为上产生细微差异。第三类你自己的代码和上下文漂移提示词被顺手改了一个词、上下文里多了一段历史消息、检索回来的片段顺序变了、温度参数在配置文件里被另一处覆盖。这一类占比往往最高且最容易被忽略因为它看起来「什么都没改」。后两类都不是模型的问题但都会让「两次跑不一样」。所以动手之前先把这三类分开归因否则会一直在错误的方向上调参数。3.2 一张对照清单必须锁死 vs 可以放开判断标准只有一条这个环节的结果要不要被复核。要复核的锁死只影响表达和探索的放开。环节处置理由落到哪模型 ID锁死换 ID 等于换了一套权重与配置两次不可比配置写固定快照 ID不用带 latest 的移动标签采样参数temperature / top_p / seed锁死参数一变「两次差异」就无从归因写进配置文件并落盘提示词模板正文锁死一个词的改动就会改变输出分布模板进版本管理与运行记录绑定检索回来的片段集合与顺序锁死顺序变化会改变拼进上下文的文本记录片段 ID 列表不记录完整原文上下文裁剪策略锁死裁剪边界不同进模型的内容就不同策略参数与生效结果一起留痕输出用词与句式可以放开只要结论一致措辞差异不影响复核比对时忽略措辞只比结构化字段探索阶段的候选方案数量可以放开探索本来就是要发散追求多样性探索产物单独放不混进台账面向对象的表达风格可以放开属于呈现层不进入判断链不改动参数只做后处理这张表的价值在于它把「要不要调参数」这个争论变成了一个可以逐行打勾的清单。凡是勾在「锁死」列的就都该在你的配置文件里有对应的一行凡是在「放开」列的就不该出现在你比对两次输出的一致性判据里。3.3 一条可以复用的原则结论要复核表达不用。涉及数字、口径、分类结果、是否命中的部分必须由确定性环节产出涉及措辞、举例、展开方式的部分可以交给模型自由发挥。这条原则一旦立住第 4 章的四个动作就是自然推论而不是额外的负担。第 4 章 工程上怎么收窄四个动作4.1 把参数落盘并且给每次请求算一个指纹第一个动作不是「把 temperature 调成 0」而是让参数有唯一一处真源。参数散落在多个脚本里是第三类漂移最常见的入口。哈希指纹人话把一段内容压成一串定长字符内容只要差一个字符这串字符就完全不同在这里很有用你不必把整段输入抄进台账只存一个指纹就能判断两次是不是同一份输入、同一套参数。下面是配置文件的样子注意模型 ID、采样参数、比对档位、留痕字段全部集中在一处凡是要进「可复核」链路的项都落在这个文件里。model:id:your_model_id# 用固定快照 ID不要用带 latest 的移动标签frozen_at:2026-10-01# 本文档最后一次确认该 ID 可用的日期sampling:temperature:0top_p:1max_tokens:1024seed:20261014# 若该厂商不支持该参数留空并在留痕里写「未传」repeat:runs:2# 同一输入连续跑几次用于比对compare_level:field# strict 逐字 / field 字段 / semantic 结论trace:store_dir:./tracestore_fields:[input_hash,params_hash,model_id,output,reviewer]⚠️代码待验证importhashlibimportjsonimportdatetimedefsha256_text(text:str)-str:returnhashlib.sha256(text.encode(utf-8)).hexdigest()defparams_fingerprint(params:dict)-str:# 按固定键序序列化后再取指纹避免字典顺序变化导致指纹漂移blobjson.dumps(params,ensure_asciiFalse,sort_keysTrue)returnsha256_text(blob)defbuild_trace(question:str,params:dict,output:str,model_id:str)-dict:return{run_at:datetime.datetime.now().isoformat(timespecseconds),model_id:model_id,input_hash:sha256_text(question),params_hash:params_fingerprint(params),output:output,reviewer:None,# 人审节点未过审前一律留空不做默认通过}注意reviewer这一栏默认留空而不是默认通过这是投研留痕和一般日志的一个重要区别。4.2 缓存把已经确认过的输入输出钉住第二个动作是缓存人话把「输入指纹 → 输出」的对应关系存下来下次同样输入直接取回不再请求模型。它的作用有两层。对内的作用是省成本对投研更重要的作用是结果稳定——已经复核过的那次输出下次取回来的还是同一条不会因为重跑而变化。这里要提醒一点官方文档明确说明提示缓存本身不影响输出 token 的生成也就是说缓存不是「让模型变确定」而是「让已经确定过的结果不再被重新生成」。这两件事不能混为一谈。做法很简单缓存键用「输入指纹 参数指纹 模型 ID」三者拼起来。任何一个变了就不命中缓存重新生成并记录差异。4.3 把判断权交回程序第三个动作最关键凡是能用确定性代码算的不要让模型算。模型负责理解材料、抽取成结构化字段、给出候选归类求和、排序、筛选、阈值判断、区间比较交给程序。这样做的直接好处是即使模型那一段的措辞每次不同最终参与复核的数值是同一套。这也顺带回应了 2.2 里的变化——厂商在把参数旋钮收走让约束回到提示和结构里。把判断写进程序就不必依赖某个参数是否还存在。4.4 人审节点要显式标出来第四个动作是人审节点人话流程里明确规定「这一段必须有人看过才算完成」的位置。不要指望模型自己说「我不确定」而是在流程里定义清楚哪些字段必须有人签字哪些字段可以自动通过。判定方式尽量机械出现了「无法归类」「依据不足」这类标记的输出一律进人审队列涉及结论口径的字段无条件进人审队列。人审通过后把复核人写回留痕记录而不是单独放在另一个表格里。第 5 章 怎么验证「两次跑一样」5.1 先定档位再谈一致「两次一样」不是一个是非题。工程上成本最低的做法是先选一个可比对的档位再谈一致不一致。档位比什么适用场景代价逐字档两次输出文本完全一致材料极短、要求结果文字原样入库最高且按官方原文这个档位在托管接口上无法获得保证字段档抽取出的结构化字段完全一致抽取、归类、字段填表类任务中措辞差异不影响判定推荐作为默认档结论档人审判断结论是否一致需要解读、权衡的开放任务低但必须有人参与给出一个顺序建议从字段档开始往上试。字段档就能稳定通过的不要为了追逐字一致去反复重跑收益很小。字段档过不了的再逐字段定位是哪一项在漂。5.2 差异出来之后怎么归因差异不是终点归因才是。下面这张表可以直接拿来对照。差异现象最可能的原因下一步动作两次字段值都不同且方向不确定采样参数未固定或参数未落盘回到 4.1把参数收进唯一真源并记录指纹参数指纹相同、字段仍不同提示词或上下文拼装发生变化比对提示词模板版本与检索片段列表参数与提示都相同差异只在措辞采样随机性属正常范围不用处理检查比对档位是否选错同一输入一段时间后开始出现差异后端与基础设施漂移记录模型 ID 与运行时标识回溯官方变更说明差异集中在长材料任务上下文被裁剪进模型的内容不同记录裁剪策略与生效结果见 4.1 配置项两次跑出结构完全不同的字段提示词的结构约束不足把要求写进提示与结构化输出格式而不是靠参数一个必须写进注意事项的点不要用「重新跑一次就好了」来收尾。如果差异能靠重跑消失说明它属于随机性而不是确定性那它下一次还会出现只是换了位置。5.3 什么时候该停手追逐字一致是有止损线的。满足下面任意一条就可以停字段档已经稳定通过只是措辞不同——这属于正常范围停。你已经把模型 ID、参数、提示词模板、检索片段列表四样都锁死并留痕差异仍在——说明落在官方明确不保证的那部分停改为在流程上做缓解而不是继续调参数。为了追一致你开始减少材料量、拆细任务——这已经改变了任务本身先确认新任务是不是你真正要的。采样参数与可复现性核对清单我把前面这几节的参数状态、判据档位、留痕字段整理成了一份自查表跑第一次之前照着过一遍能省掉大部分「重跑才发现参数没锁」的时间。放在资料包里扫码即可获取第 6 章 留痕该存什么一份最小可复核记录6.1 五个必存字段留痕不是把所有东西都存下来而是存到足够把当时那次运行原样重建。五个字段是底线。字段存什么为什么不存的后果输入指纹输入文本的哈希值证明两次是同一份输入无法区分「输入变了」和「模型变了」参数指纹采样参数序列化后的哈希值证明两次用的是同一套参数参数漂移无法归因模型标识实际使用的模型 ID换 ID 等于换权重与配置两次结果不可比输出结构化字段 原始文本复核需要看到原始内容只有结论没有依据等于没留痕复核人复核人标识与复核时间证明这一条经过了人审无法回答「谁看过」模型 ID 一定要记回应里回显的那个值不要记你配置里写的那一行。界面上的标签是渲染结果回显字段才是记录。6.2 一条记录长什么样{run_at:2026-10-14 09:12:03,model_id:your_model_id,input_hash:输入文本的哈希值定长字符串,params:{temperature:0,top_p:1,max_tokens:1024,seed:20261014},params_hash:参数序列化后的哈希值,output_summary:本次输出的要点便于人工快速过一遍,fields:{科目:示例字段,口径:示例口径},reviewer:待复核,review_note:}6.3 目录与比对脚本留痕按日期分目录比对结果单独落一个文件这样「这一次和上一次哪里不同」是打开文件就能看的事不需要回忆。下面这段命令是同一输入连续跑两遍、分别落盘再交给比对脚本。trace/ ├── 2026-10-14/ │ ├── q01_run1.json │ ├── q01_run2.json │ └── compare_q01.json └── params_lock.yaml⚠️代码待验证python run_once.py--configparams_lock.yaml--inputq01.txt--outtrace/2026-10-14/q01_run1.json python run_once.py--configparams_lock.yaml--inputq01.txt--outtrace/2026-10-14/q01_run2.json python compare_runs.py trace/2026-10-14/q01_run1.json trace/2026-10-14/q01_run2.json--levelfield⚠️代码待验证defcompare_runs(a:dict,b:dict,level:strfield)-dict:比对两次运行。level 取 strict / field / semantic。report{level:level,same_model:a[model_id]b[model_id],same_params:a[params_hash]b[params_hash],}iflevelstrict:report[identical]a[output]b[output]eliflevelfield:# 只比结构化字段忽略自然语言措辞report[identical]extract_fields(a[output])extract_fields(b[output])else:report[identical]None# 结论档需要人审不由程序判定returnreport上面的extract_fields是占位函数实际使用时替换成你自己的字段抽取逻辑run_once.py与compare_runs.py同理都是示意用的脚本名。这两段可执行片段没有在本机实跑请以你本地实际输出为准。第 7 章 投研转大模型先练这三件事7.1 每周拿一个真实小任务跑两遍不需要一开始就搭完整体系。找一件你每周都在做的小事比如把一段公告整理成固定字段然后做三件事固定参数、连续跑两遍、比对字段档。只要连续两周做到了你就会对「哪些差异是正常的、哪些是配置漂移」有手感而这种手感直接来自你自己业务里的数据。7.2 明确区分这篇讲的是可复现不是创意多样性这里必须把话说清楚。本文讨论的场景是可复现与留痕。如果你面对的是内容创作类需求——比如给游戏角色写不同风格的对白、批量生成不同标题——那目标恰恰相反你要的是多样性采样参数要放开比对判据也不是「两次一样」而是「两次不像」。两件事的工程目标相反参数策略自然也相反。把「调低参数追一致」套到创意场景上会把内容做得越来越干把「放开参数求多样」套到投研复核上会让底稿失去可复核性。先判断你做的是哪一类再动手。维度可复现 / 留痕场景本文创意多样性场景目标两次一致可复核两次不同够鲜活采样参数锁死越紧越好放开允许更大随机性留痕重点输入指纹、参数指纹、模型 ID、复核人生成批次、多样性指标、人工筛选结果比对判据结构化字段是否一致是否落在期望的风格区间内人审位置结论口径必须人审成品选择环节人审常见错误用重跑掩盖漂移用固定参数把内容压干7.3 一句话收尾「可复现」不是把所有随机性消灭掉而是把不确定性的位置说清楚、标出来、留痕。哪些环节锁死、哪些放开、差异怎么归因、什么时候停手——这四件事想明白了你从投研转过来的那套复核习惯恰好就是你做大模型工程最占优势的地方因为它本来就是干这个的。投研场景的可复现自查表上面三章讲到的参数锁定清单、三档比对判据、留痕五字段我合并成了一张可以逐项打勾的表动手前过一遍最省事。放在资料包里扫码即可获取附表 A本文引用事实与出处对照表序号事实出处本文位置1seed 说明原文为「This feature is in Beta. If specified, our system will make a best effort to sample deterministically… Determinism is not guaranteed, and you should refer to the system_fingerprint response parameter to monitor changes in the backend.」OpenAI Python SDK 官方开源仓库字段定义源文件github.com/openai/openai-pythonsrc/openai/types/chat/completion_create_params.py本机直连读取2.12temperature 说明原文为「between 0 and 2」并建议「larger values… more random」与 top_p 二选一的建议原文为「We generally recommend altering this or top_p but not both.」同上官方开源仓库源文件本机直连读取2.13top_p 说明原文含「nucleus sampling」并说明 0.1 表示只考虑概率质量前 10% 的候选同上官方开源仓库源文件本机直连读取2.14seed 在部分官方产物中被渲染为 Deprecated而同仓库源文件说明仍标 Beta两处口径不一致 → 本文标「待验证」官方 Go 版参考页developers.openai.com经检索索引取得规格文件字段定义段本机未取到截断本机未完成直连比对2.1、2.3、附表 A 本条5提示缓存不影响输出 token 的生成缓存不改变模型生成方式厂商官方文档「提示缓存」页本机未直连经检索索引取得原文标注为间接核验4.26temperature、top_p、top_k 已弃用Claude Opus 4.7 及更高版本设为非默认值返回 400 错误替代方式为省略参数、改用提示引导Anthropic 官方文档「模型弃用 / API 参数弃用」页docs.anthropic.com实际跳转 platform.claude.com本机直连被地区限制拦截改用检索索引取得官方页面原文2.27「The temperature, top_p, and top_k sampling parameters are not supported on Claude 4.7 and later models… Setting them to a non-default value returns a 400 error.」Anthropic 官方 Messages API 文档页本机直连被地区限制拦截改用检索索引取得官方页面原文2.28Python SDK v1.02026-08-20 发布移除 Messages 方法上的 temperature、top_p、top_k 参数并移除旧版 Text Completions APIAnthropic 官方平台发布说明docs.anthropic.com/en/release-notes/api本机直连被拦截改用检索索引取得官方原文2.29对于特定模型 ID模型权重固定但服务基础设施请求路由器、安全分类器、采样逻辑等可随时间变化基础设施更新可能在可观察行为上产生细微差异Anthropic 官方文档「模型 ID 与版本管理」页本机未直连经检索索引取得官方页面原文3.110「Chat Completions are non-deterministic by default」及 seed / system_fingerprint 用于「部分确定性」的表述OpenAI 官方「Advanced usage」文档页本机未直连经检索索引取得原文3.111官方 Cookbook 复现示例页顶部标注「This recipe is archived and may reference outdated models or APIs.」OpenAI Cookbook 官方仓库示例页cookbook.openai.com经检索索引取得原文2.1 相关背景12参数支持情况可能因模型而异尤其是较新的推理模型OpenAI 官方参考页Java 版原文「Parameter support can differ depending on the model used…」经检索索引取得2.3、4.313本机直连核验记录platform.openai.com返回 403docs.anthropic.com、platform.claude.com跳转地区不可用页本机 WebFetch 实测2026-10-142.314本文代码块中的配置结构、留痕字段、比对脚本均为示意未在本机实际运行已在正文中逐处标注为待验证本机未执行属待验证内容5.3、6.3附表 A 使用说明第 4 条为「待验证」、第 5 条为「间接核验」原因是官方域名在本机被地区限制拦截、或不同官方产物口径不一致。附表 B术语速查表术语一句话解释在本文哪里用到采样参数控制模型抽样随机程度的几个旋钮如 temperature / top_p1.2、2.1、2.2temperature采样温度值越低输出越聚焦官方给的范围是 0 到 22.1、4.1top_p只保留概率累加后达到阈值的那部分候选词来抽样2.1、2.3seed随机数起点指定后让随机过程变成可重复的伪随机过程2.1、2.3system_fingerprint代表后端配置的指纹字符串用来判断后端是否变化2.1、3.1哈希指纹把一段内容压成定长字符串内容差一个字符结果就完全不同4.1、6.1缓存把「输入指纹到输出」的对应关系存起来同输入直接取回4.2人审节点流程中明确规定必须有人看过才算完成的位置4.4、6.1字段档比对只比对抽取出的结构化字段是否一致忽略措辞差异5.1后端漂移模型 ID 未变但服务基础设施更新导致可观察行为出现细微差异3.1、5.2写在最后这篇用到的资料写这篇文章时把相关的官方文档和源码又翻了一遍顺手也整理了几份配套的东西大模型学习路线图从零基础到能自己动手做 Agent按阶段说明每一步该学什么、哪些可以先跳过《LangChain LangGraph MCP 智能体开发实战》视频课7 个模块从私有化部署、EmbeddingRAG 到 MCPAgent 全流程AI 大模型知识库在线可查Agent Skills 从入门到落地、Claude Skills 完全指南等专题按目录浏览即可640 套 AI 大模型行业报告 经典 PDF 书籍看行业落地案例和别人怎么做的时候用得上大模型零基础到精通教学视频跟着敲一遍比只读文档快得多资料是我自己整理的放在下面这个码上扫码即可获取添加时备注「AI」优先通过。资料按「先路线、再动手、最后查漏」的顺序整理好了建议先看学习路线那一份照着它挑一条适合自己当前基础的路径再往下看。