上个月接了个私有化部署的法律咨询问答机器人,客户指定要用Qwen2.5-7B。我一开始按照老习惯,先拉了个基线测试集,然后开始调参。跑了三天的LoRA微调,损失函数曲线漂亮得像教科书一样,但一到真实用户提问就翻车。用户问“我合同里写了违约金30%,但对方只付了10%,我能起诉吗?”模型直接回答“请咨询专业律师”。你气不气?我后来才发现,问题不在模型,在于我还在用传统软件工程的思维去定义输入输出。传统开发里,输入是确定的,接口文档写上参数类型、范围,你永远不用担心用户传一个“null”或者“字符串里带表情符号”。但AI开发面对的是开放域输入,哪怕你做了系统提示词限制,用户还是会用你完全没想到的方式提问。这不是加几个few-shot就能解决的,你需要从概率分布的角度理解这个问题——模型的输出不是一个确定的返回值,而是基于训练数据和推理参数采样出来的一个概率事件。temperature=0.1的时候看似稳定,但一旦遇到长尾输入,输出的熵会爆炸,你根本不知道它会落在哪里。
我后来做了一个实验,把同一个问题换了几十种说法,去掉标点、加入错别字、用方言口吻、甚至故意用繁体字。结果准确率从78%直接掉到41%。这个差距远超我的预期。而且最致命的是,传统软件工程的测试用例是有限的,你测1000条用例就能覆盖绝大多数情况,但AI输入的组合空间几乎是无限维的。你没法穷举,只能靠采样。后来我干脆放弃了追求100%准确率,改成设计一个置信度阈值加兜底话术。具体做法是:用模型输出的logits计算熵值,当熵值超过0.8的时候,就返回“这个问题我不确定,建议转人工”。这个阈值是拿200条真实用户问题标注出来的,代价不小,但效果立竿见影——客户投诉率降了60%。
再说到微调,网上那些说“用几百条数据就能让模型学会新领域”的教程,大部分是扯淡。我试过用500条高质量法律问答做LoRA,rank=16,alpha=32,learning_rate=2e-4,训练3个epoch,效果还不如直接改system prompt加一个检索外部知识库的脚手架。为什么?因为7B模型的知识容量就那么点,你强行让它在低秩矩阵里塞新的法律条文,它会“灾难性遗忘”,把之前的通用能力也搞坏了。后来我改成了RAG方案,用Elasticsearch存了10万条判例,每次请求检索top-5文本拼到上下文里,准确率直接上到89%。这个教训就是:AI开发里,模型微调是最后的手段,而不是第一选项。先想办法把输入空间压缩到可控范围,再考虑怎么调权重。
还有个很多人忽视的点——评估指标。传统软件你写个JUnit就完了,AI开发你拿什么评估?Blue?Rouge?还是GPT-4打分?我全试过,没有一个靠谱的。本来想用GPT-4当裁判,但客户数据不能出内网,只能自己写评估脚本。后来我用人工标注+分层抽样的方式,把测试集按问题难度分成三层:简单、中等、难,分别计算准确率和平均响应时间。结果发现,模型在简单问题上的准确率有95%,但难度大的只有33%,而这类难问题恰好是客户最看重的。要是只看平均分,你根本发现不了这个问题。所以我的建议是:AI开发的评估必须分场景、分人群,甚至分时间段,因为用户在不同状态下提问的方式完全不一样——半夜问问题和上班时间问问题,句子长度和语气都有统计差异。
最后还是想吐槽一下,现在很多团队所谓的“AI开发”其实就是调包侠,一上来就接OpenAI的API,然后写一堆if-else判断用户意图。这不叫AI开发,这叫用JSON格式化输出。真正的AI开发是从数据分布、模型不确定性、算力成本三个维度重新思考整个系统设计。你现在要做的第一件事,不是急着写代码,而是去翻你过去三个月的用户日志,统计一下都有哪些提问是模型完全答不上来的。把这些案例做成你的负样本集,你才刚开始入门。