说明:本文讨论的是线上模型行为漂移的排查与兜底,属于 AI 运维话题,不涉及具体模型版本与价格。AI 领域版本迭代极快,凡涉及版本号、价格、可用性,请以你阅读时的官方页面为准。文中代码为结构示意,未在某个具体项目里完整跑通,请按自己的技术栈调整后再上生产。
一、没有发布、没有告警、没有报错,但线上行为变了
大多数故障类型都有对应信号:发版引起的回退有发布记录可查,代码缺陷有堆栈可看,容量雪崩有耗时曲线可读。行为漂移这一类,三样都没有。
它的表象是:应用没有任何一次发布,错误率曲线是平的,接口全部返回成功,链路追踪里看不到红色;但从某个时间点起,一批固定任务的处理结果整体上和记忆里不一样了。用户能给出的描述通常只有一句——“感觉变笨了”。所谓行为漂移,指的是在你没有改动任何一侧的前提下,同一批输入的输出分布在时间维度上整体偏移。单条输出本来就有随机性,两次不一样不构成结论;只有一批固定输入在固定判定标准下,一致的结果变少、变短、变浅,才算漂移。
1.1 为什么这类问题会绕过告警
三个原因叠加,让常规监控对它完全无感。
告警挂的位置不对。告警大多挂在可用性和错误率上:请求成功、耗时正常、没有异常抛出,面板就是全绿的。而漂移期的输出语法正确、语气得体、看不出破绽,系统层面它是一次完美成功的调用。
变化是渐进的。上游若做过明显的大改动,你会在一天内看到断崖;更多时候是逐渐铺开——今天的结果还勉强能用,一周后同样的输入已经缺了要点。日环比落在噪声范围内,只有把两周前的结果和今天摆在一起,差异才显现。
成功指标定义得太浅。“任务完成率"若只判断接口有没有正常返回,它对内容质量完全不敏感,回答的是"跑没跑通"而不是"跑得对不对”。可用性指标和内容质量指标是两套东西,前者全绿不代表后者没退化。
1.2 四种可观测的表现
漂移会以几种相对固定的形态出现在线上。把形态各自绑定一个可测量的口径,是能发现它的前提。
| 表现 | 观测口径 | 常见误判 | 受影响的下游 |
|---|---|---|---|
| 格式变松 | 结构化校验失败比例、必填字段缺失数 | 当成解析代码的缺陷去修 | 入库、报表 |
| 调用工具变多变少 | 单任务平均调用次数、该调未调比例 | 当成工具描述写得不好 | Agent 任务完成率 |
| 回答变短 | 输出长度的 P10 与 P50、要点命中条数 | 当成"回答更简洁了"接受下来 | 摘要、决策建议 |
| 拒识变多 | 触发拒绝或免责表述的样本占比 | 当成安全策略收紧,认为合理 | 客服、问答 |
格式变松的判据是结构化校验的失败比例:把输出必须满足的字段、类型、取值枚举写成规则,每次调用后跑一遍并按失败原因计数。失败从偶发变成某些字段大面积缺失,这个转折点通常对应上游的某次变更。
调用工具变多变少要分别看:变少是该调不调,变多是反复试探,两个方向都按任务类型分开统计单任务平均调用次数,混在一起算会互相抵消。
回答变短不要只看均值,要看 P10,均值会被少数长回答掩盖;更有效的是给每类任务预设必须覆盖的要点,统计命中条数。
拒识变多是原本能回答的问题开始出现免责式回应或要求换问法,判据是这类回复在固定样本集里的占比,最容易被误判为"安全策略正常收紧"而被放过。
二、先排除自己这边
确认是上游之前,必须先完成一次自查。原因很实际:自己这边的改动是你唯一有能力立刻回滚的,而怀疑上游是一条无法验证、只能等待的路径。
2.1 三类自查
第一类,你改了什么。这一类的杀伤力被严重低估,因为很多改动不走发版流程:为修一个 case 直接在产线改了系统提示词;调采样参数;调整最大输出长度;增删工具或改工具描述;改检索的召回条数与切块长度;在系统提示里注入当前时间、用户昵称这类动态内容。共同点是随手就能改,所以没人记得住两周前动过哪一个。
第二类,流量结构变了。有时候不是模型变了,是你服务的人变了:新入口带来一批新用户群,输入从短问句变成整段粘贴的文档,语言分布里多了一种此前很少的语言,任务占比从问答转向长文生成。看输入的长度分位数、语言分布、任务标签占比三条曲线就能区分。
第三类,数据变了。知识库重建、语料更新、索引重排、缓存命中率变化都属此类。还有一类容易忽略的:工具的下游接口改了返回结构,比如把某个字段从数组改成对象,模型拿到之后的理解方式跟着变了。它的表象和上游漂移很像,归因却完全不同。
2.2 排查顺序
自查要有固定顺序,否则容易在几个方向之间反复横跳。
| 顺序 | 检查项 | 快速判据 | 结论方向 |
|---|---|---|---|
| 1 | 配置与提示词变更 | 两个时间点的配置快照 diff 是否为空 | 有差异,先算自己这边 |
| 2 | 采样参数与长度上限 | 是否被下游服务的默认值覆盖 | 有变化,回滚后复测 |
| 3 | 输入分布 | 输入长度的 P50 与 P95、任务标签占比 | 分布偏移,可能是错觉 |
| 4 | 检索与知识库 | 索引版本、重建时间、召回条数 | 有重建,先做检索回归 |
| 5 | 工具与下游接口 | 工具返回字段结构是否变更 | 有变更,归到自己这边 |
| 6 | 以上均无变化 | 冻结输入复跑,结果与留档一致 | 一致,转入上游怀疑 |
这张表从上往下走,任何一步命中就先停下来处理。第六行才是"确认自己这边没问题"的出口,走到这里才有理由去查上游。要让第一步可执行,前提是你有配置快照——没有快照,这一步只能靠回忆,而回忆在两周之后不可靠。
⚠️代码待验证
# 导出当前生效配置:提示词、采样参数、工具清单、检索配置放在同一份,避免漏项ops_snapshot_dump--envprod--out/tmp/snapshot-$(date+%F).jsondiff<(jq-S./tmp/snapshot-2026-09-20.json)\<(jq-S./tmp/snapshot-2026-09-27.json)# 只看关键子树,避免被无关字段淹没diff<(jq-S'.prompt, .sampling, .tools'/tmp/snapshot-2026-09-20.json)\<(jq-S'.prompt, .sampling, .tools'/tmp/snapshot-2026-09-27.json)顺手把"改配置必须落快照"写进流程,成本很低,但它决定三个月后这次排查是从五分钟开始,还是从三天开始。
三、确认是不是上游
自己这边排除干净之后,下一步不是直接去问上游,而是自己先拿出证据。做法是建一批固定输入对照组:同一批输入、同一套判定标准、同一组运行参数,定期跑,看结果相对基线的偏移。
3.1 对照组要冻结四样东西
难点不在执行,在于"冻结"。任何一样不冻结,结论都不可比。
| 要素 | 冻结什么 | 不冻结会怎样 |
|---|---|---|
| 输入集 | 固定样本与固定顺序 | 样本一变,差异分不清是模型还是题目 |
| 判定标准 | 事先写成机器可判的规则 | 每次判定口径漂移,前后结论不可比 |
| 运行参数 | 提示词版本、采样参数、长度上限 | 无法区分是参数变了还是模型变了 |
| 采样次数 | 每个样本固定跑若干次 | 单次结果噪声大,会掩盖系统性偏移 |
判定标准是四样里最容易被敷衍的。合格的判据必须机器可判:输出必须包含指定字段且类型正确、必须命中预设要点中的若干条、必须调用指定工具、长度落在给定区间。不合格的判据是"看一眼觉得答得对不对",它今天和明天给出的结论可能不同,基线也就失去意义。
3.2 为什么不能用"同一句问两遍"
同样的输入两次输出本来就不一样。只要采样不是确定性的,同一句话问两遍,措辞、长度、结构都可能有差别。这点差别可能只是随机噪声,当成漂移会得到大量假警报。
两次真的一模一样,也不能证明没漂移。那可能只说明采样被固定住了,或者你读到的是缓存。用"稳定"证明"没变化",逻辑上不成立。
单次对比混淆了两个量。你要判断的是分布的均值有没有移动,同一句问两遍测的是方差。用测方差的工具去测均值,和要回答的问题不是一回事。
漂移往往是概率级别的小偏移。原来四十条样本里三十六条判定一致,现在变成三十一条,这个变化只有在批量样本上比较一致条数才看得出来。
对照的粒度必须是"一批样本的一致条数",不是"一句话的两次回答"。前者可比较、可设阈值、可留档,后者只能提供一个印象。
3.3 对照组怎么跑
⚠️代码待验证
# 目标不是"这次答得好不好",而是"与基线判定一致的条数有没有掉"defrun_control_set(client,cases,params,repeat=3):results=[]forcaseincases:verdicts=[]for_inrange(repeat):resp=client.generate(system=params["system"],# 冻结:与基线同一版本user=case["input"],# 冻结:样本原文,不做改写temperature=params["temperature"],max_tokens=params["max_tokens"],cache=False,# 关缓存,避免读到旧结果)verdicts.append(judge(resp.text,case["checks"]))# 机器判定results.append({"case_id":case["id"],"verdicts":verdicts,"stable":all(v==verdicts[0]forvinverdicts),})returnresultsdefcompare_to_baseline(today,baseline):total=len(baseline)same=sum(1fort,binzip(today,baseline)ift["verdicts"][0]==b["verdicts"][0])return{"total":total,"consistent":same,"drift_ratio":1-same/total}两个细节:每个样本跑多次并记录是否稳定,能区分"整体偏移"和"个别样本抖动";第一次跑出的结果要连同参数快照一起留档,它是后面所有比较的参照系,丢了就得重来。
四、归因到具体环节
对照组说明"确实漂移了",但没说明"漂在哪一段"。一个请求经过三段处理:提示词层(拼装后送给上游的完整上下文)、参数层(采样与长度相关的一组设置)、模型行为层(上游对同样上下文的处理方式)。前两段在你手里,第三段不在。
定位方法是一次只替换一段、其余两段锁死,看一致条数会不会回到参照值:只有换回上一版提示词就恢复,问题在提示词侧;只有换回上一版参数才恢复,问题在参数侧;两样都换回来仍不恢复,剩下的只能是上游。
| 轮次 | 提示词 | 参数 | 上游 | 一致条数结果 | 指向 |
|---|---|---|---|---|---|
| 参照 | 上一版 | 上一版 | 用历史输出留档作参照 | 参照值 | —— |
| 第 1 轮 | 上一版 | 当前版 | 当前 | 回到参照值 | 提示词侧 |
| 第 2 轮 | 当前版 | 上一版 | 当前 | 回到参照值 | 参数侧 |
| 第 3 轮 | 当前版 | 当前版 | 不可回退,只能与留档比 | 仍明显偏低 | 上游行为 |
要提前说清楚:上游没有"上一版"可切,无法要求它回退到某个状态,所以第三轮比的是当前输出和你自己存的历史留档。
还有两个容易漏的地方:提示词层常含动态内容(当前时间、用户信息、检索片段),替换扫描时要冻结成固定值,否则变量没锁住、结论不成立;参数层的上一版要提前存快照,否则回头会发现历史值已经找不到。
⚠️代码待验证
# 两段替换扫描:看"单换一行"的三个组合就能定位到段defsweep(client,cases,prompt_snapshots,param_snapshots,baseline):report={}forptag,ptextinprompt_snapshots.items():forgtag,gvalsinparam_snapshots.items():res=run_control_set(client,cases,{**gvals,"system":ptext})cmp=compare_to_baseline(res,baseline)report[f"{ptag}|{gtag}"]=cmp["consistent"]returnreport PROMPTS={"prev":load_snapshot("prompt","prev"),"curr":load_snapshot("prompt","curr")}PARAMS={"prev":load_snapshot("params","prev"),"curr":load_snapshot("params","curr")}# 读法:prev|curr 恢复参照值 → 提示词侧;curr|prev 恢复 → 参数侧;# curr|curr 明显偏低且前两者都排除过 → 上游行为结论要写成明确的句子,比如"一致性下降集中在需要调检索工具的任务上,换回上一版提示词后恢复到参照值,判定为提示词侧的格式约束松动"。含糊的结论无法指导下一步。
五、缓解的四层
定位到哪一段,决定你在哪一层动手。但生产不会等你定位完,所以缓解手段要按"能不能立刻生效"排开。四层从快到慢、从浅到深。
5.1 提示词侧加固
目标是把隐式的期望写成显式约束。漂移的典型表现是模型不再遵守那些你从没写下来、只是"约定俗成"的规则。做法有三条:给约束编号并逐条列出;给每条约束配一个正例和一个反例;把格式要求写成可校验的结构描述,写明字段名、类型、是否必填。
反直觉的一点是:加固的目标是"可校验",不是"更长"。约束写得又长又密,往往让模型顾此失彼。更有效的做法是只补那些被观测到失效的约束,用冒号加列表写清楚。
5.2 解析侧兜底
解析侧要同时做两件方向相反的事:解析尽量不失败,校验尽量不放行。解析阶段容错,容忍输出前后多出的解释性文字、代码围栏、常见转义;校验阶段严格,字段必须存在、类型必须正确、枚举取值必须合法、数值范围必须合理。容错保证能拿到可判断的对象,严格保证脏数据不流进下游。
⚠️代码待验证
# 宽松解析 + 严格校验importjsonimportredeflenient_parse(text:str):text=text.strip()text=re.sub(r"^```(?:json)?|```$","",text,flags=re.M).strip()# 去围栏try:returnjson.loads(text)exceptjson.JSONDecodeError:passm=re.search(r"\{.*\}",text,re.S)# 从解释文字里抠出对象ifnotm:returnNonetry:returnjson.loads(m.group(0))exceptjson.JSONDecodeError:returnNoneREQUIRED={"title":str,"items":list,"confidence":float}defstrict_validate(obj)->tuple:ifobjisNone:returnFalse,"parse_failed"forkey,typinREQUIRED.items():# 字段存在且类型正确ifkeynotinobj:returnFalse,f"missing:{key}"ifnotisinstance(obj[key],typ):returnFalse,f"type:{key}"ifnot(0.0<=obj["confidence"]<=1.0):# 范围校验,脏数据不放行returnFalse,"range:confidence"returnTrue,"ok"校验失败后的处置要提前定好,通常是三选一:按修正后的提示词重试一次;走降级路径返回一个明确标注的兜底结果;报错并把失败原因结构化地告诉调用方。最不可取的是把校验失败的对象直接往下传,问题会在更远的地方以更贵的形式暴露。
5.3 路由侧切换与回切
路由侧解决"某一类任务持续不达标":把这部分流量切到另一条能达到相同目的的路径上。关键不是切换本身,而是切换判据和回切条件要同时写下来。
| 动作 | 触发判据 | 备注 |
|---|---|---|
| 切入备用路线 | 一致条数低于容忍带下沿,连续两次巡检 | 按任务类型切,不整站切 |
| 切入备用路线 | 结构化校验失败比例超阈值,滚动一小时 | 阈值按链路单独设 |
| 切入备用路线 | 特定任务拒识比例达到基线的两倍 | 需要任务级标签支持 |
| 回切主路线 | 一致条数恢复到容忍带以内,连续三次巡检达标 | 间隔按巡检周期定 |
| 回切主路线 | 先放少量流量观察一个日周期 | 无异常再逐步全量 |
切换是"满足任一条即触发",回切是"条件同时满足",代码里的判定要对齐这个差别。最容易出问题的是"切出去就不切回来"——切出去有动因,切回来没人催。把回切条件写进告警规则,让巡检达标自动提醒。
5.4 产品侧降级
上面三层都无法保证正确性时,唯一诚实的做法是收窄对外承诺并如实告知。降级有两个要点:一是告知要具体,说清哪一项能力暂时受限、影响哪一类任务、用户此刻能做什么,含糊的"系统升级中"只会让用户反复重试;二是收窄要可逆,把自动执行降为给出建议由人确认,把长文生成降为返回提纲,把结构化抽取降为返回原文片段加定位,每项都写清恢复条件。
降级方案必须提前准备好:设计它需要产品判断,而出事当天所有人都在处理技术问题,没人有空做这个判断。
完整版资料清单:本文用到的漂移排查对照表与行为指纹模板都整理在里面了,扫码即可获取:
六、把漂移纳入常态管理
一次排查做完,如果不把方法固定下来,下一次还得重头再来。
6.1 对照组进巡检、结果留档成基线
巡检频率。关键链路每天跑一次全量对照组,安排在业务低峰期,避开调用高峰;非关键链路每周一次。输入集与判定标准与排查时完全相同。
留档要求。每次结果存三样:原始输出、判定明细、当次的参数与提示词快照。缺一不可——只存原始输出,事后无法复算判定;只存判定结果,事后无法解释为什么这么判。保留时长至少覆盖两个发布周期。
基线的定义。基线不应是固定数值,而应是"最近若干次巡检一致条数的中位数,加减一个容忍带",用容忍带吸收正常波动、避免每天报噪声。
必须警惕一个陷阱:基线要跟着"可接受的行为"走,不能跟着"当前的行为"走。每次巡检都自动用上一次结果刷新基线,任何缓慢下滑都会被无声吸收成新常态。所以基线更新必须是一次人工确认的动作:有人要回答"当前的表现是否仍然可以接受"。
6.2 关键链路的行为指纹
除对照组,还有一套更轻量的观测方式:行为指纹。它不比较单条输出,而是对一类任务提取一组固定的、可机器判定的特征组成向量,比较向量的移动——向量比句子稳定,也更容易设阈值。
| 指纹 | 计算口径 | 漂移信号 | 优先关注 |
|---|---|---|---|
| 输出长度分布 | 输出字符数的 P10 与 P50 | P10 明显下移,内容变薄 | 长文生成、摘要 |
| 结构化完整度 | 必填字段齐全的样本比例 | 比例下滑,格式变松 | 抽取、结构化输出 |
| 工具调用密度 | 单任务平均工具调用次数 | 持续下降,该调不调 | 检索类 Agent |
| 拒识比例 | 触发拒绝或免责表述的样本占比 | 上升,可用任务被挡 | 客服、问答 |
| 要点覆盖数 | 命中预设要点的平均条数 | 下降,回答变短变虚 | 报告、决策建议 |
| 首字节耗时 | 输出开始返回的耗时 P50 | 出现阶跃,上游有变更 | 交互式场景 |
第六项测的是时间而不是内容,价值在于对上游变更最敏感:内容层退化往往渐进,处理链路的变化会立刻反映在首字节耗时上。把它和内容类指纹放在同一张看板上,能更早察觉"上面确实动了什么"。
⚠️代码待验证
# 行为指纹:看一组固定特征在一批样本上的分布,而不是看单条输出deffingerprint(outputs,tool_call_counts):lens=sorted(len(o)foroinoutputs)n=len(lens)return{"len_p10":lens[int(n*0.10)],"len_p50":lens[int(n*0.50)],"schema_ok_ratio":sum(1foroinoutputsifis_valid(o))/n,"tool_calls_per_task":sum(tool_call_counts)/len(tool_call_counts),"refusal_ratio":sum(1foroinoutputsifis_refusal(o))/n,}deffingerprint_shift(today:dict,baseline:dict,band:float=0.15)->list:"""只报超出容忍带的指纹项,避免每天刷出一堆噪声告警"""return[kfork,vintoday.items()ifkinbaselineandabs(v-baseline[k])>band*max(abs(baseline[k]),1e-9)]容忍带要按指纹分别调:长度类指标波动大,带宽放宽;结构化完整度平时很稳,一变化就很有信息量,带宽收窄。用同一套阈值套所有指纹,要么天天误报,要么真正的问题被埋掉。
七、一次完整排查路径与复盘产出
把前面六章串起来,就是一条完整的排查路径。以下是实际执行顺序,前一步没有结论就不要进下一步。
- 提取线索并复现。记录原始描述、时间点、涉及的任务类型,从反馈里找出"可以复现的那一条输入",现跑几次看现象是否稳定。不稳定说明落在采样噪声里,转入批量样本判断。
- 查自己这边。按第二章的顺序表从上往下走,任何一步命中就先处理,不跳步。
- 跑对照组。与留档的基线比较一致条数,确认是系统性偏移还是正常波动。核心产出是一个数字,不是一个印象。
- 锁定环节。用两段替换扫描逐个排除提示词侧与参数侧;前两段都排除后,结合漂移集中的任务类型指向模型行为层。
- 先上缓解。提示词加固与产品侧降级是分钟级动作,先顶住;解析侧兜底要改代码,排在当天;路由切换按判据执行。
- 给结论并留档。写清四件事:漂移到哪一层、影响哪一类任务、当前用什么兜底、回切条件是什么。
- 加入复检。把这条链路临时提高巡检频率,直到对照组回到容忍带以内,再恢复常规频率。
7.1 复盘要产出两样东西
复盘必须产出两样可执行的东西,否则这次排查的经验会在下一个人接手时归零。
第一样:对照组新增样本。把这次出问题的输入按"最小可复现"改造后加入对照组并补上机器判据。硬要求是——每条新增样本必须能区分"正常"和"这次这种漂移";如果在正常状态和漂移状态下判定结果相同,它进对照组只是占位置。
第二样:兜底能力补强项。回答一个问题:这次是解析侧没兜住,是产品侧没降级,还是巡检根本没覆盖这条链路?答案要拆成可验收的条目,写明改哪一层、谁来改、用什么判据验收。
⚠️代码待验证
{"review_id":"drift-review-2026-10-01","finding":{"layer":"prompt_or_params_or_upstream","task_types":["summary","structured_extract"],"consistent_before":36,"consistent_after":31,"total_cases":40},"mitigation":{"prompt_hardening":true,"parse_fallback":"lenient_parse + strict_validate + retry_once","route_switch":{"enabled":false,"reason":"漂移未集中在单一路由"},"product_degrade":"长文任务降级为返回提纲"},"new_cases":[{"id":"case-311","checks":["has_sections>=3","cites_source"],"why":"本次复现输入"}],"hardening_items":[{"layer":"parse","desc":"字段缺失时按段落结构回填,不直接丢弃","owner":"api-team","accept":"对照组该 case 恢复一致"}],"rollback_condition":"一致条数连续三次巡检进入容忍带"}这份留档里三个字段最值得保留:consistent_before与consistent_after构成可回溯的数字证据;rollback_condition防止切换后无人回切;new_cases保证这次的经验沉淀进了巡检集,而不是停留在聊天记录里。
上游的行为不是你控制的变量,它是你依赖的外部条件。既然无法要求它不变,能做的就是把它变成一件可以被观测、可以被度量、可以被兜住的事情。从"感觉变笨了"到"一致条数从三十六掉到三十一,集中在两类任务,判定为上游行为变更,按路由判据切入备用路线并设定回切条件",这两句话之间的距离就是运维能力本身。
完整版资料清单:本文用到的漂移排查对照表与行为指纹模板都整理在里面了,扫码即可获取:
附表 A:关键取舍一览
| 取舍 | 本文结论 | 判断依据 | 位置 |
|---|---|---|---|
| 漂移的判定单位 | 一批样本的一致条数 | 单条输出本身有随机性 | 第一章 |
| 先查自己还是先问上游 | 先查自己 | 自己的改动才能立即回滚 | 第二章 |
| 对照的粒度 | 批量样本,不用单句两问 | 单句测方差,需求是均值 | 第三章 |
| 判定标准 | 事先写死的机器判据 | 人工判据前后不可比 | 第三章 |
| 归因方法 | 一次只换一段 | 多变量同动无法归因 | 第四章 |
| 上游能否回退 | 不能,只能比历史留档 | 上游不受你控制 | 第四章 |
| 提示词加固方向 | 补显式约束,不追求更长 | 约束过密会顾此失彼 | 第五章 |
| 路由切换与回切 | 按任务类型切,回切条件写死 | 切出去没人催就是长期路线 | 第五章 |
| 基线怎么更新 | 人工确认,不自动刷新 | 自动刷新会吸收缓慢下滑 | 第六章 |
| 复盘产出 | 新样本 + 兜底补强项 | 只写结论下次等于重来 | 第七章 |
附表 B:术语速查表
| 术语 | 含义 |
|---|---|
| 行为漂移 | 未发版、无报错的前提下,同一批输入的输出分布随时间整体偏移 |
| 对照组 | 一批冻结输入配合冻结判定标准,定期运行并与基线比较 |
| 基线 | 由最近若干次巡检结果构成的参照区间,带容忍带 |
| 容忍带 | 基线上下允许的波动范围,用于区分正常波动与真实偏移 |
| 一致条数 | 本次判定结果与基线判定结果相同的样本数量 |
| 行为指纹 | 一组可机器判定的输出特征组成的向量,用于比较分布移动 |
| 拒识 | 模型以拒绝、免责或要求换问法的方式回避作答 |
| 逐段替换 | 一次只替换提示词、参数、模型行为三段中的一段以定位归因 |
| 回切条件 | 从备用路线退回主路线所需满足的判定条件,与切换判据同时定义 |
写在最后:这篇用到的资料
写这篇文章时,我把几个线上链路里遇到过的行为变化重新梳理了一遍,顺手整理成几份配套的东西:
- 大模型学习路线图:从 LLM 基础到 Agent 开发,各阶段该学什么、用什么资料
- 大模型全套教程:按主题分好的视频与文档清单
- 大模型实战好书:24 本,附每本适合的阶段
资料是我自己整理的,放在下面这个码上,扫码即可获取:
添加时备注「大模型」,优先通过。
拿到之后建议先看学习路线图那一份,先定位自己在哪个阶段,再决定学什么,比一上来就啃框架效率高得多。