☰
模型输出垃圾?读代码才能根治:从现象到定位的排查指南
2026/10/26 23:47:17 网站建设 项目流程

在调试大语言模型或传统机器学习模型时,最让人头疼的往往不是模型报错,而是模型“成功运行”后输出了一堆莫名其妙的垃圾。垃圾输出可能是一段重复的文本、一个完全错误的标签、一段格式混乱的 JSON,也可能是一段看似通顺但结论明显错误的回答。很多人遇到这种情况,第一反应是继续问模型、换 prompt、调 temperature,甚至怀疑模型文件坏了。但实际排查下来,真正的原因往往不在模型本身,而在调用模型的那段代码里。不读代码,就只能看到“输出很垃圾”这个结果;读了代码,才能知道垃圾是在哪个环节被生产出来的。下面会从概念、现象、定位链路、代码示例、常见坑和工程规范几个方向讲清楚:为什么识别模型垃圾输出必须读代码。

1. 先理解“模型垃圾输出”到底是什么

1.1 垃圾输出的定义和本质

“模型垃圾输出”并不是一个严格定义的学术词汇,在工程里通常指模型在推理阶段返回的无意义结果。它既包括肉眼可见的乱码,也包括结构上正确但语义错误的标签,甚至包括看起来非常流畅但完全不符合业务要求的回答。

从系统性角度看,输出是整条数据链路的产物。一个文本从原始输入到最终返回,至少经过预处理、tokenizer、前向计算、解码采样、后处理五个环节。任何一个环节出现 bug,都可能让模型输出变成垃圾。权重文件损坏会产生垃圾,tokenizer 词表错位会产生垃圾,prompt 模板拼接错误会产生垃圾,解码参数设置极端会产生垃圾,后处理解析失败也会产生垃圾。

正因为如此,光看输出结果去猜模型好坏,几乎不可能定位根因。通常的做法是,把输出当作一个“报警信号”,然后沿着代码调用链一层一层往回查。只有同时看到模型的前向计算代码、tokenizer 解码代码、后处理代码和数据映射代码,才能判断垃圾到底在哪一层产生。

1.2 从输出类型反推问题范围

不同形态的垃圾输出,往往指向不同代码层的问题。下面这张表可以作为快速分诊工具:

输出类型典型现象常见代码层原因检查方向
乱码输出包含无法识别的 Unicode、替换符tokenizer 词表错位、编码方式不一致tokenizer 加载路径与权重路径
重复文本同一句话重复几十遍采样参数缺失或温度过低no_repeat_ngram_size、repetition_penalty
标签错位输入正面内容,输出“愤怒”标签label2id/id2label 映射不一致训练代码与推理代码的标签列表
格式错误JSON 被截断、括号不匹配生成长度过短、停止词设置缺失max_new_tokens、stopping criteria
看似合理但错误文字通顺,数值或结论不匹配prompt 模板误导、数据清洗顺序不一致prompt 拼接代码、数据预处理代码

注意,这里的“输出类型”只是分诊入口。真正定位时,还是要落回代码。比如“标签错位”这一行,表面看是模型预测错了,但读代码后会发现,模型预测的索引其实是对的,错的是推理侧手动写的id2label。

1.3 为什么“输出通顺”会掩盖问题

大模型发展到今天,文本层面的流畅度已经很高,这带来一个副作用:人眼很容易被“看起来像人话”的输出误导。一段输出即使语法完全正确,也可能在业务上完全不可用。

举例来说,一个信息抽取模型把一句话完整返回,但缺少了 promise 的name字段;一个代码生成模型生成了一段可读但调用了不存在 API 的代码;一个分类模型把“正面情绪”识别成“negative”标签,但因为标签映射错误,显示出来的是“平静”。这些输出本身并不乱码,甚至可以被业务系统接收,但最终结果仍然是垃圾。

只有读代码,才能判断输出是否满足“契约”。这个契约包括:字段是否齐全、类型是否正确、标签是否属于预定义集合、生成内容是否被截断、特殊 token 是否被过滤。肉眼只能看见文本,代码才能看见约束。

判断模型输出是否正常,不能只看输出文本里有没有人话,还要看输出是否满足业务约束、是否符合模型接口的返回契约。

2. 不读代码时,你会被哪些表面现象误导

2.1 表面通顺但业务不可用

业务系统往往要求模型输出结构化内容,例如 JSON、SQL、分类标签或固定格式代码。此时,一段语句通顺的文本反而可能是垃圾输出。

一个典型场景是使用模型做客服工单分类。模型返回“这个问题需要转人工处理”,文本很通顺,但业务字段category_id是空字符串。最终下游系统无法路由工单,只能记录为失败。这个问题的根因通常在后处理代码:解析模型返回时没有校验字段是否存在,遇到缺失字段直接给默认值,或者try...except把异常吞掉。

要识别这类垃圾输出,必须读后处理代码。后处理是模型输出进入业务系统前的最后一道闸门,也是垃圾输出最容易隐藏的地方。

2.2 高置信度也可能来自错误 logits 映射

分类模型通常会输出每个类别的概率,很多人会认为softmax分数越高,结果越可靠。但如果id2label映射写错,置信度再高也是无用。

下面这段代码很常见:

import numpy as np logits = np.array([2.5, 0.2, 0.1]) prob = np.exp(logits - logits.max()) / np.exp(logits - logits.max()).sum() pred_id = int(np.argmax(prob)) # 训练时 id2label = {0: "positive", 1: "negative", 2: "neutral"} # 推理时却写成了 {0: "neutral", 1: "positive", 2: "negative"} print(id2label[pred_id])

如果推理代码里的id2label和训练代码不一致,模型明明预测了positive,最终输出的却是negative。表面看是“模型预测错了”,实际是代码映射错了。此时无论怎么调模型参数,都改不了这个 bug。

2.3 “看起来像代码”的文本不一定可执行

当模型用来生成代码时,输出文本看起来可能很像代码,但直接运行会报错。常见情况包括:变量名拼写错误、调用不存在的库函数、函数参数位置错误、缩进被 markdown 代码块污染。这类输出只有在执行验证时才会暴露问题。

因此,代码生成场景不能只靠人眼阅读输出来判断,应该在评估脚本中对生成代码做语法解析、编译或单元测试。否则,一段“像模像样”的垃圾代码会一直被当作正常结果。

2.4 随机性让表面变化掩盖固定 bug

大模型解码阶段带有很多随机因素,do_sample=True、temperature>0、top_p都会让每次输出不同。同一个输入,第一次返回“好的”,第二次返回“没问题”,第三次返回长篇大论。这时候人很容易误以为模型状态正常,只是随机波动。

但如果固定 seed、固定参数后重新运行,输出仍然有问题,排查链路就会清晰很多。随机性不能掩盖代码 bug,却会让人把 bug 误判成“模型偶尔抽风”。不读代码、不确定随机种子,就很难区分固定 bug 和随机采样噪声。

import random import numpy as np import torch random.seed(42) np.random.seed(42) torch.manual_seed(42) torch.cuda.manual_seed_all(42)

排查垃圾输出时,第一件事就是固定随机种子,复现同一条输出路径。

3. 从输出反查代码:一条可复用的定位链路

3.1 固定输入、固定 seed、固定参数

任何定位工作都需要稳定的复现条件。先保存触发垃圾输出的原始输入,再固定全局随机种子、解码参数、batch size 和运行设备,最后重新运行一次推理脚本。

python infer.py --input "今天天气不错" --seed 42 --max_new_tokens 128

这样做的目的,是把问题从“模型不稳定”中剥离出来。如果固定条件下能复现,说明存在确定性的代码路径;如果不能复现,可能是上游输入、并发状态或显存初始化问题,也要从代码中继续排查。

3.2 从输出向前逐个环节检查

推荐按照下面的顺序检查:

  1. 打印原始输入字符串,确认不是上游传入了None、空串或不可见字符。
  2. 打印输入经过 tokenizer 后的input_ids,确认与文本能对应上。
  3. 打印模型原始logits和预测索引,确认模型输出索引是否合理。
  4. 打印id2label或tokenizer.decode结果,确认索引映射是否正确。
  5. 打印后处理函数的输入输出,确认结果是否被规则改写或截断。

每到一个环节,都把当前结果与预期对比。只要某一步的输出不符合预期,问题就定位到这一步。

下面是一个简单的中间结果检查示例:

from transformers import AutoTokenizer tokenizer = AutoTokenizer.from_pretrained("my_model") inputs = tokenizer("今天天气不错") print(inputs["input_ids"]) print(tokenizer.convert_ids_to_tokens(inputs["input_ids"]))

如果convert_ids_to_tokens打印出来的 token 与文本含义不一致,说明 tokenizer 加载或词表有问题,后续生成的垃圾输出就不难解释了。

3.3 用“最小样本 + monkey patch”定位数据流

在复杂项目里,原始输入到模型输入之间可能隔着很多自定义函数。为了不打断业务逻辑,可以用临时 monkey patch 在关键入口打印中间结果。

original_decode = tokenizer.decode def debug_decode(*args, **kwargs): result = original_decode(*args, **kwargs) print("[decode]", args[0], "->", result) return result tokenizer.decode = debug_decode

这只是一个临时排查手段,定位完就要移除。它适合在本地或测试环境使用,生产环境不要保留此类调试代码。

3.4 区分训练代码与推理代码不一致

训练和推理最常见的冲突,是“同一份配置写了两遍”。训练代码里保存了一份label_list,推理代码里手写了一份,时间一长两处就不同步了。

配置项训练时代码推理时代码不一致后果
标签顺序["愤怒", "喜悦", "平静"]["平静", "喜悦", "愤怒"]所有标签错位
文本清洗先去掉换行再分词未去换行直接分词输入分布不一致
字符编码统一 UTF-8 写入按系统默认编码读取乱码

读代码时,要重点比对这两份代码对同一份数据处理方式。如果训练和推理的预处理逻辑不完全一致,垃圾输出几乎是必然的。

4. 用最小代码示例识别一次“垃圾输出”

4.1 场景描述

假设训练了一个中文情感分类模型,类别包括“喜悦”“愤怒”“平静”。训练结束后,验证集准确率 0.95。但到了推理阶段,输入“今天天气不错,我很开心”,模型返回“愤怒”。

直观判断,模型输出垃圾。但模型权重没有任何变化,为什么离线验证正常、在线推理出错?

4.2 表面现象:模型输出了错误标签

下面是一段常见的推理代码:

# infer.py import torch from transformers import AutoModelForSequenceClassification, AutoTokenizer model = AutoModelForSequenceClassification.from_pretrained("my_sentiment_model") tokenizer = AutoTokenizer.from_pretrained("my_sentiment_model") # 注意:推理代码里手动写了 id2label id2label = {0: "平静", 1: "愤怒", 2: "喜悦"} text = "今天天气不错,我很开心。" inputs = tokenizer(text, return_tensors="pt") with torch.no_grad(): logits = model(**inputs).logits pred = int(logits.argmax(-1)) print("预测结果:", id2label[pred])

运行后输出:

预测结果: 愤怒

从文本来看,这句话应该是“喜悦”,输出“愤怒”明显是垃圾输出。

4.3 读代码后发现根因

在训练代码中,类别顺序可能是:

label2id = {"愤怒": 0, "喜悦": 1, "平静": 2} id2label = {v: k for k, v in label2id.items()}

也就是说,模型内部预测的索引1本来对应“喜悦”。但推理代码里手写的id2label[1]却对应“愤怒”。模型没有错,错的是推理侧索引映射。

要验证这个判断,可以打印模型的预测索引和配置信息:

print("pred index:", pred) print("config id2label:", model.config.id2label)

输出会显示类似:

pred index: 1 config id2label: {0: "愤怒", 1: "喜悦", 2: "平静"}

到这里,问题已经定位:预测索引是 1,对应模型配置里的“喜悦”。推理代码手写的映射把 1 映射成了“愤怒”。

4.4 修复后的变化

不要手写id2label,直接使用 checkpoint 中的配置:

id2label = model.config.id2label

再运行一次:

预测结果: 喜悦

这个例子很小,但很能说明问题:垃圾输出并不一定来自模型权重,而可能来自推理代码与训练代码之间的不一致。不读代码,永远看不见映射错误。

4.5 这个案例说明什么

模型输出是“结果”,代码链路是“过程”。同一个结果可能对应完全不同的原因。面对垃圾输出时,先保存证据,再检查代码,而不是先换模型或调 prompt。一旦固定了输入和输出,再对代码做逐层反查,大多数问题都能在几分钟内定位。

很多看似“模型变笨了”的问题,最后查出来都是权重路径、tokenizer 或标签映射写错。不要急着怪模型。

5. 读代码时的关键检查点:从模型加载到输出返回

5.1 检查模型权重路径和版本

模型部署最隐蔽的问题是加载了错误的权重。服务进程没有重启,代码里写的是绝对路径,但在另一台机器上路径不同,导致加载了同名旧权重。这类问题不读代码很难发现。

建议在推理代码里增加启动日志,打印完整模型路径、文件大小和校验值:

ls -l model_dir/ sha256sum model_dir/pytorch_model.bin

同时将模型版本与代码 commit 绑定,避免“权重更新了但代码没有同步更新”的错位。

5.2 检查 tokenizer 与 vocab 对齐

文本生成模型输出乱码,最常见的原因不是模型参数出了问题,而是 tokenizer 词表和模型权重不是同一份。

可以在代码里加一个检查:

print("tokenizer vocab size:", tokenizer.vocab_size) print("model vocab size:", model.config.vocab_size) print("len(tokenizer):", len(tokenizer))

两个数字不一致时,要优先检查from_pretrained的目录是否指向了同一个 checkpoint。有些项目用本地目录加载模型权重,却用线上 tokenizer 目录加载词表,出现错位就不奇怪了。

5.3 检查解码参数

解码参数是生成类模型垃圾输出最集中的来源。下面是常见参数汇总:

参数含义常见范围错误设置可能导致的垃圾输出
temperature采样温度0.1 ~ 1.0过高时输出随机词,句子无逻辑
top_p核采样累积概率0.8 ~ 0.95过低时句式单调、容易重复
top_k候选词数量20 ~ 100过小时语义狭窄
repetition_penalty重复惩罚1.0 ~ 1.3过高时语义混乱,过低时重复
no_repeat_ngram_size禁止 n-gram 重复3 ~ 5缺失时出现死循环式重复
max_new_tokens最大生成长度任务相关过短截断 JSON,过长输出废话
do_sample是否随机采样false / true需要稳定结果时开启会产生波动

读代码时,不只要看参数有没有写,还要看它们被用在了哪里。有些推理代码定义了参数,但生成时忘记传给generate()方法,等于没有生效。

5.4 检查后处理中的过滤、截断和规则改写

后处理函数经常是垃圾输出的“最后一公里”。比如有人用字符串替换清理模型输出:

cleaned = output.replace("\n", "").replace(" ", "")

这会把 JSON 字符串里的空格全部删除,导致json.loads失败,甚至改变代码语义。还有人在后处理里用正则截取子串,正则写错了,就会把有效内容全部截掉。

针对后处理代码,要检查三点:

  • 是否有必要的字段完整性校验。
  • 是否有异常分支,是否把异常静默吞掉。
  • 对输出长度、特殊字符、特殊 token 的处理是否符合预期。

5.5 检查 batch inference 和 collate_fn

批量推理时,padding 和 attention_mask 一旦写错,模型会对被 padding 的位置也做注意力计算,导致整个 batch 的输出错乱。

检查collate_fn时,至少确认两点:

def collate_fn(batch): input_ids = [item["input_ids"] for item in batch] attention_mask = [item["attention_mask"] for item in batch] return { "input_ids": torch.tensor(input_ids), "attention_mask": torch.tensor(attention_mask), }

第一,attention_mask是否真的被传入模型;第二,padding token 是否与模型配置一致。只有 padding,没有 mask,是批量推理垃圾输出的高频原因。

6. 常见“垃圾输出”的现象、根因与修复

6.1 模型输出全是同一个 token 或重复文本

现象:生成结果类似"好的好的好的好的...",几十甚至几百个字都在循环。

常见根因:no_repeat_ngram_size没有设置,temperature设置过低,top_p设置过小,导致模型陷入高概率循环带。部分模型自身也可能存在训练数据中的重复模式。

检查方式:打印每一步生成的 token 和对应概率,观察连续几步是否都在同一个 token 上。

修复方式:

generate_kwargs = { "max_new_tokens": 128, "temperature": 0.8, "top_p": 0.9, "no_repeat_ngram_size": 3, "repetition_penalty": 1.1, "early_stopping": True, }

参数需要结合模型和任务微调,不要直接照搬。

6.2 输出包含</s>、<unk>、<pad>等特殊符号

现象:模型返回内容中出现<unk>、</s>、<pad>或[UNK]。

常见根因:

  • 生成后调用tokenizer.decode时没有设置skip_special_tokens=True。
  • tokenizer 加载错误,<unk>索引被当成正常 token 生成。
  • 输入文本包含太多词汇表外的字符,模型只能生成<unk>。

检查方式:打印tokenizer.special_tokens_map,确认特殊 token 对应的 id;再打印解码时的参数。

修复方式:

tokenizer.decode(generated_ids, skip_special_tokens=True)

如果是词表错位,需要重新加载与权重匹配的 tokenizer 目录。

6.3 生成 JSON 或代码时被截断

现象:模型返回{"name": "张三", "age":,JSON 明显不完整。

常见根因:max_new_tokens设置得太小,生成到一半被截断;没有配置针对结束 token 的停止策略;后处理没有校验 JSON 是否合法。

检查方式:增加最大长度,查看完整生成结果;检查是否在结束 token 或停止词处截断。

修复方式:为结构化任务设置足够的生成长度,同时在代码中实现停止条件。示例:

from transformers import StoppingCriteria, StoppingCriteriaList class StopOnToken(StoppingCriteria): def __init__(self, stop_token_id): self.stop_token_id = stop_token_id def __call__(self, input_ids, scores, **kwargs): return input_ids[0, -1] in self.stop_token_id stop_criteria = StoppingCriteriaList([StopOnToken(stop_token_id)])

不过停止 token 并不是万能方案。对 JSON 生成任务,更稳妥的做法是在输出后做语法校验,解析失败时触发重试或降级逻辑。

6.4 输出标签或分数与业务预期完全错位

现象:分类模型返回的标签名称看起来正常,但分布与业务完全对不上;或者排序模型给出的分数极高,但排序结果不合理。

常见根因:label2id和id2label映射不一致;训练时数据清洗了特殊字符,推理时没有清洗;模型输出 logits 被错误地套上了 softmax,导致阈值判断失效。

检查方式:打印训练时保存的映射和推理时使用的映射,逐项对比。

修复方式:训练结束时,把label2id和id2label写入模型配置:

model.config.label2id = label2id model.config.id2label = id2label model.save_pretrained("output_dir")

推理时直接从model.config读取,禁止手写映射表。

6.5 多语言混合或乱码

现象:输入中文,模型输出中夹杂英文、拼音或不可读字符;输出显示é”™这类编码错误。

常见根因:模型权重与 tokenizer 不是同一份;预处理阶段编码不一致;生成时skip_special_tokens=True但 tokenizer 的解码逻辑有版本差异。

检查方式:

print(tokenizer.decode(tokenizer.encode("测试")))

如果解码结果不是“测试”,说明 tokenizer 自身有问题。还要检查模型文件目录下是否真的包含vocab.txt、tokenizer_config.json等文件。

修复方式:使用与模型权重同目录的 tokenizer,重新保存并加载配置。不要在运行时用AutoTokenizer去远程自动下载,避免版本漂移。

7. 建立“输出可回溯”的工程规范

7.1 每次推理都留痕

垃圾输出只要发生一次,就必须能回到当时的输入、参数和模型版本。推荐为每次推理生成唯一的request_id,并把关键信息记录到日志或结构化存储中。

{ "request_id": "req_20250610_001", "model_version": "bert-sentiment-20250601", "commit_id": "a1b2c3", "input_text": "今天天气不错,我很开心。", "output": "喜悦", "params": { "temperature": 0.2, "top_p": 0.9, "max_new_tokens": 128 } }

有了这份记录,读代码时就不需要靠“我记得当时怎么调的”来回忆,直接复现现场即可。

7.2 把模型版本和代码版本绑定

模型文件除了存放权重,还要在 config 或目录中记录训练代码 commit、训练数据版本、PyTorch 版本和 tokenizer 版本。否则换一台机器部署时,很容易出现“权重是新的,代码是旧的”的错位。

可以在保存模型时写一个额外的version.json:

{ "model_name": "sentiment_bert", "train_commit": "a1b2c3", "data_version": "20250601", "tokenizer_path": "models/sentiment_tokenizer" }

7.3 准备回归用例集

针对垃圾输出建立一套固定回归用例,每个用例包含输入、期望输出、允许误差范围。当模型或代码变更后,先运行回归用例,再上线。

用例不需要多,但要覆盖易错点:

  • 空字符串输入。
  • 英文、中文、日文混合输入。
  • 特殊符号和 emoji 输入。
  • 超长输入。
  • 需要输出 JSON 的指令。
  • 需要输出固定标签的指令。

7.4 将“读代码”纳入模型交付评审

很多团队在评审模型时,只看评估指标,不看推理代码。但指标只反映验证集上的平均表现,代码 bug 会直接污染真实输出。评审清单至少包括:

  • 模型权重路径是否可复现。
  • tokenizer 与模型 vocab 是否一致。
  • label2id/id2label是否来自训练代码。
  • prompt 模板是否与训练时一致。
  • 解码参数是否固定并有依据。
  • 后处理是否校验输出格式。
  • 失败分支是否记录日志并返回可理解错误。

这些项都要求评审者真正阅读代码,而不是只看输出样例。

7.5 发布前检查清单

实际部署前,可以按下面这份清单逐项打勾:

  1. 输入字符能在 tokenizer 中正确编码。
  2. 模型能加载权重,且打印的 vocab_size 与 config 一致。
  3. generate传入的参数与预设完全一致。
  4. 后处理能解析合法输出,非法输出不会被静默吞掉。
  5. 日志中包含 request_id、输入、输出、模型版本和代码 commit。
  6. 固定 seed 后回归用例输出稳定。
  7. 特殊 token、重复文本、JSON 截断三种垃圾输出有对应测试用例。

清单看起来琐碎,但在排查“模型输出时好时坏”的问题时,能节省大量时间。

8. 扩展:从一次定位到系统性监控

8.1 离线回归测试

把垃圾输出排查经验沉淀成自动化测试。每个根因对应一个用例,防止同类 bug 再次出现。

def test_output_without_special_tokens(): output = infer("请回答:天气怎么样") assert "<unk>" not in output assert "</s>" not in output def test_output_json_valid(): result = infer("请返回一个 JSON:{\"name\": \"张三\"}") assert json.loads(result)["name"] == "张三"

这些测试不需要覆盖所有场景,只需要覆盖最容易出错的契约。每次改代码、改模型、改参数后运行一遍,能提前拦截大部分回归问题。

8.2 在线监控指标

生产环境需要对模型输出做实时监控。同一类垃圾输出出现频率升高时,说明可能有上游数据变化、代码配置变更或模型缓存未更新。

可以统计以下指标:

  • 无效 JSON 率。
  • 特殊 token 出现率。
  • 输出完全重复率。
  • 输出平均长度是否偏离基线。
  • 分类标签分布是否发生漂移。
  • 请求超时和 retry 次数。

监控代码通常不复杂,关键是把“垃圾输出”变成可量化的指标:

signals = { "invalid_json_rate": invalid_json_count / total_count, "special_token_rate": special_token_count / total_count, "duplicate_ngram_rate": duplicate_ngram_count / total_count, }

8.3 日志与告警

不要让垃圾输出静默进入业务系统。在后处理阶段增加告警逻辑,一旦发现非法格式、特殊 token、重复文本,立即记录异常并返回降级结果。

告警信息至少包含:

  • 当前模型版本。
  • 当前代码 commit。
  • 原始输入和输出。
  • 触发告警的具体原因。

这样,下次再出现“模型垃圾输出”,你手头已经有一份完整现场,可以直接开始读代码,而不是从零排查。

8.4 最终判断:垃圾输出不是模型单方面的问题

在 Transformer 模型、扩散模型、模型蒸馏、模型融合以及各种部署实践中,垃圾输出的表现各不相同,但根因都落在代码链路里。vLLM在某些加速卡环境下无法启动 Embedding、Reranker 模型,输出为空或直接抛错,是部署代码与硬件不兼容;蒸馏模型输出分数分布不合理,是教师模型、学生模型和推理逻辑没有对齐;模型融合后标签混乱,是融合层的映射表写错。

识别模型垃圾输出的能力,不是靠猜,而是靠读代码建立起来的。一旦你在一条数据链路上反复定位过几回,就会明白输出只是最后一声警报,真正的病灶往往藏在读取权重、拼接 prompt、解析结果那几行代码里。下一次再看到模型输出异常,建议先把输出连同请求原始输入保存下来,然后从推理代码第一行开始往前读,你会比反复调 prompt 更快找到答案。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询