7天从零构建大模型应用:RAG与Agent实战指南
想学大模型应用开发但面对海量教程和快速迭代的技术你是不是经常感到无从下手要么是课程太浅只讲API调用要么是项目太散学完不知道如何整合更头疼的是很多教程用的工具链和模型版本已经过时照着做一堆报错。这篇文章要解决的正是这个核心痛点如何用一套系统、可落地的路径真正从零开始在7天内构建出具备RAG和Agent能力的完整大模型应用。这不是一个简单的“Hello World”调用而是涵盖环境搭建、核心概念、项目架构、代码实战到部署上线的全流程。很多人误以为大模型应用开发就是调个API返回一段文本。实际上一个能投入使用的应用至少需要处理知识检索增强RAG来突破模型的知识截止日期设计智能体Agent来完成多步骤任务并考虑工程化问题如成本、流式输出和错误处理。本文将基于当前2026年的主流技术栈带你完整走通这个流程。读完本文你将能清晰地回答大模型应用开发的技术栈是什么RAG和Agent分别解决什么问题如何从零搭建一个具备对话、检索和任务执行能力的AI应用以及如何避开那些新手最容易踩的“坑”。1. 重新定义“入门”大模型应用开发到底在开发什么在开始写代码之前我们必须先厘清概念。大模型应用开发绝不仅仅是openai.ChatCompletion.create()那么简单。它本质上是在构建一种新的软件范式——以大型语言模型为推理核心的智能系统。传统的软件是“确定性”的输入A经过逻辑B必然得到输出C。而大模型应用是“概率性”的它具备理解、推理和生成能力但输出存在不确定性。因此我们的开发目标从“实现固定逻辑”转变为“设计交互流程、提供上下文、约束输出并处理不确定性”。当前2026年一个典型的企业级大模型应用通常由以下核心模块构成大模型服务层提供核心的文本生成与理解能力。可以是OpenAI GPT、Claude、国内大厂模型或本地部署的Llama、Qwen等开源模型。嵌入模型与向量数据库层负责将非结构化文本如PDF、Word转化为向量并存储实现RAG检索增强生成。这是让模型“拥有”最新、私有知识的关键。智能体Agent框架层负责规划、工具调用和任务分解。一个Agent可以理解用户意图决定调用搜索工具、计算器还是数据库查询并整合结果。应用编排与业务逻辑层处理用户会话、状态管理、权限验证并将上述组件串联成完整的业务流。如果你是一名Web开发者可以这样类比大模型相当于“数据库业务逻辑”的智能结合体向量数据库是新型的“索引存储”Agent框架则是“工作流引擎”。我们的开发工作就是将这些“智能中间件”有机地集成起来。2. 环境准备搭建一个稳定、可复现的开发底座工欲善其事必先利其器。大模型开发环境涉及Python环境、包管理、可能用到的本地模型服务等。为了避免“跑不通”的尴尬请严格按照以下步骤操作。2.1 Python与包管理工具推荐使用Python 3.10或3.11。Python 3.12可能存在某些库的兼容性问题。使用conda或venv创建独立的虚拟环境是必须的。# 使用 conda推荐便于管理不同Python版本 conda create -n llm-dev python3.10 conda activate llm-dev # 或者使用 venv python3.10 -m venv llm-dev-env source llm-dev-env/bin/activate # Linux/Mac # llm-dev-env\Scripts\activate # Windows2.2 核心开发库安装我们将使用一套2026年依然主流且稳定的技术栈LangChain / LangGraph: 应用编排框架的事实标准用于构建链和Agent。Chroma / Qdrant: 轻量级、易于上手的向量数据库。Sentence-Transformers: 用于生成文本向量的嵌入模型。Ollama(可选): 在本地运行开源大模型如Llama 3, Qwen2.5的利器。通过pip一次性安装核心库pip install langchain langchain-community langchain-core pip install chromadb sentence-transformers pip install pypdf python-dotenv # 用于处理PDF和读取环境变量 # 如果需要Web交互界面可以安装Gradio或Streamlit pip install gradio2.3 模型API密钥配置如果你使用云端API如OpenAI DeepSeek 智谱AI等需要将API密钥设置为环境变量。永远不要将密钥硬编码在代码中创建一个名为.env的文件在项目根目录# .env 文件示例 OPENAI_API_KEYsk-your-openai-key-here # 国内模型示例 DASHSCOPE_API_KEYsk-your-dashscope-key-here # 阿里通义千问 ZHIPUAI_API_KEYyour-zhipuai-key-here # 智谱GLM在Python代码中使用python-dotenv加载# config.py import os from dotenv import load_dotenv load_dotenv() # 加载 .env 文件中的所有变量 OPENAI_API_KEY os.getenv(OPENAI_API_KEY) if not OPENAI_API_KEY: raise ValueError(请在 .env 文件中设置 OPENAI_API_KEY)3. 核心概念深度解析RAG与Agent为何是两大支柱理解了“为什么”才能更好地知道“怎么做”。RAG和Agent是大模型应用的两大核心范式它们解决了不同维度的问题。3.1 RAG给模型装上“外部记忆”它解决了什么问题大模型存在“知识截止日期”和“幻觉”问题。问它“2025年诺贝尔奖得主是谁”它可能不知道或编造答案。RAG通过以下流程解决索引将你的私有文档手册、报告、知识库切块转化为向量存入向量数据库。检索当用户提问时将问题也转化为向量从数据库中找出最相关的文本块。增强将这些相关文本块作为“参考依据”和用户问题一起提交给大模型要求它基于此生成答案。关键比喻RAG就像开卷考试。模型学生可以带着你的资料向量数据库进考场答题时快速查阅从而给出更准确、有依据的答案。3.2 Agent让模型学会“使用工具”它解决了什么问题大模型本身无法执行动作它只会“说”。Agent赋予模型“做”的能力。一个典型的Agent工作流程是规划模型分析用户请求如“查一下北京明天天气并总结成一句话”。工具调用模型决定需要调用哪些工具如“天气查询API”、“文本总结函数”。执行与观察框架执行工具调用将结果返回给模型“观察”。迭代与输出模型根据结果决定下一步继续调用工具或生成最终答案。关键比喻Agent就像一位项目经理。它理解目标用户需求知道团队里有哪些专家工具并协调这些专家分工合作最终交付成果。4. 项目实战一构建你的第一个RAG问答系统让我们从一个具体的RAG系统开始。目标上传一份PDF产品手册让AI能基于手册内容回答用户问题。4.1 项目结构初始化my_rag_project/ ├── .env # 存储API密钥 ├── config.py # 配置文件 ├── main.py # 主程序入口 ├── documents/ # 存放待处理的PDF文件 │ └── product_manual.pdf ├── vector_store/ # 向量数据库持久化目录Chroma自动创建 └── requirements.txt # 项目依赖4.2 文档加载与处理我们使用LangChain的文档加载器和文本分割器。# main.py - 第一部分文档处理 from langchain_community.document_loaders import PyPDFLoader from langchain.text_splitter import RecursiveCharacterTextSplitter def load_and_split_documents(pdf_path): 加载PDF并分割成文本块 loader PyPDFLoader(pdf_path) documents loader.load() # 加载文档 # 文本分割器按字符递归分割保证语义相对完整 text_splitter RecursiveCharacterTextSplitter( chunk_size500, # 每个块的最大字符数 chunk_overlap50, # 块之间的重叠字符避免割裂上下文 separators[\n\n, \n, 。, , , , , , ] # 分割符优先级 ) splits text_splitter.split_documents(documents) print(f原始文档页数: {len(documents)}) print(f分割后文本块数量: {len(splits)}) return splits if __name__ __main__: doc_splits load_and_split_documents(./documents/product_manual.pdf)关键参数解析chunk_size500这是一个经验值。太小会丢失上下文太大会包含无关信息影响检索精度。对于中文可以适当调大到600-800。chunk_overlap50重叠部分能防止一个完整的句子或概念被硬生生切开。4.3 向量化与存储这里我们使用Chroma作为向量数据库all-MiniLM-L6-v2作为嵌入模型轻量且效果不错。# main.py - 第二部分创建向量库 from langchain.embeddings import HuggingFaceEmbeddings from langchain.vectorstores import Chroma def create_vector_store(splits, persist_directory./vector_store): 创建并持久化向量存储 # 使用开源嵌入模型无需API密钥在本地运行 embeddings HuggingFaceEmbeddings( model_namesentence-transformers/all-MiniLM-L6-v2, model_kwargs{device: cpu}, # 如果有GPU可改为 cuda encode_kwargs{normalize_embeddings: False} ) # 创建向量存储并持久化到磁盘 vectorstore Chroma.from_documents( documentssplits, embeddingembeddings, persist_directorypersist_directory ) vectorstore.persist() # 确保写入磁盘 print(f向量库已创建并保存至: {persist_directory}) return vectorstore if __name__ __main__: # 接上一部分代码 vectordb create_vector_store(doc_splits)4.4 构建检索链并提问现在我们将向量库与大模型连接起来形成一个完整的“检索-生成”链。# main.py - 第三部分构建RAG链并查询 from langchain.chains import RetrievalQA from langchain_openai import ChatOpenAI # 假设使用OpenAI模型 from config import OPENAI_API_KEY # 从config.py导入密钥 def create_rag_chain(vectorstore): 创建RAG问答链 # 1. 定义LLM llm ChatOpenAI( modelgpt-3.5-turbo, # 或 gpt-4, gpt-4-turbo temperature0.1, # 较低的温度使输出更确定更适合事实性问答 openai_api_keyOPENAI_API_KEY ) # 2. 创建检索器设置返回最相关的3个文本块 retriever vectorstore.as_retriever(search_kwargs{k: 3}) # 3. 创建RetrievalQA链 qa_chain RetrievalQA.from_chain_type( llmllm, chain_typestuff, # 最常用的类型将所有检索到的文档“塞”进上下文 retrieverretriever, return_source_documentsTrue, # 返回源文档便于调试 verboseTrue # 打印详细日志学习时建议开启 ) return qa_chain def ask_question(qa_chain, question): 向RAG链提问 result qa_chain.invoke({query: question}) print(f\n问题: {question}) print(f答案: {result[result]}) print(\n 参考来源 ) for i, doc in enumerate(result[source_documents]): print(f[片段{i1}]: {doc.page_content[:200]}...) # 打印前200字符 return result if __name__ __main__: # 接上一部分代码 qa_chain create_rag_chain(vectordb) # 示例问题 ask_question(qa_chain, 这款产品的主要特性是什么) ask_question(qa_chain, 如何安装该产品)运行与验证 在终端执行python main.py。你会看到文档加载、分割、向量化的过程最后模型会基于你上传的PDF内容回答问题并打印出它参考了哪些原文片段。这验证了RAG的核心能力答案源于你的文档而非模型的固有知识。5. 项目实战二打造一个能调用工具的AI智能体Agent接下来我们升级复杂度构建一个能主动使用工具的Agent。场景一个旅游助手Agent它能查询天气、计算汇率。5.1 定义工具Tools工具是Agent能力的延伸。我们先定义两个简单的工具函数。# agent_tools.py import requests import json def get_weather(city: str) - str: 获取指定城市的天气信息。 # 注意这里使用一个模拟的天气API实际项目中请替换为真实API # 例如和风天气、OpenWeatherMap等 weather_data { 北京: 晴15~25℃微风, 上海: 多云18~28℃东南风3级, 广州: 阵雨23~32℃南风4级, } return weather_data.get(city, f未找到{city}的天气信息。) def currency_converter(amount: float, from_currency: str, to_currency: str) - str: 货币换算。 # 模拟汇率数据实际项目需接入实时汇率API exchange_rates { USD_CNY: 7.2, EUR_CNY: 7.8, JPY_CNY: 0.047, } key f{from_currency.upper()}_{to_currency.upper()} rate exchange_rates.get(key) if rate: converted amount * rate return f{amount} {from_currency.upper()} {converted:.2f} {to_currency.upper()} (汇率: {rate}) else: return f不支持{from_currency}到{to_currency}的换算。 # 为了被LangChain识别需要将函数包装成Tool对象 from langchain.tools import Tool weather_tool Tool( nameget_weather, funcget_weather, description根据城市名称查询天气。输入应为一个城市名例如‘北京’。 ) currency_tool Tool( namecurrency_converter, funccurrency_converter, description进行货币换算。输入应为三个参数用逗号分隔金额、原货币代码、目标货币代码。例如‘100, usd, cny’。 )5.2 构建ReAct智能体ReActReasoning Acting是Agent的经典范式。我们使用LangChain的create_react_agent来构建。# main_agent.py from langchain import hub from langchain.agents import create_react_agent, AgentExecutor from langchain_openai import ChatOpenAI from agent_tools import weather_tool, currency_tool # 导入刚才定义的工具 def create_travel_agent(): 创建旅游助手智能体 # 1. 定义LLM llm ChatOpenAI(modelgpt-3.5-turbo, temperature0, openai_api_keyOPENAI_API_KEY) # 2. 定义工具列表 tools [weather_tool, currency_tool] # 3. 从LangChain Hub获取一个预设的ReAct提示词模板 # 这个模板会指导模型进行“思考-行动-观察”的循环 prompt hub.pull(hwchase17/react) # 4. 创建Agent agent create_react_agent(llm, tools, prompt) # 5. 创建Agent执行器它负责运行循环处理工具调用 agent_executor AgentExecutor( agentagent, toolstools, verboseTrue, # 强烈建议开启可以看到Agent的思考过程 handle_parsing_errorsTrue, # 优雅处理解析错误 max_iterations5, # 限制最大迭代次数防止死循环 early_stopping_methodgenerate # 当Agent认为任务完成时停止 ) return agent_executor def run_agent_demo(): agent create_travel_agent() questions [ 北京和上海的天气怎么样, 100美元能换多少人民币然后再告诉我北京的天气。, 帮我计算一下500欧元兑换成日元是多少 # 这个会失败因为我们没定义EUR_JPY汇率 ] for q in questions: print(f\n{*50}) print(f用户: {q}) print(f{*50}) try: result agent.invoke({input: q}) print(f助手: {result[output]}) except Exception as e: print(f执行出错: {e}) if __name__ __main__: run_agent_demo()运行与观察 执行python main_agent.py。开启verboseTrue后你会在控制台看到类似以下的精彩输出 Entering new AgentExecutor chain... 我需要先查询北京的天气再查询上海的天气。 Action: get_weather Action Input: 北京 Observation: 晴15~25℃微风 Thought: 现在查询上海的天气。 Action: get_weather Action Input: 上海 Observation: 多云18~28℃东南风3级 Thought: 我已经获得了两个城市的天气信息可以给出最终答案了。 Final Answer: 北京天气晴15~25℃微风。上海天气多云18~28℃东南风3级。这就是Agent在“思考”。它自动将复杂问题分解为多个工具调用步骤并整合结果。这比单纯调用一次大模型强大得多。6. 进阶整合构建一个兼具RAG与Agent能力的综合应用现在我们将前两个项目结合起来打造一个“超级助手”它能回答基于知识库的问题RAG也能执行外部工具操作Agent。架构图如下用户提问 | v [智能路由] | |-- 如果是关于知识库的问题 -- [RAG流程] -- 答案 | |-- 如果是需要执行任务的问题 -- [Agent流程] -- 答案 | v 最终回复6.1 实现智能路由我们用一个简单的LLM来判断用户意图。# hybrid_assistant.py from langchain.prompts import ChatPromptTemplate from langchain_openai import ChatOpenAI from enum import Enum class Intent(Enum): 用户意图枚举 KNOWLEDGE_QA knowledge_qa # 知识库问答 TOOL_CALL tool_call # 需要调用工具 CHITCHAT chitchat # 闲聊 def route_intent(user_query: str, llm) - Intent: 判断用户查询意图 prompt_template ChatPromptTemplate.from_messages([ (system, 你是一个意图分类器。请根据用户问题判断其属于以下哪一类\n 1. knowledge_qa: 问题涉及公司产品、文档、手册等具体知识需要从知识库中查找答案。\n 2. tool_call: 问题需要执行具体操作如查询天气、计算、搜索等。\n 3. chitchat: 普通问候、闲聊或无法归入以上两类的问题。\n 只返回类别名称不要任何解释。), (human, {query}) ]) chain prompt_template | llm # 使用LangChain表达式语法 response chain.invoke({query: user_query}).content.strip().lower() # 根据返回文本映射到Intent枚举 if knowledge_qa in response: return Intent.KNOWLEDGE_QA elif tool_call in response: return Intent.TOOL_CALL else: return Intent.CHITCHAT def create_hybrid_assistant(rag_chain, agent_executor): 创建混合助手 llm ChatOpenAI(modelgpt-3.5-turbo, temperature0, openai_api_keyOPENAI_API_KEY) def assistant(query: str) - str: intent route_intent(query, llm) print(f[路由结果] 意图: {intent.value}) if intent Intent.KNOWLEDGE_QA: # 走RAG流程 result rag_chain.invoke({query: query}) return result[result] elif intent Intent.TOOL_CALL: # 走Agent流程 result agent_executor.invoke({input: query}) return result[output] else: # 闲聊直接让LLM回答 response llm.invoke(f用户说: {query}。请进行友好、简短的回复。) return response.content return assistant if __name__ __main__: # 假设我们已经有了之前创建的 rag_chain 和 agent_executor # from main import create_rag_chain # from main_agent import create_travel_agent # rag_chain create_rag_chain(...) # agent create_travel_agent() # 创建混合助手 assistant create_hybrid_assistant(rag_chain, agent) test_queries [ 我们产品保修期是多久, # 应触发RAG 明天杭州的天气怎么样, # 应触发Agent工具调用 你好介绍一下你自己。, # 应触发闲聊 100欧元换人民币然后告诉我今天北京天气。 # 应触发Agent多工具 ] for q in test_queries: print(f\n用户: {q}) answer assistant(q) print(f助手: {answer})这个架构的优点是清晰、可扩展。你可以很容易地添加新的意图如“数据查询”、“流程审批”和对应的处理模块。7. 部署与上线从脚本到可访问的Web服务一个本地运行的脚本价值有限。我们需要将其部署为Web服务。这里使用轻量级的Gradio快速构建界面。7.1 使用Gradio构建Web界面# app.py import gradio as gr from hybrid_assistant import create_hybrid_assistant # 假设你的RAG和Agent初始化代码在一个初始化函数里 from project_init import initialize_components # 初始化所有组件RAG链、Agent等 print(正在初始化系统组件可能需要一些时间...) rag_chain, agent_executor initialize_components() assistant create_hybrid_assistant(rag_chain, agent_executor) print(系统初始化完成) def chat_with_assistant(message, history): Gradio聊天函数 history history or [] # history格式: [[user_msg, assistant_msg], ...] response assistant(message) # 将本次交互加入历史 history.append((message, response)) return , history # 返回空消息清空输入框和更新后的历史 # 构建Gradio界面 with gr.Blocks(titleAI全能助手 (RAGAgent), themegr.themes.Soft()) as demo: gr.Markdown(# AI全能助手) gr.Markdown(这是一个融合了知识库问答(RAG)和工具调用(Agent)的智能助手。你可以问关于产品文档的问题也可以让它查天气、算汇率。) chatbot gr.Chatbot(label对话历史, height400) msg gr.Textbox(label请输入您的问题, placeholder例如产品特性是什么或者北京天气怎么样) clear gr.Button(清空对话) # 设置提交动作 msg.submit( chat_with_assistant, inputs[msg, chatbot], outputs[msg, chatbot] ) clear.click(lambda: None, None, chatbot, queueFalse) if __name__ __main__: # 本地启动服务器运行在 http://127.0.0.1:7860 demo.launch(server_name0.0.0.0, server_port7860, shareFalse) # shareTrue可生成临时公网链接运行python app.py打开浏览器访问http://127.0.0.1:7860你就拥有了一个功能完整的AI助手Web应用。7.2 生产环境部署考虑对于真实项目Gradio可能过于简单你需要考虑后端API化使用FastAPI或Flask将核心逻辑封装成API前后端分离。异步处理对于耗时的RAG检索或工具调用使用asyncio避免阻塞。会话管理引入session或数据库来管理多轮对话状态。向量数据库升级将Chroma替换为Qdrant、Weaviate或Pinecone等支持生产环境的向量数据库。缓存对常见查询结果进行缓存降低LLM API调用成本和延迟。监控与日志记录用户查询、模型响应、Token使用量便于分析和优化。8. 避坑指南大模型应用开发中的常见问题与解决方案在实际开发中你会遇到各种问题。以下是一些高频“坑点”及解决方案。问题现象可能原因排查方式解决方案RAG回答“我不知道”或胡编乱造1. 检索到的文档不相关。2. chunk_size设置不当。3. 提示词未要求模型基于上下文回答。1. 检查source_documents看检索到的文本是否与问题相关。2. 调整文本分割参数。3. 检查提示词模板。1. 优化检索器尝试不同的search_type(如mmr)。2. 调整chunk_size和chunk_overlap。3. 在提示词中强约束请严格根据以下上下文回答如果上下文没有提到请直接说“根据已知信息无法回答”。Agent陷入死循环不停调用工具Agent无法自行判断任务何时完成。观察verbose日志看Agent的“Thought”是否在重复。1. 设置max_iterations(如5-10)。2. 优化工具的描述(description)使其更精确。3. 使用更强大的模型如GPT-4作为Agent的“大脑”。处理长文档时内存溢出或速度极慢1. 嵌入模型在CPU上运行。2. 一次性加载所有文档。3. 未使用持久化向量库。监控任务管理器的内存和CPU使用情况。1. 使用GPU运行嵌入模型 (model_kwargs{device: cuda})。2. 对于超长文档分批处理。3. 向量库创建后持久化后续直接加载无需重复计算。回答包含敏感信息或格式混乱模型自由度过高未进行输出格式化。检查模型返回的原始内容。1. 降低temperature(如0.1)。2. 在提示词中指定输出格式例如“请用列表形式总结”或“请输出JSON”。3. 使用LangChain的OutputParser进行后处理。国内无法访问OpenAI API网络限制。测试API连通性。1. 切换为国内合规大模型API阿里通义、智谱GLM、百度文心等。2. 使用LangChain的集成只需更换API Key和base_url。切换国内模型的示例from langchain_openai import ChatOpenAI # 使用阿里通义千问 llm ChatOpenAI( modelqwen-plus, # 或其他qwen模型 openai_api_keyyour-dashscope-api-key, openai_api_basehttps://dashscope.aliyuncs.com/compatible-mode/v1, # 兼容OpenAI的端点 ) # 智谱GLM、百度文心等也有类似的兼容方式具体查看LangChain文档。9. 最佳实践与项目优化建议遵循这些实践能让你的项目更健壮、更易维护。配置与密钥管理永远使用.env文件和环境变量管理密钥。将.env加入.gitignore避免密钥泄露。版本锁定使用requirements.txt或poetry精确锁定依赖版本确保团队环境一致。pip freeze requirements.txt结构化日志使用logging模块记录不同级别INFO, DEBUG, ERROR的日志便于调试和运维。超时与重试调用外部API或模型时务必设置超时和重试机制增强鲁棒性。from langchain.callbacks.manager import CallbackManagerForLLMRun # 许多LangChain LLM类支持 request_timeout 参数 llm ChatOpenAI(..., request_timeout60)成本监控记录每次调用的Token消耗尤其是使用按Token计费的云服务时。OpenAI等提供商有使用量仪表盘。测试驱动为你的RAG检索逻辑、工具函数、Agent决策流程编写单元测试。渐进式复杂度不要一开始就追求完美架构。先从最简单的管道跑通然后逐步添加RAG、Agent、路由等模块。提示词工程提示词是“编程”大模型的主要方式。将其模板化、模块化并保存在单独的文件中如prompts/目录方便迭代优化。至此你已经完成了一个具备RAG和Agent能力的大模型应用从零到一的构建。这条路径涵盖了环境搭建、核心概念理解、两个核心项目实战、系统整合、Web部署以及避坑指南。接下来你可以基于这个框架接入更丰富的数据源数据库、Confluence、Notion、定义更强大的工具发送邮件、查询数据库、调用内部API并优化前端体验打造出真正满足业务需求的智能应用。