拓十年匠心定制 · 商业建站与技术教学双线并行 咨询热线:400-886-1026 service@lmnt.cn
ARTICLE DETAIL

资讯详情

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

AI工程学习路线:从RAG到Agent的实战指南

AI工程学习路线:从RAG到Agent的实战指南

最近在技术社区里被问到最多的问题就是:AI工程到底怎么学?大家搜出来的路线往往是“先学Python,再啃PyTorch,然后从Transformer原理开始”,这套路径不能说错,但它更像算法研究员的成长路线。真正做AI工程的人,日常打交道的是RAG流水线、Agent工具调用、评估集设计、上下文截断、接口延迟和token账单,这些内容在传统机器学习教程里几乎找不到系统化的整理。我花了大半年时间把从零进入AI工程的经验沉淀成了自己的项目,取了个名字就叫ai-engineering-from-scratch,这篇博文就是把项目背后的路线、选型和踩坑一并拆开来讲。

这篇文章适合两类人:一类是想从后端、前端转过来的软件工程师,另一类是被“算法”两个字劝退、但对AI应用开发有强烈兴趣的同学。我不会聊模型训练细节,也不会推损失函数公式,重点是工程化思维、可复现的实操步骤,以及怎么把一个带RAG和工具调用的系统真正跑起来。

1. AI工程不是“算法岗换皮”:它在解决完全不同的问题

1.1 和传统机器学习工程的区别在哪

很多想入行的人问我的第一句话是:“做AI工程是不是得先把机器学习基础打好?”这个问题的前提就已经错了。传统机器学习工程的工作链路是:收集数据、做特征工程、选模型、训练、调参、评估指标、部署上线,最后交付的“成果”是一个推理模型。而AI工程的工作链路是:基于现成的强大模型(GPT、Claude、Qwen、GLM这些),把它当作一个智力组件,去搭建一套能够完成实际任务的系统,最后交付的是一个“系统”。

这个区别带来的是完全不同的思维方式。做ML工程时,你担心的是模型AUC不够高、特征泄漏、过拟合;做AI工程时,你担心的是提示词在什么情况下会崩、检索回来的资料是否准确、工具调用失败了怎么办、这个功能跑一次要烧多少token。换句话说,ML工程是在“造一个更聪明的脑袋”,AI工程是在“给现有的聪明脑袋配上手脚、资料库和验收流程”。

我用一个比较接地气的类比:传统软件开发是写死流程,像给员工发一份非常详细的标准作业手册,每一步都写得明明白白;AI工程更像是给员工一个模糊的目标,他需要自己判断该查哪些资料、该调用哪些工具、该怎样组织回答,而你作为开发者的任务,是确保他手里的资料足够准确、工具足够顺手、干坏了有兜底方案。这个类比在做Agent设计时尤其重要。

1.2 AI工程师真正要会的东西

我把AI工程涉及的能力拆成了一张清单,方便你对照自己目前缺什么:

  • 模型接口调用与参数控制:HTTP调用、SDK使用、temperature/max_tokens/top_p的含义;
  • 结构化输出:JSON模式、函数调用(Function/Tool Calling)、输出校验;
  • 提示词工程:系统提示词设计、少样本示例、上下文管理;
  • 检索增强(RAG):文档解析、文本分块、向量化、召回排序、相关性判断;
  • Agent循环:ReAct模式、工具注册、多轮状态管理、失败重试;
  • 评估体系:评估集构建、自动断言、模型评分、回归测试;
  • 可观测性与成本控制:日志、追踪、token计量、缓存与限流。

这里面有哪一条需要你推公式?都没有。它更像后端工程和产品逻辑的结合体。听到“不用深入研究反向传播”的时候,很多人松了一口气,但我也要说实话:不推公式不代表不需要理解基本概念。你需要知道向量是什么、相似度怎么算、上下文窗口意味着什么,这些在后续使用embedding和设计提示词时都会直接碰到。理解到什么程度?会用、会调试就够,不需要能从零推导。

2. 从零开始的第一阶段:把心智模型从“训练模型”切换到“设计系统”

2.1 先建立一个正确的系统心智模型

动手写代码之前,我先建议你做一个思维转换。我记得自己刚开始学的时候,总把“调用一次大模型”当成“完成一个功能”,后来发现这个理解会处处碰壁。

单次调用不是系统,单次调用只是系统里的一个齿轮。真正的AI工程系统,至少要包含五个环节:

  1. 输入解析:把用户的原始需求转化成能被模型理解的结构化指令;
  2. 上下文构建:决定哪些资料、哪种背景信息应该被塞进这一次调用;
  3. 推理决策:模型基于上下文产出回答或决定调用工具;
  4. 执行动作:如果模型决定调用工具,系统去执行真实的API操作(查库、查订单、发消息);
  5. 结果校验:对模型输出做格式检查、内容验证,不合格就触发重试或降级。

这五个环节串起来,才叫一个AI应用。学AI工程最重要的,不是记住某个框架的API,而是把这五个环节的每个衔接点想明白:什么情况下会断,断了之后怎么接上。很多人上来就学LangChain,结果连“为什么一个Chain需要那么多步骤”“为什么Retriever的返回要重新加工”都搞不清楚,出了问题只能到处问。

2.2 前置知识到底需要多少数学

我可以直接给结论:不需要高深数学。需要掌握的是三个基本概念,每一个都是工程直觉层面就能理解的:

  • 向量与相似度:embedding把文本变成一串数字,检索本质上是算“哪两串数字长得最像”,你会用余弦相似度即可;
  • 概率与置信度:模型输出的是概率分布,所以同一个问题在不同次调用可能得到不同答案,这决定了你必须设计重试机制;
  • 统计思维:评估系统好坏不是看一两个用例,而是要准备一组有代表性的问题,综合计算通过率。

至于线性代数的严格推导、概率论的完备体系,这些可以等以后真的需要时再补。我更建议你把时间花在Python基础、HTTP与JSON接口调用这些“工程日常”上。说实话,我见过太多人在数学上原地打转,迟迟不敢动手调接口,结果浪费了整整一个月。

2.3 动手前先亲手调通一次API

理论说再多,都不如亲手调通一次接口来得实在。注册一个大模型平台的API,用Python发起第一次对话请求,把返回的JSON结构打印出来看一遍。

这一步的目的有三个:第一,破除“模型很神秘”的心理障碍;第二,亲眼看到请求参数和返回结构,后面做结构化输出才有直观载体;第三,体会token是怎么计算的——同一个接口,返回内容变长,账单数字也在变,这是你建立成本意识的第一步。

我强烈建议在这个阶段就把temperature、max_tokens、top_p这三个参数各玩一遍。把temperature调到0和调到1.5分别生成同一道题的回答,对比结果的稳定性和创造性,你就能直观理解“可控性”和“多样性”之间的张力。这一课比读十篇参数文档都管用。

3. 四阶段学习路线图:从结构化输出到一个能交付的Agent系统

3.1 阶段一:输出可控是地基

很多人学AI应用开发,第一个项目就做聊天机器人,这是我觉得最不推荐的方式。聊天机器人看起来简单,但它的评估太难了——怎么算答得好?怎么算答得差?对话长了之后上下文怎么管理?这些全是复杂问题。从工程训练的角度,我建议第一个目标小而明确:把用户的自然语言输入,转成一个结构化的JSON输出。

举个例子,写一个函数,输入“帮我订一张周五下午去杭州的火车票”,输出:

{ "intent": "book_train", "params": { "destination": "杭州", "time": "周五下午" } }

这个功能很小,但你要处理至少三个问题:怎么让模型稳定输出合法JSON、怎么处理模型偶尔输出无关文字的情况、怎么校验和兜底。这三个问题一旦解决,你就掌握了AI工程里最常用的一环——结构化输出,后续所有Agent和工具调用都建立在这一能力上。

我自己的体会是:模型返回“看起来合法、但字段值完全不对”的JSON,比返回乱码更危险。比如它把“杭州”解析成“hangzhou”,字段对但值错了,程序不会报错,结果却是错的。所以从第一个项目开始就必须引入校验层,这个习惯会一直伴随你。

3.2 阶段二:RAG让你的系统“有资料可用”

第二个阶段做检索增强生成。为什么需要RAG?因为模型训练完,知识就冻结在某个时间点了,而且它的训练语料不一定包含你的业务数据。RAG的思路很直白:先在外部建立知识库,用户提问时,把相关的资料片段检索出来,连同问题一起交给模型,让它“看着资料回答”。

最经典的入门项目是:把一个公司员工手册(或者任意一份Markdown文档)做成一个能回答问题的助手。看起来简单,实际做起来全是细节:

  • 分块策略:整篇塞进上下文不可能,切小了又会把完整语义切断;我试过200字、500字、1000字几种块大小,对同一个文档回答质量差别很大,需要测;
  • 重叠设计:相邻块之间重叠几十个字,能减少切断句子造成的召回遗漏;
  • Embedding选型:不同embedding模型对中文的支持差异很大,需要拿你的真实文档跑一圈对比;
  • 相关度阈值:低于多少分的检索结果不应该送给模型,这是防止幻觉的第一步;
  • 参考答案比对:同一个问题,直接问模型和“带资料回答”,质量差距肉眼可见,这个对比做一次就能理解RAG的价值。

这一步做完,你的系统开始有“知识”了,不再是一个纯凭记忆答题的模型。

3.3 阶段三:工具调用和Agent循环让系统“会做事”

第三阶段是很多AI工程学习者觉得“突然上了一个台阶”的地方:让你的系统不是光会说话,而是能动手操作外部系统。这本质上就是Function Calling,也叫Tool Use。

我推荐的入门项目是做一个能查天气和能搜索新闻的小助手。天气数据接一个公共接口,新闻搜索也接一个公共接口,然后把这两个能力“声明”给模型,模型在需要的时候会以结构化参数的形式发起调用请求,你的代码接收到请求后执行真实API操作,把结果回传给模型,模型再根据结果组织最终回答。

这个过程中最关键的是理解“Agent循环”:模型先判断“我现在需不需要工具”——如果需要,它不直接回答用户,而是输出一个工具调用指令——你的代码执行工具——把结果塞回给模型再看一轮——直到模型认为信息足够,才给用户最终答复。这个循环听起来简单,实际工程中有无数细节:最多允许循环几次、工具调用出错怎么重试、工具返回的结果太长怎么压缩、多工具时优先调用哪个。

3.4 阶段四:评估、观测、成本,决定你能否走得更远

前三阶段做完,你已经能做出一个“能跑”的AI系统了。但离“能交付”还很远。第四阶段是很多自学的人最容易漏掉的:评估体系和可观测性。

“能跑”和“能交付”之间,隔着一套评估基础设施。我建议你现在就动手做三件事:

  1. 沉淀一个评估集:至少准备30到50条覆盖典型场景的问题,标注标准答案或评分要点;
  2. 写一个自动化回归脚本:每次修改提示词或检索逻辑后,批量跑一遍评估集,统计通过率;
  3. 建立trace日志:记录每次请求的完整链路——输入了什么、检索到了什么、模型怎么决策的、调用工具花了多久、花了多少token、最终答了什么。

这三件事做完,你的开发节奏会完全改变。你不再依赖“感觉回答变好了”,而是依赖数据。我自己在带项目时经常说:AI工程的重点不是让模型“看起来聪明”,而是让你的改动结果可以被测量、被比较、被回滚。没有评估体系的AI项目,做得越久越容易变成一团乱麻。

4. 工具链选型:为什么我先劝你别碰重量级框架

4.1 模型服务怎么选:先跑通云端API,再谈私有化

第一选择永远是各大厂商的云端API。理由很简单:零部署成本,按量付费,你需要把精力放在应用逻辑而不是运维模型上。至于选哪家,说实话各家能力各有长短,但我建议初学者锁定一到两家主流的,把API调通了再横向对比。

什么时候需要考虑开源模型?两种情况:一是数据敏感,业务数据不能出域;二是调用量巨大,云端价格撑不住。这时候才去考虑Qwen、GLM这类开源模型的自部署。我见过不少初学者一开始就折腾本地部署,显卡、驱动、推理框架一整套下来,人先累瘫了一半,应用逻辑还没开始写。这个顺序是错的。

4.2 编排框架:先手写循环,再引入LangGraph

这是我最想强调的一点。现在市面上主流的编排框架有LangChain、LlamaIndex等,功能强大,组件丰富,点几下就能把RAG串出来。但我强烈建议你在学习期不要用,至少不要一上来就用。

原因有三个:第一,框架把太多细节封装成了黑盒,出了问题你根本不知道断在哪一环;第二,框架本身的抽象概念(Chain、Runnable、Callbacks)也是一套需要学习的内容,叠加在AI工程之上,等于一次学两套东西;第三,市面上绝大多数的报错,到最后排查时你会发现,自己手写十行代码就能解决的问题,框架里绕了半圈。

我自己带人的路径是:用原生SDK手写一次Agent循环,把请求、判断、工具调用、结果回填全部显式写出来。等你完全理解了每一步在干什么,再去看LangGraph这一类工具,你会发现自己几分钟就能看懂它的设计逻辑,而且能用得比直接上手更稳。

4.3 向量存储怎么选

三个字:看规模。我个人把选择分成四档,用一个表格说清楚:

方案适合场景部署方式是否需要中间件
Chroma学习项目、原型验证、数据量小嵌入式否
FAISS百万级以下、单机够用嵌入式/独立否
Qdrant需要高并发、过滤筛选丰富的生产环境Docker/独立服务是
Milvus千万级以上、大规模检索集群独立集群是

我的建议非常明确:第一个项目用Chroma就够,数据量大了再迁移到Qdrant。原因是Chroma的开箱即用体验极好,几行代码就能跑起来,让你专心理解检索逻辑本身。过早引入分布式向量库,等于在还没学会开车时先研究发动机原理。

4.4 观测与调试工具:越早接越好

很多做AI应用的人没有日志习惯,这是要付出代价的。普通程序的bug可以稳定复现,AI应用的bug往往“这次好、那次坏”,没有日志你根本无从定位。我现在最低限度的要求是:每个请求必须记录模型名称、输入内容、输出内容、token数、延迟、检索命中文档ID、工具调用过程。出错时能完整回溯。

开源工具里我比较常用的是Langfuse或者阿里云的链路追踪,核心无非是把关键节点埋点。如果你不想引入额外服务,用最简单的结构化日志打印到文件也能解决问题。重要是“有”,而不是“工具多高级”。这句话在我自己踩了无数次坑之后体会很深:没有日志的AI项目,出了问题就像在黑屋子里找一只黑猫。

5. 端到端实战拆解:一个带RAG和工具调用的客服助手

5.1 项目背景与功能定义

纸上谈兵这么多,我们直接跑一个完整的小项目。场景是:给一个小型电商公司做客服助手,需要处理两类用户请求。第一类是“知识库问答”,比如退换货政策、发货时间这类高频问题,靠RAG查企业手册;第二类是“订单查询”,用户给出订单号查物流状态,这个必须调真实订单系统接口。

这个项目规模不大,但它完整覆盖了AI工程的两条主要链路:检索增强和工具调用,非常适合照着做一遍。

5.2 整体流程设计

运行逻辑是这样的:用户发来一句话,系统先让模型判断意图。如果用户问的是政策类问题,模型触发search_knowledge_base工具,我们执行知识库检索,把结果带回模型生成回答;如果用户问的是订单状态,模型触发get_order_status工具,我们调订单接口拿真实数据,再组织回答;如果用户一次问了两件事,模型也会分别触发工具。

为了让步骤清晰,我画一下请求流转的要点:

  1. 用户输入进入对话循环;
  2. 模型判断:直接回答本地话术,还是需调用工具;
  3. 如需调用工具,模型返回结构化工具调用指令;
  4. 代码解析指令并执行对应函数;
  5. 把函数返回结果附加到对话上下文,回到第2步;
  6. 模型认为信息足够,输出最终回答,循环结束。

我在实际项目中把最大循环次数设为5,超过就返回“暂时无法处理,请转人工”,宁可让用户转人工也不无限烧token。

5.3 核心代码实现

这里给出一段可以照跑的Python核心逻辑,用OpenAI兼容接口演示,模型不锁定:

import json from openai import OpenAI client = OpenAI() def get_order_status(order_id: str) -> str: # 真实项目里这里是HTTP请求订单中心,这里做一个mock返回 return f"订单{order_id}当前状态:已发货,预计2天内送达。" def search_knowledge_base(query: str) -> str: # 真实项目里这里会走向量检索,这里用关键词匹配mock if "退货" in query or "退款" in query: return "我们支持7天无理由退货,前提是商品未经使用且包装完好。" if "发货" in query: return "现货商品一般在48小时内发货,定制类商品需要5-7个工作日。" return "知识库中没有找到直接相关的答案,请转人工处理。" TOOLS = [ { "type": "function", "function": { "name": "get_order_status", "description": "根据订单号查询订单当前物流状态", "parameters": { "type": "object", "properties": { "order_id": {"type": "string", "description": "订单编号"} }, "required": ["order_id"] } } }, { "type": "function", "function": { "name": "search_knowledge_base", "description": "从企业知识库中检索售后服务相关问题的标准答案", "parameters": { "type": "object", "properties": { "query": {"type": "string", "description": "用户原始问题或检索关键词"} }, "required": ["query"] } } } ] def run_agent(user_input: str) -> str: messages = [ {"role": "system", "content": "你是电商客服助手,回答简洁专业,涉及订单信息必须调用工具获取真实状态。"}, {"role": "user", "content": user_input} ] for _ in range(5): resp = client.chat.completions.create( model="gpt-4o-mini", messages=messages, tools=TOOLS, ) msg = resp.choices[0].message if msg.tool_calls: # 把模型产出的tool_calls追加到上下文 messages.append(msg) for tc in msg.tool_calls: args = json.loads(tc.function.arguments) if tc.function.name == "get_order_status": result = get_order_status(args["order_id"]) elif tc.function.name == "search_knowledge_base": result = search_knowledge_base(args["query"]) else: result = "未知工具" # 把工具执行结果以tool角色回传 messages.append({ "role": "tool", "tool_call_id": tc.id, "content": result, }) else: return msg.content return "抱歉,我暂时无法完成这个请求,已为你转接人工客服。" # 测试用例 if __name__ == "__main__": print(run_agent("帮我查一下订单20240617-8899的物流状态")) print(run_agent("我想退货,请问怎么操作?"))

这段代码有三个关键细节值得你反复看:一是tool_calls信息要追加到messages里,不追加模型就丢了“它自己刚才想调用工具”这个上下文;二是工具执行结果必须以role等于tool回传,并且tool_call_id要和模型给出的一致;三是循环次数的硬上限,这是成本控制和避免死循环的第一道防线。

5.4 评估集与回归测试

代码能跑起来之后,不要急着交付。我建议建一个分类评估集,至少20条问题,分布如下:

类型数量示例
纯知识库问答8条“退换货运费谁承担?”
纯订单查询6条“订单20240618-1234发货了吗?”
混合型问题6条“我的订单晚到了,能赔偿吗?”

每次改动代码后,批量跑一遍评估集,人工判断或写脚本自动评分。这一步在你日后的复杂系统里会变成一个自动化流水线,它决定了你改任何一行代码时有没有安全感。我自己在这个项目里的实测结果是:手写循环比直接套框架的通过率高7个百分点,原因不是模型变聪明了,而是我能精确控制上下文拼接和重试策略。

6. 落地时最容易翻车的四个工程坑

6.1 上下文塞爆与截断的取舍

我见过最多的灾难点是:开发者为了“让模型答得更好”,把整本手册、全部历史对话一股脑塞进提示词,然后很快遇到上下文窗口爆掉。解决方法看起来是“截断”,但粗暴截断会让模型丢失关键信息。

正确的做法是分层递进:先用检索把资料范围缩小,只把命中的片段放进去;命中片段仍然过长时,就做摘要压缩,而不是头部截断;历史对话只保留最近几轮,更早的信息做摘要缓存。这个“资料只是引用,不是全文”的思路,是RAG的核心精神。我有一次把用户手册一个章节全文塞进去,回答质量反而下降了,因为无关文字干扰了模型对重点的注意力。

6.2 工具调用时JSON解析的防御式处理

模型返回的tool_calls参数经过JSON序列化,但解析时不能假设它永远合法。实测中会出现参数名拼错、值类型错误、多出无关字段等情况。我的处理方式是:解析外层函数名用官方SDK字段,参数解析则包一层try-except,失败后不回传错误给用户,而是重新请求模型一次,让模型修正参数。

还有一个隐藏很深的坑:模型返回一个工具名,但参数里缺了必填字段。你的代码访问args["order_id"]会抛KeyError,然后整个Agent崩溃。处理办法是写一个字段校验函数,缺什么补提示词让模型补充,而不是直接相信模型输出。凡是模型输出的东西,都要当成“来自外部用户输入”一样做严格校验,这是我在AI工程里学到的第一课。

6.3 Agent死循环与费用失控

Agent循环不加限制的后果,比想象中严重得多。最坏的情况是:模型反复要求调用同一个工具,工具每次返回相似结果,它又觉得信息不足,继续调用,一轮循环几十次,账单蹭蹭上涨,用户还等不到答复。

三道防线缺一不可:硬性循环次数上限(实战中我一般设3到5轮);同工具连续调用次数检测,超过两次就强制转人工;单次请求的token总预算,用max_tokens和调用监控双保险。我在生产环境里还加了费用告警,每天超过预设金额直接切断接口,宁可功能不可用,也不能失控。这个说得可能有些严重,但在企业场景里,成本失控是真实的安全生产事件。

6.4 “自测感觉良好”的评估陷阱

最后一个坑不是技术问题,而是心态问题。很多开发者自己设计了测试问题,跑几次觉得回答都挺好,就上线了。结果真实用户一问,答得乱七八糟。原因是自测问题往往和你的提示词措辞高度一致,而真实用户的表达千奇百怪,包括错别字、口语化、指代不明。

我的建议是:评估集除了自己写,还要分两个来源——第一,让身边不参与开发的人按真实语气提问题;第二,上线后收集真实用户问题进入评估集。把评估集改造成一个“会生长的活集子”,每次用户反馈不好的案例都沉淀进去。系统不是越做越聪明,是越做越“稳”,原因是它见过的坏例子越来越多,回归测试能拦住大部分劣化。

踩过足够多的坑之后,我自己的体会

亲手把从零到交付的流程完整走过一遍之后,我最大的感受是:AI工程真正考验人的地方不在于某一次调用写得多漂亮,而在于你能不能把一个充满不确定性的系统设计得有边界、有兜底、可观测。它和传统后端的区别,就像带实习生和写死脚本的区别——你得相信“实习生”有判断力,同时永远假设它会犯错。

如果只给一条建议,我会说:拿一个真实的小任务,哪怕只是把你自己的知识库做成问答,也要把它当作一个长期维护的产品来做,而不是一次性的脚本。先跑通最小系统,再逐步补上检索优化、评估、日志和成本控制。卡住的时候,把报错信息原样复制去搜索,你大概率不是第一个遇到这个问题的人。AI工程没有想象中那么陡峭的入门门槛,但它确实需要耐心——每一步都搞懂为什么,比赶进度重要得多。

返回列表