ARTICLE DETAIL

资讯详情

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

从零搭建AI工程能力:先跑通再深挖的实战学习路径

从零搭建AI工程能力:先跑通再深挖的实战学习路径 1. 从零搭建AI工程能力为什么我劝你别一上来就啃论文这两年AI岗位的需求量涨得离谱打开任何一个招聘平台搜“AI工程师”出来的岗位描述里十有八九写着“熟悉大模型原理”“有RAG落地经验”“掌握LangChain/LlamaIndex”这类要求。很多人一看就慌了转头去买一堆《深度学习》砖头书或者从Transformer论文原文开始硬啃结果啃了两个月连一个能跑起来的问答机器人都没做出来。我特别理解这种焦虑。我自己当年也是这么过来的——先啃理论再想动手结果理论没啃透动手能力也没练出来两头空。后来我才想明白一件事AI工程和AI研究是两条完全不同的路。研究是搞清楚“为什么这样设计有效”工程是搞清楚“怎么把已有的东西拼起来解决实际问题”。你不需要自己推导反向传播就像你不需要自己造一台发动机才能开车。“ai-engineering-from-scratch”这个方向核心就是解决这个错位问题。它面向的是那些想进入AI工程领域、但被传统学习路径劝退的人。不管你是后端转行、前端想拓展、还是刚毕业的计算机学生只要你会写基本的Python能看懂API文档就可以从零开始搭建一套完整的AI工程能力栈。这篇文章我会把整个学习路径、每个阶段的核心技术点、实操中踩过的坑以及可以直接抄作业的代码方案全部摊开讲清楚。2. 整体学习路径设计先跑通再深挖别反过来2.1 为什么“自底向上”的学习方式在AI工程里行不通传统计算机科学的教育路径是自底向上的先学数字电路再学计算机组成原理然后操作系统、编译原理最后才是应用层。这套路径对打基础确实有效但放到AI工程领域问题就大了。AI工程的技术栈迭代速度极快。你今天花三个月啃完的某个框架源码下个月可能就被新版本重构了。更关键的是AI工程的核心能力不是“理解某个算法的数学推导”而是“在不确定的环境下快速搭建可用的系统”。这两种能力需要的训练方式完全不同。我试过带过几个新人一开始就让他们读Attention Is All You Need那篇论文结果一周后他们连PyTorch的DataLoader怎么用都还不熟。后来我换了策略先让他们用现成的API做一个能对话的机器人哪怕底层原理一知半解先跑通再说。结果三天就能出demo两周后他们自己就开始主动去查注意力机制的细节了——因为他们在调参时遇到了实际问题有了“想知道为什么”的驱动力。注意这不是说理论不重要而是说学习的顺序应该是“先用起来再搞明白”。有了实际体感之后再去补理论效率至少翻倍。2.2 三阶段能力模型调用者、构建者、优化者我把AI工程能力分成三个阶段每个阶段的目标和产出物都不一样阶段核心能力典型产出建议耗时调用者调用API、写Prompt、处理返回结果能对话的机器人、文本分类工具2-4周构建者搭建RAG系统、微调小模型、设计Agent流程知识库问答系统、自动化工作流4-8周优化者性能调优、成本控制、效果评估与迭代生产级AI应用、评估Pipeline持续进行大部分人的问题在于他们想直接从“调用者”跳到“优化者”跳过了“构建者”阶段。结果就是demo能跑但一上生产就崩。我见过太多团队花大价钱调了模型结果发现瓶颈根本不在模型而在数据清洗和检索策略上。2.3 工具选型别追新追稳AI领域的工具更新速度堪比时装周今天LangChain明天LlamaIndex后天又冒出个新框架。我的建议是在“调用者”阶段只用最基础的库。具体来说Python环境下你只需要这几样东西openai或anthropic的官方SDK用于调用大模型APIrequests或httpx用于调用其他HTTP接口python-dotenv管理API密钥streamlit或gradio快速搭界面就这些。不要一上来就上LangChain那玩意儿抽象层太多出了问题你根本不知道是哪里卡住了。等你手写RAG流程写到第三遍觉得“每次都要重复写这些代码好烦”的时候再去用框架那时候你才能真正理解框架帮你解决了什么问题。3. 核心细节解析从调用API到搭建RAG的完整技术栈3.1 大模型API调用的五个关键参数很多人调API就是复制粘贴官方示例改个prompt就完事。但实际工程中有几个参数直接决定了你的应用能不能用temperature控制输出的随机性。做事实性问答时设0.1-0.3做创意写作时设0.7-0.9。我见过有人做客服机器人设了0.8结果同一个问题每次回答都不一样客户直接投诉。max_tokens限制输出长度。这个参数不设的话有些API会默认给一个很大的值导致你的账单爆炸。建议根据实际场景设置比如客服回复一般200-300 tokens足够。top_p和temperature配合使用控制采样范围。一般设0.9-0.95不需要频繁调整。frequency_penalty和presence_penalty控制重复内容。做长文本生成时特别有用能避免模型反复说同一句话。stop停止序列。这个参数很多人忽略但在结构化输出时极其重要。比如你让模型输出JSON可以设stop为\n\n防止它输出多余的解释文字。import os from openai import OpenAI from dotenv import load_dotenv load_dotenv() client OpenAI(api_keyos.getenv(OPENAI_API_KEY)) def ask_llm(prompt, system_prompt你是一个专业的AI助手): response client.chat.completions.create( modelgpt-4o-mini, messages[ {role: system, content: system_prompt}, {role: user, content: prompt} ], temperature0.3, max_tokens500, top_p0.9, frequency_penalty0.3, presence_penalty0.3 ) return response.choices[0].message.content这段代码看起来简单但每个参数都是我踩过坑之后调出来的。temperature0.3是保证回答稳定性的底线max_tokens500是防止意外长输出frequency_penalty和presence_penalty各设0.3是避免重复又不至于让语句变得不自然。3.2 Prompt工程的三个层次从能用到好用Prompt工程不是玄学它有明确的层次结构第一层指令清晰。这是最基本的要求。不要说“帮我写个东西”要说“帮我写一封给客户的道歉邮件原因是发货延迟了三天语气要诚恳但不卑躬屈膝控制在200字以内”。指令越具体输出越可控。第二层格式约束。如果你需要结构化输出必须在prompt里明确格式。比如“请以JSON格式输出包含以下字段name, age, occupation”。最好再给一个示例这叫few-shot prompting。第三层思维链引导。对于复杂推理任务让模型“一步一步思考”能显著提升准确率。具体做法是在prompt末尾加一句“让我们一步一步来分析”或者给一个推理过程的示例。我实测下来对于分类任务few-shot prompting比zero-shot的准确率能高出15-20个百分点。对于数学推理思维链引导的效果更明显有时候能从50%正确率直接拉到80%以上。3.3 RAG系统的核心组件与常见陷阱RAG检索增强生成是目前AI工程落地最广泛的技术方案。它的核心思路很简单用户提问 → 从知识库检索相关内容 → 把检索结果和问题一起交给大模型 → 生成回答。但简单归简单坑一点都不少。我按组件拆开讲文档加载与切分这是最容易被低估的环节。很多人直接把整个PDF丢进去切结果切出来的chunk要么太大包含无关信息要么太小丢失上下文。我的经验是中文文本按500-800字切分英文按300-500词切分同时设置10-15%的重叠区域。对于结构化文档如Markdown按标题层级切分效果更好。向量化与存储embedding模型的选择直接影响检索质量。OpenAI的text-embedding-3-small性价比最高中文场景下BGE-M3效果不错。存储用FAISS或Chroma都行数据量小于10万条时两者性能差异不大。检索策略纯向量检索在遇到专有名词时经常翻车。比如用户问“XX-2000型号的参数”向量检索可能返回一堆不相关的内容。这时候需要混合检索向量检索关键词检索BM25然后用RRF算法融合结果。重排序检索回来的top-10结果里真正相关的可能只有3-4条。用一个小的cross-encoder模型做重排序能显著提升最终效果。我常用的是BGE-reranker-base速度快效果也不错。from langchain.text_splitter import RecursiveCharacterTextSplitter from langchain_community.vectorstores import FAISS from langchain_openai import OpenAIEmbeddings # 文档切分 text_splitter RecursiveCharacterTextSplitter( chunk_size600, chunk_overlap100, separators[\n\n, \n, 。, , , , , , ] ) chunks text_splitter.split_text(raw_text) # 向量化存储 embeddings OpenAIEmbeddings(modeltext-embedding-3-small) vectorstore FAISS.from_texts(chunks, embeddings) # 检索 retriever vectorstore.as_retriever( search_typesimilarity, search_kwargs{k: 5} )这段代码里separators的顺序很关键。中文文本必须把中文标点放在前面否则切分出来的chunk会在句子中间断开严重影响检索质量。这个细节官方文档里不会写是我切了上千个文档之后总结出来的。4. 实操过程从零搭建一个可用的知识库问答系统4.1 环境准备与依赖安装先把环境搭起来。我推荐用conda创建独立环境避免和系统Python冲突conda create -n ai-eng python3.11 conda activate ai-eng pip install openai langchain langchain-community langchain-openai faiss-cpu streamlit python-dotenv pypdf这里解释一下每个包的作用openai用于调用GPT接口langchain系列用于文档处理和检索faiss-cpu是向量数据库streamlit用来快速搭界面pypdf用于读取PDF文档。提示faiss-cpu在Windows上安装有时会报错如果遇到问题可以换成chromadbAPI基本兼容。4.2 文档处理Pipeline的完整实现假设你有一堆PDF格式的产品手册需要做成问答系统。完整的处理流程如下第一步加载PDF并提取文本。用pypdf逐页读取注意有些PDF是扫描件需要OCR处理这里先假设是文本型PDF。第二步清洗文本。去掉页眉页脚、页码、多余的空格和换行。这一步看起来简单但不做的话检索质量会差很多。第三步切分chunk。用上面提到的RecursiveCharacterTextSplitterchunk_size600overlap100。第四步生成embedding并存入向量库。批量调用embedding接口注意控制并发数一般5-10个并发比较稳。第五步构建检索QA链。用户提问 → 检索top-5相关chunk → 拼接成context → 交给LLM生成回答。from pypdf import PdfReader import re def load_and_clean_pdf(file_path): reader PdfReader(file_path) full_text for page in reader.pages: text page.extract_text() # 去掉页码和页眉页脚 text re.sub(r\n\d\n, \n, text) text re.sub(r\s, , text) full_text text \n return full_text def build_qa_chain(vectorstore, llm_client): def qa(question): docs vectorstore.similarity_search(question, k5) context \n\n.join([doc.page_content for doc in docs]) prompt f基于以下参考资料回答问题。如果资料中没有相关信息请直接说根据现有资料无法回答。 参考资料 {context} 问题{question} 回答 response llm_client.chat.completions.create( modelgpt-4o-mini, messages[{role: user, content: prompt}], temperature0.1, max_tokens800 ) return response.choices[0].message.content return qa这个QA链里有两个关键设计一是明确告诉模型“资料中没有就说无法回答”避免幻觉二是temperature设0.1保证回答的稳定性。4.3 用Streamlit搭一个能用的界面界面不需要花哨能上传文档、能提问、能显示回答就行import streamlit as st st.title(知识库问答系统) uploaded_file st.file_uploader(上传PDF文档, typepdf) if uploaded_file: with st.spinner(正在处理文档...): text load_and_clean_pdf(uploaded_file) chunks text_splitter.split_text(text) vectorstore FAISS.from_texts(chunks, embeddings) st.success(f文档处理完成共{len(chunks)}个片段) question st.text_input(输入你的问题) if question and uploaded_file: with st.spinner(正在检索...): answer qa(question) st.markdown(f**回答** {answer})这套代码加起来不到100行但已经是一个可用的知识库问答系统了。我拿它处理过200页的产品手册检索准确率在80%以上对于内部工具来说完全够用。4.4 效果评估怎么知道你的系统好不好用很多人做完系统就完事了从来不评估。这是大忌。没有评估你根本不知道优化有没有效果。最简单的评估方法是人工构造测试集从文档里挑20-30个问题手动写出标准答案然后让系统回答对比准确率。虽然土但有效。进阶一点可以用RAGAS框架它能自动评估faithfulness回答是否忠于检索内容、answer_relevancy回答是否切题、context_precision检索内容是否精准等指标。我自己的习惯是每次调整chunk_size、检索数量、prompt模板之后都跑一遍测试集记录准确率变化。这样你才能知道哪个参数真正有用。5. 常见问题与排查技巧实录5.1 检索不到相关内容怎么办这是RAG系统最常见的问题。排查思路按以下顺序来先看chunk切分是否合理。把检索到的chunk打印出来看看是不是在句子中间断开了。如果是调整separators顺序把中文标点提前。再看embedding模型是否适合中文。text-embedding-3-small对中文的支持还行但如果你的文档有大量专业术语建议换成BGE-M3或者m3e-base。然后看检索数量。k5可能不够试试k10然后加重排序。我遇到过一个问题正确答案在top-15里但top-5里没有加了重排序之后就解决了。最后看query本身。用户的提问方式可能和文档表述差异很大。这时候可以加一个query改写步骤让LLM先把用户问题改写成更适合检索的形式。5.2 模型回答出现幻觉怎么处理幻觉的根源是模型在“编造”而不是“引用”。解决方法有三个层次Prompt层面明确要求“只基于参考资料回答”并给出无法回答时的标准话术。检索层面提高检索精度确保交给模型的context里确实包含答案。如果context里没有答案模型编造的概率会大幅上升。后处理层面让模型在回答时标注引用来源比如“根据文档第3页...”。这样即使有幻觉用户也能快速判断。我实测下来prompt层面能解决60%的幻觉问题检索层面能解决30%剩下10%需要后处理兜底。5.3 响应速度太慢怎么优化AI应用的响应速度直接影响用户体验。优化手段按性价比排序优化手段效果实施难度成本影响换更小的模型显著低降低减少检索数量中等低降低流式输出感知提升大低无缓存常见问题显著中降低并行调用中等中不变流式输出是最容易做的优化用户看到文字一个个蹦出来感知等待时间能减少一半以上。缓存的话对于FAQ类场景特别有效命中率能到40%以上。5.4 常见问题速查表问题现象可能原因排查方法解决方案检索结果不相关chunk切分不合理打印chunk内容调整separators和chunk_size回答包含幻觉context缺少答案检查检索结果提高检索精度或增加k值响应时间超过10秒模型太大或检索太慢分段计时换小模型、减少k值、加缓存中文回答质量差embedding模型不适合对比不同模型换BGE-M3或m3e-baseAPI调用频繁报错并发太高或超时查看错误码降低并发、增加重试机制长文档处理慢串行处理检查处理逻辑批量并行处理6. 进阶方向从能用走向好用6.1 Agent工作流的设计思路当你把RAG跑通之后下一步自然是让系统能“做事”而不只是“回答”。这就是Agent的概念。Agent的核心是让LLM能够调用工具查数据库、发邮件、调API、执行代码。设计Agent工作流时最关键的是工具描述要清晰。LLM根据工具的名称和描述来决定调用哪个工具如果描述模糊它就会乱调。比如一个“查询天气”的工具描述要写成“根据城市名称查询当前天气状况输入参数为城市名返回温度和天气描述”而不是简单的“查天气”。另一个关键是错误处理。Agent调用工具失败时要能让LLM知道失败了并决定是重试还是换一种方式。这需要在工具返回值里包含明确的错误信息。6.2 微调小模型的适用场景不是所有场景都需要微调。我的判断标准是如果你的任务用prompt engineering能做到80分就不要微调。微调的成本包括数据标注、训练资源、部署维护加起来远超你的预期。微调真正适用的场景是任务非常垂直比如法律文书分类、对延迟要求极高不能调API、或者数据隐私要求不能出本地。这时候微调一个7B参数的小模型效果可能比GPT-4还好。6.3 成本控制的五个实用技巧AI应用的成本大头在API调用。控制成本的手段包括用更小的模型处理简单任务、缓存常见问题的回答、压缩prompt长度、批量处理请求、设置预算告警。我见过一个团队光是优化prompt长度这一项每月就省了40%的API费用。7. 我踩过的坑与实操心得第一个坑是过度依赖框架。刚开始用LangChain的时候觉得什么都能做结果一个简单的检索问题排查了三天最后发现是框架内部的一个默认参数导致的。后来我养成了一个习惯核心逻辑自己写框架只用来做辅助。第二个坑是忽略数据质量。我做过一个项目花了两周调模型参数效果一直上不去。后来把训练数据拿出来一看30%的标注是错的。数据清洗花了一天效果直接提升了20个百分点。这件事让我明白在AI工程里数据质量比模型选择重要十倍。第三个坑是不做评估就上线。我曾经把一个问答系统直接部署给内部同事用结果第一天就收到一堆投诉。后来补了评估流程发现检索准确率只有60%。如果上线前跑一遍测试集这些问题完全可以在内部解决。最后一个心得是保持简单。AI领域的新概念层出不穷但真正能落地的方案往往是最简单的。一个清晰的prompt、一个合理的检索策略、一个稳定的API调用比一堆花哨的框架组合起来管用得多。我现在的习惯是每引入一个新工具或新框架之前先问自己不用它我能不能做如果能就不用。
返回列表