这几年我在社区分享里被问到最多的一个问题,就是“我想学AI开发,应该从哪里开始”。市面上的教程其实不少,但大多只讲一个点:要么只教Prompt怎么写,要么扔给你一段RAG代码,要么让你先啃三个月数学。结果就是学的时候热血沸腾,真到自己动手做一个“能用的东西”时,又不知道这些零散的知识到底怎么串起来。
这篇文章把我在实际带新人、做项目过程中沉淀下来的一条完整路线摊开讲。所谓7大核心领域,说穿了就是7个绕不开的关卡:LLM与Prompt工程、RAG检索增强生成、Agent智能体、记忆系统、工具调用、评估调优、部署工程化。把这条线走通,你就能从一个只会调接口的调用者,变成能独立搭建完整AI应用的开发者。我不说什么“秒变大神”,但按这条线走,确实能让你少走至少半年的弯路。
不管你是刚学Python准备转行的人,还是写了几年业务代码想切到AI应用方向的工程师,又或者只是想在公司内部快速落地一个智能问答机器人,下面这份拆解都值得从头到尾看一遍。
1. 七大核心领域全景拆解:AI开发到底在学什么
1.1 这七个领域分别解决什么问题
很多新手学AI开发最大的障碍,不是某个技术点难,而是不知道这些技术点各自处于什么位置。我习惯把AI应用开发拆成7个问题,每个问题对应一个核心领域,答案就非常清晰了。
| 领域 | 要解决的问题 | 最小可运行产出 |
|---|---|---|
| LLM与Prompt工程 | 怎么让大模型按你的想法输出高质量内容 | 一段稳定生效的Prompt,一个标准的模型调用 |
| 结构化输出 | 怎么让模型输出可被程序直接解析,而不是一堆自由文本 | 能稳定返回JSON的程序接口 |
| 工具调用 | 怎么让模型调用外部函数、操作数据库、访问第三方接口 | 一个模型可触发并可拿到结果的函数 |
| RAG检索增强生成 | 怎么让模型回答私有知识、最新知识 | 一个“文档进、答案出”的知识库问答链路 |
| Agent智能体 | 怎么让模型把一个复杂任务拆解成多步并自动执行 | 一个能自主规划并调用工具的机器人 |
| 记忆系统 | 怎么让AI记住多轮对话和用户长期偏好 | 一个跨会话记住用户身份的对话系统 |
| 评估调优与部署 | 怎么判断AI答得好不好,怎么让系统稳定、可控、低成本上线 | 一个评估集、一套监控日志、一个API服务 |
这7件事,正好构成了一个AI应用从无到有、从能跑到能用的完整闭环。
1.2 它们是怎么串起来的
你可以想象一个真实的用户请求走完整条链路的样子:用户发来一句话,模型需要先理解意图,如果这个问题涉及私有知识,就触发RAG去检索资料;如果这个任务需要操作外部系统,Agent就会规划步骤并调用工具;过程中记忆系统负责把之前聊过的话题、用户的偏好带回来;最后生成的结果要被评估系统验证质量,整个服务通过部署模块对外提供稳定访问。
所以这7个领域不是并列的7个知识点,而是一条生产流水线。这也是为什么我特别不建议只盯着“大模型原理”看——对于绝大多数应用开发者来说,真正决定你项目能否落地的,不是你对Transformer理解多深,而是你能不能把这条流水线的每个环节都跑通。
1.3 推荐的学习顺序
我建议的学习路径是:先学Prompt与结构化输出,再学RAG,然后是记忆系统,接着是Agent,最后补评估和部署。
这个顺序不是随便排的。Prompt是基本功,你连让模型稳定输出JSON都做不到,后面所有环节都会很痛苦;RAG是应用最广、性价比最高的能力,做知识库问答是练手的最佳场景;记忆系统是让对话“像真人”的关键;Agent最复杂,它同时依赖工具调用、上下文管理和任务拆解,所以放在中间偏后;评估和部署则应该尽早接触,但不用学得太深,先知道有这回事,等项目做大了再回来补。
2. Prompt工程与结构化输出:先学会让模型“说人话”
2.1 把大模型当成一个能力很强但什么都不懂的实习生
我经常给新人打一个比方:大模型就像一个刚来公司报到的实习生,知识面广、理解能力强、反应速度飞快,但它对你的业务一无所知,也不知道你的真实意图。你给它模糊指令,它就自由发挥;你给它清晰的要求、材料、步骤和示例,它就能交出接近你想要的结果。
这个认知能解释很多现象。为什么同一个模型,有人用起来像“人工智障”,有人却觉得强得离谱?因为前者把模型当数据库,直接问“我们公司的报销流程是什么”,模型当然只能编一个;后者把模型当执行者,先把报销制度文档传进去,再明确要求“只基于材料回答,不要自己发挥”,结果自然靠谱得多。
这里有一个很重要的概念叫“上下文窗口”。模型的输入空间是有限的,旧内容会被挤出去。它不是真的“什么都记得”,你给它的材料,才是它当下唯一能依据的事实来源。理解了这一点,你就能理解RAG为什么存在,也能理解记忆系统为什么难做。
2.2 一份可以直接抄走的Prompt结构
好的Prompt没有神秘配方,但有一个非常稳定的结构。我自己写Prompt,几乎都是这个框架:
# 角色 你是一名熟悉XX业务的资深客服顾问。 # 任务 根据用户的问题,从提供的材料中寻找答案并回复。 # 背景材料 (这里放检索到的文档内容) # 要求 1. 只基于材料回答,如果材料中没有答案,必须说“资料未覆盖该问题”。 2. 回答控制在200字以内,使用口语化表达。 3. 不要编造任何数据。 # 输出格式 先给出直接答案,再附上“信息来源”字段。 # 示例 材料:报销标准为每人每天300元。 问题:出差住宿能报多少? 回答:每人每天300元,超过部分自理。 信息来源:差旅报销制度V2每一段都有它的作用。“角色”是给模型一个行为基准,“任务”是说清楚要做什么,“背景材料”是事实边界,“要求”是硬性约束,“输出格式”是为了让结果能进入下游流程,“示例”则是给模型一个“照这个样子去写”的参照物。
其中最容易被人忽略的是“示例”。很多人写Prompt只写“请用专业方式回答”,但模型对“专业”的理解和你完全不同。你给一个具体的例子,它立刻就能对齐你要的语感、长度和结构。哪怕只给一个示例,效果往往都比增加十条抽象描述更明显。
2.3 结构化输出:让AI结果能被程序消费
用大模型做应用,最怕的不是它答错,而是它答出来的东西没法被程序解析。你做一个点单机器人,让模型返回“顾客点了什么”,它给你回一句“这位顾客想要一份牛肉面,唔……加个蛋好像也不错”,后端就只能干瞪眼。
这条路线的第一个硬门槛,就是让模型稳定输出JSON。目前主流做法有两种:一种是使用接口层面的JSON模式约束,直接在请求参数里声明返回格式为JSON对象;另一种是写清楚JSON的结构,甚至给一个带示例的返回模板。对于复杂的结构化需求,更可靠的方式是使用模型工具调用能力,也就是让模型从一个预定义好的函数列表里,选出应该调用的那个函数,并填好参数。
from pydantic import BaseModel class OrderInfo(BaseModel): customer_name: str items: list[str] total_amount: float def extract_order(user_input: str): resp = call_model( messages=[{"role": "user", "content": user_input}], response_format={"type": "json_object"}, ) raw = resp["content"] # 解析之前先做一层兜底:清理多余逗号、修补引号 return OrderInfo.model_validate_json(raw)这里有个实战教训:就算加了JSON模式约束,模型偶尔也会产出带注释、多逗号、字段缺失的JSON。所以在解析层一定要做校验和兜底,解析失败时让模型重新生成一次,或者直接给出“无法识别”的友好提示。永远不要默认模型100%听话。
3. RAG检索增强生成:把知识库变成模型的外挂
3.1 为什么要学RAG,而不是去微调
新手很容易纠结一个问题:想让模型懂我们公司的业务,到底是微调还是RAG?我的回答很直接:绝大多数场景,优先做RAG。
原因很简单。微调的本质是改变模型内部的参数,它适合改变模型的“行为风格”或“输出习惯”,比如让模型更幽默、更严谨、更擅长某种文风。但它不擅长注入频繁更新的知识,因为每次知识变了都要重新训练,成本高、周期长,而且你很难控制它到底记住了什么。
RAG的本质则是“考开卷考试”。你并不指望模型脑子里装着你的知识,你只是在它回答问题之前,把相关的资料塞进它的视野里。这样做有三个直接好处:知识更新只需要换文档,不需要重新训练;答案可以追溯到具体来源,出现错误时能定位责任;成本远低于微调,一个小团队也能轻松维护。
3.2 RAG的标准链路
RAG的全称是检索增强生成,标准链路分离线准备和在线问答两段。
离线阶段要做四件事:加载文档、切分文本、向量化、存入向量数据库。在线阶段则是把用户的提问向量化,在向量库里找到最相似的几个片段,把片段拼接进Prompt,再交给大模型生成答案。
这里我见过最多的失败案例,不是生成环节,而是离线准备阶段被糊弄过去了。文档不清理就直接切分、表格被硬生生从中间切开、同一份PDF里夹杂着扫描图片没做OCR……这些脏数据进到链路里,检索质量必然崩盘。RAG这条链路是“垃圾进、垃圾出”,前置的数据清洗工作占了整个项目一半以上的工作量,一点都不夸张。
3.3 切分、向量化和检索参数的经验值
文本切分是RAG里最容易被忽视、却又最影响效果的环节。切得太粗,一个片段里塞了太多无关内容,向量检索时匹配不精准;切得太细,语义被切断,模型拿到的上下文不完整。
常见的经验做法是:通用文本按字符切分,块大小建议设在300到800字之间,相邻块之间保留30到80字的重叠,避免关键句恰好被切成两半。如果文档本身有清晰的标题结构,更好用的方式是先按标题、章节切分,再对过长的段落二次切分。代码文件最好按函数或类切分,表格则尽量不要跨行截断。
向量化这一步核心是选Embedding模型。中文场景不要只看公开榜单,一定要自己拿领域数据做小规模测试。判断指标就是你随便抽几个问题,看检索出来的前5条是不是真的相关。检索时TopK一般设在5到10之间,太低容易漏,太高则会把大量噪声塞进Prompt。如果发现专有名词、人名、产品名经常检索不到,别急着换Embedding,先试试在向量检索之外加一层传统的关键词检索,把两边的结果合并去重,这种混合检索往往立竿见影。
3.4 一个最小可用的RAG检索实现
我平时做原型验证,会先写一个最简版本,确认链路通不通,再做优化:
def search(query: str, top_k: int = 5): query_vec = embed_model.encode(query) hits = vector_store.search(query_vec, top_k=top_k) return [hit.text for hit in hits] def build_rag_prompt(query: str, docs: list[str]) -> str: context = "\n\n".join(f"[片段{i + 1}] {doc}" for i, doc in enumerate(docs)) return f"""基于以下材料回答问题。如果材料中没有相关内容,直接回答“资料未覆盖”。 材料: {context} 问题:{query} 回答:"""这个版本跑通以后,再逐步加段落重排、混合检索、引用溯源。我自己做知识库问答项目时,第一步永远是把检索结果打印出来人工看一遍。如果检索结果本身就不相关,那不管Prompt写得再好都没有用;如果检索结果是相关的,但答案还是不对,问题就出在生成环节。这个排查顺序能让调试效率高非常多。
4. Agent与记忆系统:让AI自己规划、干活、记得住
4.1 Agent的本质:从“一次性提问”变成“多步任务执行”
普通对话是你问一句、模型答一句;Agent则是把一个大任务拆成多个小步骤,每走一步都观察结果、调整计划,直到任务完成。打个比方,普通对话像是你让实习生写一段话,Agent则是你给实习生一个目标,他自己决定查哪些资料、问哪些人、用哪些工具,然后把结果汇总给你。
Agent的核心循环其实很简洁:模型根据当前状态决定下一步行动,如果需要外部信息或操作,就调用工具;工具执行完,把结果返回给模型继续推理;直到模型认为任务结束,输出最终答案。最小实现长这样:
def run_agent(query: str, tools: list[dict], max_steps: int = 8): messages = [ {"role": "system", "content": system_prompt}, {"role": "user", "content": query}, ] for _ in range(max_steps): resp = call_model(messages, tools=tools) if resp.get("tool_calls"): messages.append(resp) for call in resp["tool_calls"]: result = execute_tool(call) messages.append({ "role": "tool", "tool_call_id": call["id"], "content": str(result), }) else: return resp["content"] return {"error": "达到最大步数,任务未完成"}这里有三个细节新手很容易忽略。第一,必须设置最大步数上限,否则模型可能在错误路径上反复循环;第二,工具执行结果要全部放回上下文,模型才能“看到”结果并继续决策;第三,工具出错时不要只返回一个异常对象,尽量把错误原因写成人话,模型才知道接下来该怎么补救。
4.2 工具调用:Agent的“手”和“眼睛”
没有工具的Agent只是聊天机器人,有了工具,Agent才真正具备执行力。工具定义的核心是让模型清楚“这个工具是干什么的、参数怎么填”。写工具描述时,要像写给一个从没见过这个功能的实习生看:说清楚用途、参数含义、单位、边界条件。
{ "type": "function", "function": { "name": "get_weather", "description": "获取指定城市当前天气,供用户出行参考", "parameters": { "type": "object", "properties": { "city": { "type": "string", "description": "城市中文名,例如:北京、上海" } }, "required": ["city"] } } }工具描述的质量直接影响调用成功率。我见过最典型的失败案例,是把“根据城市查询天气”写成“查询天气”,结果模型频繁漏传城市名。工具描述一定要包含“什么时候用、什么时候不用”的说明,比如只查今天的天气、不查历史天气,这些边界写清楚,能显著减少误调用。
另外,不要一次性给模型挂十几个工具。工具越多,模型挑错工具的概率越高。合理的做法是在一个Agent里只放当前任务真正需要的3到8个工具,或者先做一个工具路由,让模型先决定进入哪个子模块,再面对那一组精简工具。
4.3 记忆系统:短中长记忆怎么落地
记忆系统是Agent能不能“越用越懂你”的关键。我习惯把记忆分成三种,分别处理不同时间尺度的信息。
第一种是短期工作记忆,也就是当前这轮会话里的上下文。它最简单,但受上下文窗口限制,对话一长旧内容就被挤掉了。第二种是长期记忆,用来保存用户的偏好、关键事实、历史结论。第三种是程序记忆,也就是系统Prompt、工具定义、流程规范这些“该怎么做”的知识。
常见的落地方式是把长期记忆做成“事实抽取+检索注入”。每一轮对话结束后,让模型从对话里抽取值得长期保留的事实,比如“用户偏好简短回答”“用户上周提到家里养了一只猫”,把事实存进向量库或关系表。下次新会话开始时,根据用户当前输入检索相关记忆,把这些记忆拼进系统Prompt里。这样AI就拥有了“跨会话记忆”。
def build_initial_messages(user_input: str, memory_store): memories = memory_store.retrieve(user_input, top_k=5) memory_block = "\n".join(f"- {m.text}" for m in memories) system_prompt_with_memory = system_prompt + "\n\n关于用户的已知信息:\n" + memory_block return [ {"role": "system", "content": system_prompt_with_memory}, {"role": "user", "content": user_input}, ]4.4 上下文管理:别让记忆变成负担
很多新手做记忆系统,容易走极端,恨不得把用户所有历史消息全部塞给模型。结果就是上下文爆掉、响应变慢、费用飙升,模型反而被一堆无关历史带偏。
短期的多轮对话,我建议只保留最近N轮完整的消息,更早的内容生成一段摘要放在最前面。这个窗口大小根据模型上下文长度来定,一般保留最近10到20轮是够用的。长期的记忆要控制写入量,只保留那些“下次大概率还会用到”的信息。无关记忆召回也是一种污染,不要一上来就把所有历史记忆全部注入,按相关度做检索才是正确的姿势。
这里还要提一句合规意识:用户对话记录和偏好信息属于个人数据,做记忆系统时一定要遵循最小化存储原则,明确告诉用户保存了什么、保留多久,该做脱敏的做脱敏。这是做一个合格AI应用的基本底线。
5. 评估与调优:别靠感觉,要用数据说话
5.1 为什么必须建一套评估集
AI应用开发里最可怕的不是效果差,而是“不知道今天比昨天好了还是坏了”。没有评估集的AI项目,就是一个没有仪表盘的飞机,全凭驾驶员手感。
我的习惯是,项目第一天就建一个评估集,哪怕只有20条人工整理的问题和期望答案。每一条样例要包含输入、期望回答、判断标准。慢慢补充到50到100条,覆盖主要使用场景、边缘情况和容易被搞错的硬骨头问题。这个评估集就是整个项目“好不好”的唯一标尺。任何Prompt调整、参数变化、模型替换,都要跑一遍评估集,对比分数,再做决定。
5.2 常用评估指标和“模型当裁判”的实操方法
评估维度不要只盯着“答得对不对”,我常用这几类指标。
| 维度 | 度量方式 | 说明 |
|---|---|---|
| 准确性 | 人工/模型评分 | 答案核心信息是否与标准答案一致 |
| 相关性 | 检索结果人工抽检 | 召回的片段与提问是否相关 |
| 完整性 | 打分制 | 该回答的要点是否都覆盖 |
| 格式正确率 | 程序自动统计 | JSON能否被解析、字段是否齐全 |
| 工具调用成功率 | 程序自动统计 | Agent正确选择和调用工具的比例 |
| 延迟与成本 | 日志统计 | 单次请求耗时、Token消耗 |
人工一条条评估太慢,我一般会让一个更强的模型当“裁判”。做法是把问题、标准答案、模型回答一起交给裁判模型,给它一份评分标准,让它按1到5分打分。但要注意,裁判模型打分存在偏好,所以我会抽20%的样本做人工复核,防止裁判模型被带偏。
5.3 bad case排查:先修检索,再修Prompt,最后换模型
评估集建好以后,真正拉开水平差距的是处理bad case的能力。我总结了一套排查顺序,基本适用于所有问答和Agent场景。
第一步看检索结果。把这条问题的召回片段打印出来,如果不相关,问题在切分、Embedding或检索策略;如果相关,继续往下查。第二步看Prompt。如果召回是对的但答案答偏了,检查是不是约束不清、材料摆放顺序不对、示例不匹配。第三步才考虑换模型。同一个问题,如果小模型加好Prompt能解决,就没必要上大模型。
另外一条铁律:一次只改一个变量。很多人调试的时候同时改Prompt、换模型、调参数,效果变好了都不知道是哪个改动起了作用。用评估集做“对照组实验”才是正确的优化方式。
6. 部署与工程化:从能跑通的Demo到能上线的系统
6.1 Demo和产品之间到底差了什么
本地Notebook里能跑的Demo,和能稳定对外服务的产品,中间隔着好几层。最直观的是并发:Demo一次处理一个请求,产品要同时应对几十上百个请求;然后是异常处理:上游大模型接口超时怎么办、返回格式异常怎么办、用户输入恶意内容怎么办;还有可观测性:线上报错了,你却不知道是哪一步出的问题;最后是成本:一个请求消耗多少Token、能不能扛住日常量,这些都是工程问题。
我见过太多团队卡在这一步:AI能力已经验证得很好,但迟迟无法上线,因为一并发就挂、一出错就没日志、一优化就伤及效果。所以从一开始写代码时,就要把日志和版本记好,把“发生了什么”记录下来。
6.2 快速封装一个可用的API服务
把AI能力服务化,用常见的Web框架就能搞定。核心是做一个输入输出明确的接口,把LLM/RAG/Agent链路封装在内部,对外只暴露一个简单的Chat接口。
from fastapi import FastAPI from pydantic import BaseModel app = FastAPI() class ChatRequest(BaseModel): message: str session_id: str = "default" @app.post("/chat") def chat(req: ChatRequest): reply = run_rag_or_agent(req.message, req.session_id) return {"reply": reply}这里有个体验层面的重点:流式输出。大模型生成文本有延迟,如果让用户等一个完整答案生成完才返回,感觉就像“卡死了”。生产环境一定要支持流式返回,让用户看到文字一个一个蹦出来,体验差距非常大。
6.3 缓存、观测与成本控制
服务上线后,第一个要面对的就是成本。我的经验是:能缓存就缓存。完全相同的用户提问,如果近期已经回答过,直接返回缓存结果;知识库里相同的检索片段,也可以做结果缓存。但要注意,带记忆的对话不能简单整条缓存,否则会出现“上一条记住了”“这一条又忘了”的怪异体验。
观测层面,每个请求必须记录:时间、用户标识、输入内容、输出内容、调用了哪些工具、耗时、Token消耗、用的什么模型版本。这些日志不仅是成本分析的基础,也是后面排查bad case的核心资产。
成本控制还有几个实用技巧。第一是模型分级,简单任务用便宜的小模型,复杂任务才上大模型;第二是Prompt瘦身,把冗余的模板词删掉,能压几百个Token;第三是控制历史轮数,不要无限堆累积。这些细节累积起来,月度成本差距可能是几倍。
7. 常见问题速查与新手避坑实录
7.1 高频问题速查表
| 现象 | 可能原因 | 排查思路 |
|---|---|---|
| 模型答非所问 | Prompt约束不足、缺少示例 | 补角色、任务、约束和示例 |
| 多轮对话失忆 | 上下文窗口被旧内容占满 | 压缩历史、做摘要、接长期记忆 |
| RAG答案不准 | 检索片段不相关或切分有问题 | 先人工检查召回,再调整切分策略 |
| Agent反复执行同一工具 | 工具返回信息不明确 | 让工具返回清晰错误原因,设置最大步数 |
| JSON解析报错 | 模型输出不符合规范 | 增加解析兜底、要求重新生成、用工具调用 |
| 系统响应越来越慢 | 上下文太长、链路太重 | 压缩输入、做缓存、模型分级 |
| 效果时好时坏 | 没有评估集,凭感觉优化 | 建评估集,一次只改一个变量 |
| 成本超预期 | 历史全量塞入、频繁调用大模型 | 精简Prompt、控制历史、动态选择模型 |
7.2 新手最容易踩的几个坑
第一个坑是把大模型当搜索引擎用,不提供材料就让它答私有问题,结果当然是幻觉。第二个坑是跳过评估直接调参数,改了两周不知道效果是变好还是变坏。第三个坑是不看日志,出了问题只能对着屏幕发愣。第四个坑是过早优化,项目还在验证阶段就想着分布式、上K8s,结果连核心链路都没跑通。
我的建议是:用最小化方案先跑通一个完整闭环。哪怕只是一个“上传一份文档,然后可以提问”的网页,也比十篇课程笔记更有价值。从一个具体小场景出发,把它全链路走通,你自然就知道下一步该补什么。
我自己带过不少转行做AI的新人,大多数人最后没做出来,不是输在智商,而是输在“东西太多不知道先抓哪一头”。如果你现在也处在同样的状态,不需要焦虑,就按照这条路线,从写好一个Prompt开始,到跑通一个RAG问答,再试着加一层记忆,给Agent挂一个工具。每一步都做出一个真正能运行的东西,这个过程中的收获,远比你囤十门课要实在。