ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

AI工程从零开始:系统化架构与实战路径全解析

AI工程从零开始:系统化架构与实战路径全解析 1. 项目概述当“AI工程师”不再是招聘广告上的黑话“ai-engineering-from-scratch”这个名字第一次出现在我屏幕上的时候我愣了一下。不是因为它有多难懂恰恰相反——它太直白了直白到让人怀疑是不是谁把文件夹命名规范搞错了。但从那一刻起我就知道这绝不是一个普通的项目标题。它代表着一个信号有人想把“AI工程师”这个被各种培训班、招聘启事和社交媒体反复包装的标签重新拉回地面然后从零开始一砖一瓦地搭起来。这个项目解决的问题其实非常朴素AI工程到底是什么它和“调个API”“跑个模型”“写个Prompt”有什么关系如果我现在是一个完全没有AI基础的开发者或者是一个在工作中被AI浪潮裹挟的产品经理、测试、运维我该从哪里开始市面上有铺天盖地的“Prompt Engineering”课程有“AI应用开发”的速成班也有动辄几万字的大模型原理科普但很少有一个项目愿意老老实实地告诉你别急着碰那些花哨的模型我们先把AI工程的骨架搭好——“from scratch”。我个人的理解是这个项目适合三类人。第一类是传统软件工程师想转做AI方向但不知道学的跟实际用的之间隔了多少层第二类是刚入门的学生或转行者需要一个从零到一、不依赖“读完就能月薪三万”承诺的扎实路径第三类是已经在用AI工具但总觉得自己在“表面滑行”、缺乏系统感的人比如天天写Prompt但不知道上下文窗口为什么是这个问题、不知道RAG检索增强生成为什么那样设计的人。一个合格的“从零开始”项目从来不应该是“把一堆工具罗列出来”而应该是一张地图。这张地图告诉你AI工程的地形是什么你站在哪往哪走会踩坑往哪走能见到真正的系统工程。所以下面我想从一个从业者的角度把这个项目的架构逻辑、核心环节、实操路径和常见坑全部摊开来讲。不讲玄的只讲我实际验证过的东西。2. 内容整体设计与思路拆解为什么“从零开始”比“从热门开始”更难2.1 从“模型调用”到“系统工程”的认知翻转如果你在Google上搜索“AI engineering”前几页大概率是某家云厂商的广告或者某个AI框架的文档再或者是一堆“掌握这些技能成为AI工程师”的列表文。但在真实的工业场景里AI工程师的工作远远不止“调用模型”这一步。一个真实的AI系统从需求到上线至少要经过数据获取与清洗、Embedding向量化设计、检索策略选择、Prompt模板管理、模型调用封装、缓存与限流、成本控制、评测反馈、监控告警、持续迭代这十个环节。我在这个项目里最核心的思路就是把“AI能力”当作一个系统组件而不是一个神秘黑盒。我们可以把大模型想象成一个刚入职的、能力很强但脾气古怪的新同事。你当然可以每次遇到问题都直接问他“这个怎么写”但你很快就会发现他回答的质量不稳定、上下文聊长了就“失忆”、有时候他还会一本正经地胡说。一个成熟的AI工程师做的事情不是整天跟这个新同事吵架而是设计一套工作流程——把该给它的资料先整理好RAG、把不适合它干的事分流出去传统程序处理、把它的回答统一验收校验与后处理、把它的表现记录下来Log与评测然后反馈到下一轮优化。这个思路在项目里有一个非常明确的体现它的内容编排不是“先学机器学习理论再学Deep Learning再学LLM”而是“先建立问题意识再掌握系统工程骨架最后围绕大模型应用深入”。这实际上是在模拟工业界真实的技能需求。在真正的项目中你没有那么多次“从头推导反向传播”的机会但你有无数次“这个召回结果不对我得调一下切分粒度”“这个Prompt的Few-shot例子放多了响应变慢”的机会。2.2 为什么我不建议“拿到模型先跑通再说”在项目的早期版本讨论中有一个常见的声音既然模型都开源了API也那么便宜为什么不先跑一个Demo看效果再回头补理论这听上去很务实但我在实际带人做项目时发现这个“先跑后补”的思路有巨大的隐患。因为它会让学习者陷入“调参-看结果-再调参”的循环而缺乏对整个系统瓶颈的感知。举个例子。你用一个开源的Embedding模型做私有知识库的问答第一次测试效果不好。你可能第一反应是换更大的模型或者加Prompt长度。但实际上问题很可能出在文档切分策略上——你把一个PDF按照固定字符长度切成500字的块而其中有大量章节是表格和代码切出来语义完全断裂。如果不理解“检索-生成”这条链路的整体逻辑你永远不会往那个方向排查。所以“ai-engineering-from-scratch”这个项目在设计思路上故意绕开了那种“五分钟跑通”的兴奋感转而去建立一种“系统级Debug”的思维习惯。这也是我认为这个项目最有价值的地方它不是在教你怎么使用某个工具而是在教你面对一个未知的AI问题时脑子里应该先弹出哪几个排查路径。2.3 项目结构的三层递进一个合格的从零项目应该像剥洋葱一样层递。如果项目直接把代码仓库、API文档、最佳实践扔到你脸上那叫资料汇编不叫工程路径。我个人的建议是这个项目可以分成三层结构而每一层都有独立的核心目标。第一层是“基础设施层”目标是把AI工程的地基打牢包括Python环境管理、基础数据处理、向量数据库选型、模型API统一封装。这一层解决的问题是你手里有什么工具它们各自能干什么不能干什么。第二层是“核心链路层”目标是构建一个最小可用的RAG系统包括文档加载、文本切分、Embedding、向量检索、上下文构建、LLM生成、结果后处理。这一层解决的问题是一个典型的企业知识库问答系统到底是怎么从一堆Word、PDF变成一个能回答问题的“数字员工”的。第三层是“生产化增强层”目标是把一个能跑的Demo变成一个能被业务方使用的系统包括评估集建设、Prompt版本管理、反馈收集与自动重写、成本优化、并发与流式输出、异常处理。这一层解决的问题是为什么Demo很好、上线就崩以及怎么避免这种悲剧。这样设计的好处是无论你最终做的是一个写文案的辅助工具、一个售后客服机器人还是一个代码生成助手你都能把这些“场景”映射到这三层结构里去。这就好比学厨——你先练刀工、火候再学一个完整的菜品流程最后学如何给菜品摆盘、控制上菜速度、处理客人反馈。换一道新菜你也不会慌。3. 核心细节解析与实操要点每一个环节都要知其所以然3.1 Embedding向量化不是你想象的“把文字变成数字”在接触这个项目的初期最容易犯的错误就是把Embedding当成一个“黑盒工具”传入一句话出来一串数字然后直接丢进向量数据库就算完事。但如果你多往前走两步你会发现这串数字的质量直接决定了整个RAG系统的天花板。我的实测经验是选Embedding模型时至少要关注三个维度维度大小、语义粒度、领域适应度。维度大小不难理解。比如OpenAI的text-embedding-3-small输出1536维而有些中文开源模型输出768维或1024维。维度越高理论上能表达的语义细节越丰富但存储成本和检索耗时也会增加。对于一个一万条文档的中小型项目这个差异不大但如果文档量到了百万级你就必须认真权衡。语义粒度就微妙得多。有些Embedding模型擅长短文本有些适合长文本。你在做文档切分的时候往往会把长文档切成几百字的“块”然后对每个块做向量化。如果你的模型擅长的是短文本匹配而不是长段落语义压缩那么切分出来的块性能会严重下降。领域适应度是最容易被忽略的。通用Embedding在可能被新闻、百科数据训练得很好但如果你处理的是医疗文献、法律条文、工业设备手册那种充满专业术语的文本通用模型往往会把近义词的语义特征压缩到几乎区分不开。我在一个设备维修文档项目中就遇到过这种情况把“液压泵漏油”和“液压泵密封失效”这两个短语向量化之后余弦相似度极高但这两个问题对应的维修动作是完全不同的。所以在这个项目里我强烈建议你单独开一个环节对不同Embedding模型做“领域小样本评测”。不要只看着公共榜单选模型要拿你自己项目的真实数据去测。选中一个基础模型之后再考虑要不要微调。注意对于大多数中小项目来说微调Embedding模型是性价比极低的事情先用好已有的模型把你的切分策略和检索策略调好往往就能解决绝大部分问题。3.2 文本切分决定你“AI记忆”粒度的那个隐形开关文本切分Splitting看起来是整个RAG链路里最“没有技术含量”的步骤但实际上它决定了系统的一半效果。我经常跟别人打比方切分文本就像给一个人安排记忆单元。你给的信息粒度太大他一次性消化不了就会遗漏关键内容你给的信息粒度太小他就容易只盯着局部而忘了上下文。在实操作上最简单的方案是按固定字符数切分比如500个字符重叠100个字符。但这只是纯机械的做法。更合理的做法是“递归字符切分器”——先按照文档本身的段落结构比如双换行、标题、序号去切切出来的块实在太大再按句子边界切实在不行再按字符数兜底。这样做的好处是尽量不把语义完整的段落拦腰截断。还有一个容易被忽略的参数叫“块重叠Chunk Overlap”。它的作用是在相邻两个块之间保留一部分重复内容从而让检索系统识别到跨越边界的语义信息。比如一篇技术文档里前半部分在介绍“什么是HTTP状态码”后半部分在介绍“4xx类错误如何处理”如果你切分时没有给两者之间留重叠那么当用户问“HTTP 404应该如何处理”时检索系统可能会命中偏向前半部分的那个块而那个块里根本没有具体的处理步骤。实操时我建议用“意图-回应”两个维度去检查切分质量。什么意思呢就是拿几个真实用户问题逐个去看检索系统召回的块问自己三个问题第一这个块是否真的包含回答用户问题的关键信息第二这个块的片段是否在语义上自洽第三如果在这个块上直接生成答案会不会因为缺失上下文而产生误导如果这三个问题里有任何一个不合格你的切分策略就需要调整。这个检查过程在项目里建议至少要完整做一轮因为很多问题在“加了更贵的大模型之后依然存在”的原因就是因为你没有回头看切分。3.3 检索策略向量检索不是唯一答案混合检索才更稳很多人在刚接触RAG时会有一个误解只要文档切好了向量化做好了直接按相似度返回Top-K块就行。但在真实业务里关键词的精确匹配能力往往比语义相似度更刚需。比如用户查询“发票号码”这个词如果在向量空间里检索它可能匹配到“票据编码”“财务凭证号”这种语义相近但字段完全不同的内容而用传统的关键词倒排索引却能精确命中“发票号码”这几个字所在的文档。所以现在的主流工程方案是“混合检索”Hybrid Search也就是同时跑一条向量检索通道和一条关键词检索通道然后把两边的结果用算法融合在一起。比较典型的融合方法有RRFReciprocal Rank Fusion倒数排名融合。RRF的原理非常朴素每个文档在两条通道里都会有一个排序位置把排序位置的倒数求和作为最终得分再按这个得分重新排序。这种方法的优势是不需要手动调权重对数量级的差异也不敏感而且实现非常容易。我在项目里通常会先搭一个最简版本向量检索Top20 关键词检索Top20再用RRF融合成Top5作为最终送入大模型的上下文。注意这里有一个容易忽略的工程点混合检索里的“关键词检索”在中文场景下必须做分词处理。如果你用的是一个分词效果不好的开源工具很多专有名词会被切碎那关键词检索这条通道基本就废了。实测下来在中文业务文档场景我通常会把分词词典和停用词表提前人工维护一版把产品名称、型号、部门名称都加进去检索质量的提升立竿见影。再补充一个关于“重排序”Re-ranking的观点。在预算允许的情况下可以加一个专门的Cross-Encoder重排序模型把混合检索拿到的Top20压缩到Top5。Cross-Encoder会把查询和文档拼接成一对让模型直接判断相关性比Embedding那种Bi-Encoder的方式更准。但代价是慢所以它一般只用在精排阶段而不是召回阶段。这个阶段如果你不想引入额外模型也可以推迟到后面优化时再加不影响先把系统跑通。3.4 Prompt管理从“写得好”到“改得稳”在AI工程里Prompt不是一个文本框而是一个需要版本管理和评测追踪的代码资产。我在这个项目里最强调的一件事就是永远不要把Prompt直接写死在代码里。为什么呢因为Prompt的迭代速度远超代码的迭代速度。你可能今天用了一个三段式结构写了Few-shot示例明天业务方反馈说某个情绪场景回复太生硬你改了一版后天又发现改了这一版之后另外一类问题又变差了。如果没有版本管理你根本没法回溯“上周效果比较好”到底是哪一版Prompt、哪个模型参数组合产生的。我建议的实践是把Prompt模板单独放到一个目录比如prompts/文件夹每一版都带上版本号、变更说明和评测记录。在代码里引用模板时用明确的变量名去加载而不是零零散散地在字符串里拼。这听起来像是常识但实际去看很多工程代码你都会发现Prompt被藏在十几个不同的函数里改了都不知道会影响谁。Prompt的结构设计方面我个人的心得是“角色任务约束输入示例”这个经典框架依然好用但更重要的是学会给模型加“防胡说护栏”。比如我经常会在Prompt里显式加一条“如果你不知道答案请直接告诉用户你无法从已有资料中得出答案不要捏造。”模型对这个约束的遵循程度因模型而异但加了之后严重幻觉的出现频率确实会降低。此外我会把“输出格式”用JSON或Markdown模板锁死方便后面做结构化解析这比让模型自由发挥再正则匹配省心一万倍。3.5 评估与回归没有“评测集”的优化都是自欺欺人这个项目的核心环节之一就是建设一个“最小可行评测集”。什么叫“最小可行”它不是要求你搞一套完整的标注体系而是需要你整理出50到100对“用户问题-标准答案/核心要点”。这些问题的来源可以是真实用户反馈、业务方的常见咨询、你自己假设的高风险场景。有了评测集之后你才能回答一个关键问题“我改了这个Prompt、换了这个切分参数到底变好了还是变坏了”如果没有评测集你所有的优化动作都会变成“感觉”“好像”“可能是”。这在项目演示阶段无所谓但一旦到了生产环境那种感觉流优化会让你的系统陷入无休止的回归。实操上我会把评测跑成两个层次。第一层是“自动评测”用脚本把评测集里的所有问题都跑一遍调用大模型对回答做打分注意这里用另一个模型打分的话要小心偏差并与前一版本对比。第二层是“人工抽检”自动评测只能发现明显的变差和变好真正的用户体感还需要人来看。每周固定抽20条看回答是否准确、是否贴合业务语境、是否还有格式问题。这块内容在项目里建议至少留出10到20个小时的完整时间因为评测集的建设本身就是一个迭代过程——你一开始想的问题不一定覆盖真实场景跑着跑着就会发现原来用户问的方式跟你想象的不一样。这时候就需要往评测集里补“坏例子”。请注意把坏例子加进评测集这件事比追求单次准确率提升要有价值得多因为它防止你未来重蹈覆辙。4. 实操过程与核心环节实现从空目录到一个能聊知识库的完整路径4.1 环境与工具选型别在第一步被库依赖劝退如果你跟着这个项目一路做下来环境搭建一定是第一道关卡。我的建议是在做任何代码之前先确认三件事Python版本号建议3.10以上、依赖管理工具poetry或者uv都行别再用pip加requirements.txt裸奔、是否为本项目建立一个专用虚拟环境。工具选型方面我把自己实际在用的方案列成一个表你可以当作参考起点不用视为唯一标准环节工具选型推荐选型理由语言Python 3.10生态最成熟几乎覆盖所有AI库依赖管理uv 或 poetry锁文件可复现避免依赖升级踩雷数据库/向量存储SQLite sqlite-vec起步Qdrant或Milvus后期起步简单后期可平滑迁移文档加载LangChain文档加载器 / Unstructured支持常见格式接口统一文本切分LangChain RecursiveCharacterTextSplitter按结构切分兼顾语义完整Embedding开源BGE系列或API接入中文效果好成本可控框架LangChain可选或纯手写手写利于理解LangChain提速大模型APIOpenAI兼容接口可统一封装换供应商只需改BaseURL这里有一个特别容易踩的坑不要把LangChain当成“万能胶水”一上来就引入全家桶。LangChain的抽象层确实能帮你把组件快速串起来但当你需要细粒度控制时它的“魔法”反而变成了包袱。我的建议是项目的前半段尽量手写核心链路把每个环节的输入输出手工打出来亲眼看到数据流的形状后半段再决定是否引入框架封装薄弱环节。在实际操作“from scratch”的动手环节里我强烈建议你先别急着看任何高级框架的文档。给自己半小时写一个最原始的“读PDF-按段落切分-调用API向量化-存入列表-遍历相似度-拼上下文-调LLM”的demo。这段代码可能丑陋得要命但它会给你带来一种无可替代的直觉——你会亲眼看到“一条上下文从哪来、怎么拼、模型怎么吃进去”。这种感觉是任何框架教程都给不了你的。在这之后再引入工具和框架来优化体验你会有一种“我在指挥工具”而不是“被工具指挥”的状态。4.2 数据准备脏数据比模型差更致命项目做实操时很多人会拿一两个干净教程文档做实验效果奇好于是欢欣鼓舞地部署到真实环境然后被打脸。问题不在模型而在数据。真实业务文档的脏乱程度往往超出你想象中文PDF里有全角半角混排扫描件转出来的文本有大量乱码表格数据在解析之后变成了一堆没有语义的碎片。所以“数据处理”这个环节在实操中我会花上大量精力。不要小看这个过程。我见过太多项目模型选型没变、Prompt没变仅仅把数据清洗流程做了优化效果就提升了一个量级。一个比较可靠的数据处理流水线是格式识别PDF/Word/Markdown- 文档解析保留层级结构- 清洗去页眉页脚、去乱码、修正全半角- 结构归一把标题、段落、列表、表格标记成不同结构- 元数据打标来源文档名、章节标题、页码、日期等- 切分 - 向量化。这里的“元数据打标”特别值得多说一句。你在把文本切分成块之后这些块会失去它们在原文档中的位置感。如果没有元数据检索到某个块之后你无法告诉用户“这个答案来自哪份文档、哪个章节”这对企业知识库场景几乎是不可接受的。而且元数据还能帮你做过滤——比如按业务线过滤、按时间范围过滤这在多文档混合检索时特别有用。在实操中我还会做一件事对清洗后的文本做一轮“人工抽读”。从每个文档类型里抽查两三个段落看看排在最前面的检索结果是否真的能对应上语义。这一步看似笨拙却能提前暴露出大量问题比如某些文档的解析结果存在严重乱码或者某些文档的标题层级被拍平了导致检索到的块缺失了必要的上下文。这些问题如果你不打数据抽取环节就发现不了等着跑完整条链路再去排查成本会高很多。4.3 核心链路实现手写一个最小的RAG闭环下面我给出一个经过简化但仍然能完整跑通的核心链路实现思路。我会用伪代码的方式展示你可以根据自己的项目场景替换细节。注意这段代码不是为了炫技而是为了让你看清“每一步的输入和输出到底是什么”。# 伪代码示例最小RAG闭环 import os from typing import List # 1. 文档加载与文本抽取 def load_document(path: str) - str: 读取PDF/Word/Markdown返回纯文本。注意处理扫描件与乱码。 # 这里替换为你的文档解析工具 return extract_text(path) # 2. 结构化切分 def split_document(text: str, chunk_size: int 500, overlap: int 100) - List[dict]: 按段落/标题/句子递归切分返回块列表 每个块包含text, metadata(来源, 标题, 页码) chunks recursive_character_split(text, chunk_size, overlap) return chunks # 3. 向量化 def embed_texts(texts: List[str]) - List[List[float]]: 调用Embedding模型把文本列表转为向量列表。 return embedding_model.encode(texts).tolist() # 4. 存储 def store_chunks(chunks: List[dict], embeddings: List[List[float]]) - None: 把块和向量写入向量存储元数据一并保存。 for chunk, emb in zip(chunks, embeddings): vector_store.insert(chunk[text], emb, chunk[metadata]) # 5. 检索混合检索示例 def retrieve(query: str, top_k: int 5) - List[dict]: # 向量检索 query_emb embed_texts([query])[0] vector_results vector_store.search(query_emb, top_k20) # 关键词检索 keyword_results keyword_index.search(query, top_k20) # RRF融合 fused reciprocal_rank_fusion(vector_results, keyword_results, top_ktop_k) return fused # 6. 生成 def generate_answer(query: str, retrieved_chunks: List[dict]) - str: context \n\n.join([c[text] for c in retrieved_chunks]) prompt build_prompt(query, context) # 从prompt模板读取 return llm_call(prompt)这段流程里最容易出问题的地方有三个。第一切分后的块必须带着元数据否则检索结果没办法溯源。第二查出来的块在拼入Prompt时要按原文档顺序排列而不是按相似度排序排列。因为大模型在阅读上下文时如果内容东一句西一句很容易产生错误的逻辑关联。第三检索结果要设置一个“最低相关度阈值”如果所有结果的相关度都过低就不要强行送进Prompt直接让模型回答“资料库里没有相关信息”这比硬编一个答案安全得多。关于Prompt模板我通常会用{context}和{question}这种占位符然后在调用前用format_map安全填充避免用户输入里的大括号把模板搞炸。这个小细节我在真实项目中遇到过好几次值得留意。4.4 生产化增强从“能回答”到“答得好、答得稳、答得便宜”跑通了上面的闭环你只能算完成了Demo。接下来这个项目就进入最考验工程能力的阶段生产化增强。我给你拆四个方向。第一个方向是“增加引用溯源”。让大模型在回答的时候输出它依据的是哪些检索块并把块对应的来源和页码展示给用户。这个功能不是锦上添花而是建立信任的必需品。实现方式通常是在Prompt里要求回答格式包含[citation:1]之类的标记然后在后处理中把这些标记映射到元数据上。这里有一个体验优化技巧如果发现检索出的前三个块与回答完全无关宁愿把引用去掉也不要硬挂免得用户点开发现文不对题反而更伤信任。第二个方向是“对话记忆”。在真实使用中用户很少只问一个问题。但如果你把所有历史对话都塞进上下文不仅浪费token而且会让模型分心。我的建议是维护一个滑动窗口式的对话摘要每次把最近的几轮对话摘要当前问题送进Prompt。对话摘要可以用一个轻量模型来生成也可以简单地截取后几轮。注意摘要的丢失会让系统回答看似更“聪明”因为它跳过了很多陈旧上下文反而更能聚焦在当前问题上这是我在一批客服机器人项目里体会很深的一点。第三个方向是“成本优化”。大模型的成本主要来自输入token数。你每次把一堆检索块拼进Prompt输入token数会飞速上涨。降低成本的思路有几个一是尽量用小模型做召回、用大模型做生成把职责拆开二是对高频问题做一个基于缓存的命中层如果检索到的上下文组合与历史请求高度相似就直接复用上次的回答不再调用大模型三是对回答做流式输出让用户感觉“更快”同时也能在streaming过程中及时中断无效生成节省成本。这三个方向在这个项目里都建议实际做一遍因为只有动过手你才会对“token不是免费午餐”这句话有切身体会。第四个方向是“评估与回归”这部分我在前面已经讲得比较多了。这里只补充一个实操建议把评测集跑进CI。每当你改了一版Prompt或换了一个Embedding模型自动跑一遍评测集把评分和关键Bad Case输出到日志里。这样你就能在代码提交之前快速判断这次改动是正向还是负向。不要嫌它麻烦这一定是未来你花时间最值的部分。5. 常见问题与排查技巧实录从“怎么跑不通”到“为什么效果差”5.1 环境与依赖问题的快速排查清单在这个项目从零到一的过程中我几乎可以肯定你会遇到下面这些环境问题。我把它们整理成一张速查表方便你出问题的时候直接对着查。场景常见表现排查思路向量数据库连接失败启动即报错或超时检查端口、容器状态、鉴权Token看看是不是本机开了防火墙Embedding模型下载卡住程序长时间无响应检查网络代理配置考虑换国内镜像模型源API Key报错401 / 403确认环境变量名拼写、是否有隐藏换行符token超限输入输出长度超过上下窗口检查检索块是否过大、是否把历史全塞进去了考虑压缩上下文中文乱码检索结果文本不可读检查PDF解析器与编码在清洗环节统一转UTF-8慢得离谱单次问答耗时超过10秒看看是不是检索环节没有建索引有没有对向量数据库全表扫描5.2 效果不佳时的排查顺序如果你做好了环境搭建但发现真实问答效果很差千万不要第一反应就“换更大的模型”。我总结了一个固定排查顺序经过多个项目验证效率很高。先查检索召回。怎么查把检索出来的Top块直接打印出来看那几块文本是否真的回答了用户问题。如果检索结果压根不对生成再强的模型也是“巧妇难为无米之炊”。这一步是最多项目翻车的地方。然后查Prompt。看看你给模型的“指令”是不是足够清晰有没有加“不要乱编”的护栏有没有给输出格式范例。接着查上下文拼装。看看你送入Prompt的检索块顺序和内容是否有冗余、是否有冲突信息。最后才是查模型能力。注意这个顺序的底层逻辑问题的源头往往越靠前、越便宜就越容易被修复。你换一个更强的模型可能确实能把“检索到了但没回答好”的问题盖住但它掩盖的是检索链路的浅层问题后续成本会越来越高。这就像你家里的水管漏水你换个压力更大的泵确实能让出水快一点但漏的洞还在那儿迟早要出大事。这里分享一个我自己的“Bad Case日志法”。每次遇到效果不佳的情况不要只记录“回答错了”而是把以下五条信息记录下来用户问题原文、检索召回的Top5块ID、每个块的得分、最终生成的回答、人工分析结论。这种日志积累到50条以后你会对自己系统的弱点一目了然——是切分粒度问题、检索偏向问题还是Prompt约束问题。这种数据驱动式的优化比凭感觉调参要靠谱得多。5.3 关于“幻觉”问题的实操心得幻觉问题模型编造不存在的内容是AI工程里最受关注的痛点之一。我个人的态度是不要指望从模型层面彻底消灭幻觉而是要“结构化地降低幻觉带来的损害”。第一个手段是“约束生成”。在Prompt里要求模型尽量基于上下文回答并且要求它在无法确定答案时明确说“资料未提及”。第二个手段是“引用溯源”这部分我在前面已经说过了。第三个手段是“后置校验”。如果你的业务场景是固定格式输出比如工单分类、保险理赔初判可以在模型生成结果之后用规则或小模型校验关键字段是否合法。例如模型说“根据发票编号XX..”你就可以用正则去校验那个编号是否存在于检索到的知识库里。如果不存在宁可让系统反馈一个“存疑”也不要直接输出给用户。这里还有一个小技巧在回答的结尾可以加一句“以上内容仅为基于现有资料的分析具体以官方信息为准”这样的免责声明模板。不要小看这句话在真实业务场景里它至少可以减少大量因回答不准确而引发的用户投诉。这也是我在实际交付AI客服项目时几乎必定要求业务方接受的一个设计。5.4 成本爆炸预警你以为便宜其实贵得吓人很多人在做Demo时数据集小、请求量少感觉API调用费可以忽略不计。但一旦上线你会发现成本增长的曲线比你想象中陡峭得多。我给你算一笔很粗略的账假设你的系统一天处理1万次请求每次请求平均消耗3000个输入token500个输出token按中等价位的大模型API计算一个月的费用可能在数千到上万元。如果每个请求再叠加一些低效的Retry逻辑、无谓的历史对话记录、过大的检索块费用轻松再翻倍。所以在这个项目里我建议至少要做一个“Token使用量的可视化面板”。不需要很复杂在每次调用的日志里记录输入Token数、输出Token数、命中缓存与否、请求耗时、成本估算。这五个字段积累一个月你就能非常清楚地看到钱花在哪里进而有依据地做优化。很多团队不是没钱而是不知道钱是怎么烧掉的这才是最可怕的。有了这个面板之后你可以尝试“缓存复用”策略如果在一个小时内某个用户问了另一个用户完全相同的问题而且检索到的上下文组合也一致就直接复用之前的回答。这个方法在客服类场景里往往能省下20%到40%的成本而且回答质量是稳定的因为它不是随机生成而是经过了一次验证的答案。注意这里需要小心用户的隐私和授权问题不要在跨用户共享缓存时泄露敏感信息。如果你做的是企业内部系统这套缓存大概率是可行的如果是外部To C场景务必做好数据隔离。最后分享一点我在实际项目里的感受这个项目最打动我的地方在于它逼着你放弃“点一点就能用”的幻想回到工程的本源数据、流程、评测、迭代。我在真实交付过几个AI应用之后最大的体会是AI工程的瓶颈往往不在模型能力而在系统设计能力。一个靠谱的AI工程师本质上是一个懂得给能力做减法、给系统做加法的人——他知道什么环节应该依赖模型什么环节应该用规则兜底什么环节必须人工介入。所以如果你正在走“from scratch”这条路请不要急着追求“我能不能立刻做出一个爆款应用”。先花两周时间把手写的RAG链路跑通把脏数据处理干净把评测集积累到100条把成本面板搭起来。这个过程可能有点枯燥但等你走完这一步你会发现市面上绝大多数AI应用的技术方案在你眼里已经没有任何神秘感了。这个项目的最终目的其实不是让你“学会某个技术栈”而是让你获得一种掌控感——在AI技术快速迭代的当下你不再是被潮流推着走的人而是能判断潮流走向的人。
返回列表