从Prompt工程到Agent开发:构建基于RAG与LangChain的AI应用实战指南

📅 2026/8/24 2:48:17
从Prompt工程到Agent开发:构建基于RAG与LangChain的AI应用实战指南
最近在尝试将大语言模型LLM应用到实际业务中时你是否也遇到过这些困惑模型回答天马行空无法基于你的私有数据给出准确答案想让模型调用外部工具或API却不知如何构建工作流面对复杂的微调任务感觉无从下手如果你正被这些问题困扰那么恭喜你这篇文章正是为你准备的。本文将系统性地拆解当前AI应用开发的核心技术栈涵盖从Prompt工程、LangChain框架、RAG知识库构建、MCP工具调用到大模型微调的完整路径。无论你是刚接触AI应用的新手还是希望系统提升工程化能力的中级开发者都能从中找到从理论到实践的清晰指引。我们将通过大量可运行的代码示例带你一步步构建起属于自己的智能体Agent应用。1. 背景与核心概念为什么需要这些技术在深入代码之前我们有必要理解这些技术各自解决了什么问题以及它们如何协同工作。大语言模型LLM的局限性以GPT、Claude、通义千问为代表的通用大模型虽然拥有强大的语言理解和生成能力但它们存在几个关键短板知识截止性模型训练数据有截止日期无法获取最新信息。缺乏领域专精对特定行业如医疗、法律、金融的深度知识掌握不足。“幻觉”问题可能生成看似合理但实际错误或虚构的内容。无法执行动作模型本身不能操作数据库、调用API或控制软件。为了克服这些限制一系列工程技术应运而生它们共同构成了现代AI应用开发的基石。核心概念解析Prompt提示词这是与LLM交互的“指令”或“问题”。Prompt工程的核心在于如何通过精心设计的文本输入引导模型产生更准确、更符合预期的输出。它是一切LLM应用的基础。RAG检索增强生成为了解决模型知识陈旧和专精度不足的问题RAG技术被提出。其核心思想是当用户提问时先从外部的知识库如向量数据库中检索出相关的文档片段然后将这些片段作为上下文连同原始问题一起提交给LLM。这样模型就能基于最新的、特定的知识来生成答案显著减少“幻觉”。LangChain一个用于开发由LLM驱动的应用程序的框架。它不是一个具体的应用而是一个“工具箱”和“脚手架”。LangChain通过提供标准化的接口、模块化的组件如模型I/O、记忆、链、代理和丰富的工具集成极大地简化了构建复杂LLM应用如RAG系统、智能代理的流程。你可以把它想象成AI应用开发的“Spring Framework”。Agent智能体一个能感知环境、进行决策并执行动作以完成目标的系统。在LLM语境下Agent通常指一个由LLM作为“大脑”的程序它可以调用工具如计算器、搜索引擎、API、访问记忆并通过多轮推理和规划来完成任务。LangChain是构建Agent的流行框架之一。MCP模型上下文协议这是一个由Anthropic提出的新兴协议旨在标准化LLM与外部工具、数据源之间的交互方式。它定义了工具的描述、调用和结果返回格式。使用MCP开发者可以更方便地为LLM集成各种能力而模型提供商如Claude也能更安全、可控地支持工具调用。你可以把它看作LLM工具调用的“USB标准接口”。大模型微调指使用特定领域的数据集在预训练好的大模型基础上进行额外的训练使模型适应特定任务或领域。微调后的模型在相关任务上的表现会显著提升。根据计算资源和数据量的不同微调方式包括全参数微调、LoRA、QLoRA等。它们之间的关系一个典型的AI应用开发流程可能是这样的你首先需要编写有效的Prompt与模型沟通为了给模型注入特定知识你需要构建一个RAG系统为了管理复杂的对话状态、工具调用链你使用LangChain框架来组织代码为了让你的应用能主动执行任务如发邮件、查数据你将其设计成Agent并为其配备工具为了更规范、安全地集成工具你可以考虑采用MCP协议最后如果通用模型在核心任务上仍不满足要求你可以收集数据对模型进行微调获得一个专属模型。2. 环境准备与版本说明在开始实战之前我们需要搭建一个统一的Python开发环境。本文示例将主要使用Python和相关的AI库。基础环境操作系统Windows 10/11, macOS, 或 Linux (Ubuntu 20.04)。本文命令以macOS/Linux的bash和Windows的PowerShell为例。Python版本推荐使用Python 3.10或3.11。这是目前大多数AI库兼容性最好的版本。避免使用Python 3.12因为部分库的适配可能还不完善。包管理工具使用pip进行包安装。强烈建议使用虚拟环境如venv或conda来隔离项目依赖。核心库及版本示例 以下版本为撰写本文时的稳定版本实际开发时请根据官方文档调整。# 创建并激活虚拟环境 (以venv为例) python -m venv ai_agent_env # Windows ai_agent_env\Scripts\activate # macOS/Linux source ai_agent_env/bin/activate # 安装核心库 pip install langchain0.1.0 pip install langchain-community0.0.10 # 社区贡献的组件 pip install langchain-openai0.0.5 # OpenAI模型集成 pip install openai1.12.0 # 用于RAG的向量数据库和文本处理 pip install chromadb0.4.22 # 轻量级向量数据库 pip install sentence-transformers2.2.2 # 用于生成文本向量的嵌入模型 pip install pypdf3.17.4 # 用于读取PDF文档 pip install tiktoken0.5.2 # OpenAI的Tokenizer # 可选用于Web应用演示 pip install streamlit1.29.0 pip install flask3.0.0 # 可选用于大模型微调需要GPU # pip install transformers4.37.2 # pip install peft0.8.2 # pip install accelerate0.26.1 # pip install datasets2.16.1 # pip install trl0.7.10API密钥准备 本文部分示例需要调用云端LLM API你需要提前申请并设置环境变量。OpenAI访问 platform.openai.com 获取API Key。其他模型如通义千问、DeepSeek等请参考各自平台文档。设置环境变量Linux/macOSexport OPENAI_API_KEY你的-api-key设置环境变量Windows PowerShell$env:OPENAI_API_KEY你的-api-key项目结构建议ai_agent_course/ ├── 01_prompt_engineering/ │ ├── basic_prompt.py │ └── few_shot.py ├── 02_rag_system/ │ ├── data/ │ │ └── your_document.pdf │ ├── vector_store.py │ └── query_chain.py ├── 03_langchain_agent/ │ ├── tools/ │ │ └── custom_tool.py │ └── agent_executor.py ├── 04_mcp_demo/ # MCP示例概念性 │ └── simple_server.py ├── 05_fine_tuning/ # 微调示例需GPU │ ├── dataset.jsonl │ └── lora_finetune.py ├── requirements.txt └── README.md3. 核心语法、配置与原理拆解3.1 Prompt工程从基础到高级技巧Prompt是与模型沟通的桥梁其质量直接决定输出结果。基础Prompt# 文件01_prompt_engineering/basic_prompt.py from langchain_openai import ChatOpenAI llm ChatOpenAI(modelgpt-3.5-turbo) # 1. 直接提问零样本 simple_prompt 法国的首都是哪里 response llm.invoke(simple_prompt) print(f零样本回答: {response.content}) # 2. 指令式Prompt instruction_prompt 请将以下英文句子翻译成中文并确保翻译准确、流畅。 句子: The rapid development of artificial intelligence is reshaping various industries. response llm.invoke(instruction_prompt) print(f指令式回答: {response.content}) # 3. 角色扮演Prompt role_play_prompt 你是一位经验丰富的软件架构师。请用简洁的语言向一位刚入行的程序员解释什么是‘微服务架构’并列举其两个主要优点和两个潜在挑战。 response llm.invoke(role_play_prompt) print(f角色扮演回答: {response.content})少样本提示Few-Shot Prompting 当任务复杂或格式要求严格时提供几个例子能极大提升模型表现。# 文件01_prompt_engineering/few_shot.py from langchain_core.prompts import FewShotPromptTemplate, PromptTemplate from langchain_openai import ChatOpenAI llm ChatOpenAI(modelgpt-3.5-turbo) # 定义示例 examples [ { input: 这家餐厅的服务太差了上菜慢服务员态度也不好。, output: 负面 }, { input: 产品非常好用设计精美完全超出了我的预期, output: 正面 }, { input: 快递按时送达包装完好但产品本身有点小瑕疵。, output: 中性 } ] # 定义单个示例的格式 example_prompt PromptTemplate( input_variables[input, output], template输入: {input}\n情感: {output} ) # 创建FewShotPromptTemplate few_shot_prompt FewShotPromptTemplate( examplesexamples, example_promptexample_prompt, prefix请根据以下示例判断后续输入文本的情感倾向正面、负面、中性。, suffix输入: {user_input}\n情感:, input_variables[user_input], example_separator\n\n ) # 使用 formatted_prompt few_shot_prompt.format(user_input这部电影的剧情一般但特效非常震撼。) response llm.invoke(formatted_prompt) print(f少样本提示结果: {response.content}) # 预期输出: 中性高级技巧思维链Chain-of-Thought 通过引导模型“一步一步思考”可以解决复杂的数学或逻辑推理问题。cot_prompt 问题一个篮子里有15个苹果。你拿走了3个然后又放回去5个。现在篮子里有多少个苹果 让我们一步一步地思考 1. 最初有15个苹果。 2. 拿走3个后剩下 15 - 3 12 个苹果。 3. 又放回去5个现在有 12 5 17 个苹果。 所以答案是17。 现在请回答下面的问题 问题书店第一周卖了120本书第二周比第一周多卖了30本第三周卖的是第二周的一半。这三周总共卖了多少本书 请按照上面的格式一步一步思考。 response llm.invoke(cot_prompt) print(f思维链回答:\n{response.content})3.2 RAG系统原理与核心组件RAG系统通常包含以下步骤文档加载 - 文本分割 - 向量化嵌入- 存储到向量数据库 - 检索 - 生成。1. 文档加载与分割# 文件02_rag_system/vector_store.py from langchain_community.document_loaders import PyPDFLoader from langchain.text_splitter import RecursiveCharacterTextSplitter # 1. 加载文档 (以PDF为例) loader PyPDFLoader(./data/your_document.pdf) # 请替换为你的PDF文件路径 documents loader.load() print(f加载了 {len(documents)} 页文档。) # 2. 分割文本 # 大模型有上下文长度限制需要将长文档切分成小块chunks。 text_splitter RecursiveCharacterTextSplitter( chunk_size500, # 每个块的最大字符数 chunk_overlap50, # 块之间的重叠字符避免语义断裂 separators[\n\n, \n, 。, , , , , , ] # 分割符优先级 ) chunks text_splitter.split_documents(documents) print(f文档被分割成 {len(chunks)} 个文本块。) print(f第一个块的内容预览: {chunks[0].page_content[:200]}...)2. 向量化与存储 文本块需要被转换成数值向量嵌入才能进行相似度计算。from langchain_openai import OpenAIEmbeddings from langchain_community.vectorstores import Chroma # 3. 创建嵌入模型 (这里使用OpenAI的嵌入模型需要API Key) # 也可以使用本地模型如 sentence-transformers embeddings OpenAIEmbeddings(modeltext-embedding-3-small) # 4. 创建向量数据库并存储向量 # persist_directory 指定向量数据库的持久化目录 vector_store Chroma.from_documents( documentschunks, embeddingembeddings, persist_directory./chroma_db # 数据将保存到此目录 ) vector_store.persist() # 持久化到磁盘 print(向量数据库已创建并持久化。)3. 检索与生成 当用户提问时从向量库中检索最相关的文本块并将其作为上下文提供给LLM。# 文件02_rag_system/query_chain.py from langchain.chains import RetrievalQA from langchain_openai import ChatOpenAI from langchain_community.vectorstores import Chroma from langchain_openai import OpenAIEmbeddings # 1. 加载已保存的向量数据库 embeddings OpenAIEmbeddings() vector_store Chroma( persist_directory./chroma_db, embedding_functionembeddings ) # 2. 创建检索器 retriever vector_store.as_retriever( search_typesimilarity, # 相似度搜索 search_kwargs{k: 3} # 返回最相关的3个块 ) # 3. 创建LLM llm ChatOpenAI(modelgpt-3.5-turbo, temperature0) # 4. 创建检索增强生成链 qa_chain RetrievalQA.from_chain_type( llmllm, chain_typestuff, # 将检索到的所有文档“塞”进上下文 retrieverretriever, return_source_documentsTrue # 返回源文档便于溯源 ) # 5. 提问 query 文档中主要讨论了哪些AI技术 result qa_chain.invoke({query: query}) print(f问题: {query}) print(f答案: {result[result]}) print(\n--- 参考来源 ---) for i, doc in enumerate(result[source_documents][:2]): # 显示前两个来源 print(f[来源{i1}]: {doc.page_content[:150]}...)通过以上步骤我们就构建了一个最基本的RAG系统。模型在回答时会优先使用从你的文档中检索到的信息从而生成更准确、更相关的答案。3.3 LangChain Agent的核心工具、记忆与执行链Agent的核心思想是让LLM学会使用工具。在LangChain中一个简单的Agent由以下几部分组成工具ToolsAgent可以调用的函数如计算器、搜索引擎、数据库查询。LLM作为决策的“大脑”。Agent执行器Agent Executor负责运行Agent处理LLM的思考、工具调用和结果整合。定义一个自定义工具# 文件03_langchain_agent/tools/custom_tool.py from langchain.tools import tool from datetime import datetime tool def get_current_time(format: str %Y-%m-%d %H:%M:%S) - str: 获取当前的日期和时间。可以指定格式默认是‘年-月-日 时:分:秒’。 now datetime.now() return now.strftime(format) tool def calculate_bmi(weight_kg: float, height_m: float) - dict: 计算身体质量指数BMI。输入体重公斤和身高米。 bmi weight_kg / (height_m ** 2) category 偏瘦 if bmi 28: category 肥胖 elif bmi 24: category 超重 elif bmi 18.5: category 正常 return {bmi: round(bmi, 2), category: category} # 工具列表 tools [get_current_time, calculate_bmi]创建并运行一个简单的Agent# 文件03_langchain_agent/agent_executor.py from langchain.agents import create_react_agent, AgentExecutor from langchain_openai import ChatOpenAI from langchain import hub from tools.custom_tool import get_current_time, calculate_bmi # 1. 加载一个预设的PromptReAct框架 prompt hub.pull(hwchase17/react) # 2. 创建LLM llm ChatOpenAI(modelgpt-3.5-turbo, temperature0) # 3. 定义工具 tools [get_current_time, calculate_bmi] # 4. 创建Agent agent create_react_agent(llm, tools, prompt) # 5. 创建执行器 agent_executor AgentExecutor( agentagent, toolstools, verboseTrue, # 打印详细的思考过程 handle_parsing_errorsTrue # 处理解析错误 ) # 6. 运行Agent question 我现在体重70公斤身高1.75米我的BMI是多少另外请告诉我现在的时间。 result agent_executor.invoke({input: question}) print(f\n最终答案: {result[output]})运行上述代码你会看到Agent的详细思考过程verboseTrueThought思考模型分析问题识别出需要调用calculate_bmi和get_current_time两个工具。Action行动模型生成工具调用的指令如calculate_bmi的参数。Observation观察工具执行后返回的结果如BMI值和时间。模型根据观察结果最终合成一个完整的答案输出。这就是LangChain Agent的基本工作原理。通过组合不同的工具和Prompt可以构建出能完成复杂工作流的智能应用。3.4 MCP协议初探MCPModel Context Protocol是一个较新的协议旨在为LLM提供一个标准化、安全的方式来访问外部工具和数据源。它类似于一个“驱动程序”模型让模型供应商如Anthropic的Claude无需为每个工具编写特定代码只需实现MCP客户端就能连接任何符合MCP协议的服务器提供工具。核心概念MCP Server提供工具和数据源的服务器。例如一个提供天气查询、数据库连接或代码执行的服务器。MCP ClientLLM应用如Claude Desktop中实现的客户端用于与MCP Server通信。工具ToolsServer向Client注册的可调用功能。资源ResourcesServer提供的可读数据源如文件、数据库表视图。一个简单的MCP Server示例概念性 目前MCP的Python SDK还在快速发展中以下代码展示了其核心思想。# 文件04_mcp_demo/simple_server.py (概念示例) # 注此为示意代码实际开发请参考官方MCP SDK。 import asyncio from mcp import Server, Tool # 1. 定义一个工具 Tool async def get_weather(city: str) - str: 获取指定城市的当前天气。 # 这里模拟一个API调用 weather_data { 北京: 晴15°C, 上海: 多云18°C, 深圳: 阵雨22°C } return weather_data.get(city, f未找到{city}的天气信息。) # 2. 创建MCP Server async def main(): server Server(my-weather-server) # 3. 向Server注册工具 server.register_tool(get_weather) # 4. 启动Server (例如通过Stdio与Client通信) async with server.run_over_stdio() as (read_stream, write_stream): # ... 处理与Client的通信 print(MCP Server 已启动等待Client连接...) await asyncio.Future() # 保持运行 if __name__ __main__: asyncio.run(main())对于应用开发者MCP的价值在于未来你可以编写一次MCP Server然后任何支持MCP的LLM客户端如Claude Desktop、Cursor等都能直接使用你提供的工具无需为每个客户端做适配。3.5 大模型微调概览LoRA与QLoRA全参数微调需要巨大的计算资源。LoRALow-Rank Adaptation和QLoRAQuantized LoRA是两种高效的微调技术。原理简述LoRA在原始大模型的权重旁添加一组低秩的“适配器”权重。在微调时只训练这些新增的小参数而冻结原始的大模型参数。这极大地减少了训练参数量和显存占用。QLoRA在LoRA的基础上更进一步将原始大模型的权重量化为4-bit而通常模型是16-bit或32-bit从而在微调时占用更少的显存使得在消费级GPU上微调大模型成为可能。一个使用PEFTParameter-Efficient Fine-Tuning库进行LoRA微调的简化流程# 文件05_fine_tuning/lora_finetune.py (简化流程实际运行需准备数据和GPU) # 以下代码展示了核心步骤无法直接运行。 from transformers import AutoModelForCausalLM, AutoTokenizer, TrainingArguments from peft import LoraConfig, get_peft_model, TaskType from trl import SFTTrainer import torch # 1. 加载基础模型和分词器 model_name Qwen/Qwen2-7B-Instruct # 示例模型 model AutoModelForCausalLM.from_pretrained( model_name, torch_dtypetorch.bfloat16, device_mapauto ) tokenizer AutoTokenizer.from_pretrained(model_name) tokenizer.pad_token tokenizer.eos_token # 设置填充token # 2. 配置LoRA lora_config LoraConfig( task_typeTaskType.CAUSAL_LM, # 因果语言模型任务 r8, # LoRA的秩rank越小参数量越少 lora_alpha32, # 缩放参数 lora_dropout0.1, target_modules[q_proj, v_proj] # 对Transformer的哪些层应用LoRA ) # 3. 将基础模型转换为PEFT模型仅LoRA参数可训练 model get_peft_model(model, lora_config) model.print_trainable_parameters() # 打印可训练参数量会发现远小于总参数量 # 4. 准备训练数据 (需要格式化为对话或指令格式) # dataset load_dataset(json, data_filesdataset.jsonl) # 5. 配置训练参数 training_args TrainingArguments( output_dir./lora_finetuned_model, per_device_train_batch_size4, gradient_accumulation_steps4, num_train_epochs3, logging_steps10, save_steps100, learning_rate2e-4, fp16True, # 混合精度训练节省显存 ) # 6. 创建Trainer并开始训练 # trainer SFTTrainer( # modelmodel, # argstraining_args, # train_datasetdataset, # tokenizertokenizer, # ) # trainer.train() # model.save_pretrained(./final_lora_model)微调是一个系统工程涉及数据准备、格式转换、超参数调优、评估等多个环节。QLoRA的流程类似但需要在加载模型时进行量化配置。对于大多数开发者如果云端API能满足需求优先使用RAG和Prompt工程当对模型行为有非常定制化、且数据充足时再考虑微调。4. 完整实战案例构建一个智能技术问答助手现在我们将综合运用以上技术构建一个能回答特定技术领域例如“LangChain”问题的智能助手。该助手具备以下能力基于本地知识库RAG回答关于LangChain的问题。能调用工具获取实时信息如当前时间。以连贯的对话形式与用户交互记忆功能。4.1 项目结构与数据准备创建项目文件夹tech_qa_assistant。tech_qa_assistant/ ├── data/ │ └── langchain_docs.txt # 放置一些LangChain的官方文档片段 ├── tools/ │ └── custom_tools.py ├── vector_store.py ├── agent_setup.py ├── app.py # 主应用入口 (使用Streamlit) └── requirements.txt在data/langchain_docs.txt中放入一些文本例如LangChain是一个用于开发由语言模型驱动的应用程序的框架。 它使应用程序能够1. 具有上下文感知能力将语言模型与上下文源连接起来。2. 具有推理能力允许语言模型与其环境进行交互。 LangChain的主要价值在于1. 组件化为使用语言模型提供抽象层。2. 链式调用将组件组合成链完成复杂任务。 Agent是LangChain中的核心概念它使用语言模型作为推理引擎来决定采取哪些行动以及以何种顺序进行。4.2 构建知识库向量数据库# 文件vector_store.py from langchain_community.document_loaders import TextLoader from langchain.text_splitter import RecursiveCharacterTextSplitter from langchain_openai import OpenAIEmbeddings from langchain_community.vectorstores import Chroma import os def create_and_save_vector_store(): 创建并持久化向量数据库 # 1. 加载文档 loader TextLoader(./data/langchain_docs.txt, encodingutf-8) documents loader.load() # 2. 分割文本 text_splitter RecursiveCharacterTextSplitter( chunk_size300, chunk_overlap50, separators[\n\n, \n, 。, , , , , , ] ) chunks text_splitter.split_documents(documents) print(f创建了 {len(chunks)} 个文本块。) # 3. 创建向量存储 embeddings OpenAIEmbeddings() vector_store Chroma.from_documents( documentschunks, embeddingembeddings, persist_directory./chroma_db_tech ) vector_store.persist() print(向量数据库已保存至 ./chroma_db_tech) if __name__ __main__: create_and_save_vector_store()运行python vector_store.py来生成向量数据库。4.3 定义工具和检索器# 文件tools/custom_tools.py from langchain.tools import tool from datetime import datetime from langchain_community.vectorstores import Chroma from langchain_openai import OpenAIEmbeddings tool def get_current_time() - str: 获取当前的日期和时间格式为‘年-月-日 时:分:秒’。 now datetime.now() return now.strftime(%Y-%m-%d %H:%M:%S) tool def search_knowledge_base(query: str) - str: 从技术知识库中搜索与问题相关的信息。 当用户询问关于LangChain、RAG、Agent等技术概念时使用此工具。 # 加载之前创建的向量数据库 embeddings OpenAIEmbeddings() vector_store Chroma( persist_directory./chroma_db_tech, embedding_functionembeddings ) # 检索最相关的3个片段 docs vector_store.similarity_search(query, k3) if not docs: return 知识库中未找到相关信息。 # 将检索到的内容合并成一个字符串返回 context \n\n.join([doc.page_content for doc in docs]) return f从知识库中检索到以下相关信息\n{context}4.4 创建具有记忆和知识库检索能力的Agent# 文件agent_setup.py from langchain.agents import AgentExecutor, create_react_agent from langchain_openai import ChatOpenAI from langchain.memory import ConversationBufferMemory from langchain import hub from tools.custom_tools import get_current_time, search_knowledge_base def create_tech_agent(): 创建并返回一个配置好的Agent执行器 # 1. 加载LLM llm ChatOpenAI(modelgpt-3.5-turbo, temperature0) # 2. 定义工具 tools [get_current_time, search_knowledge_base] # 3. 创建对话记忆 memory ConversationBufferMemory( memory_keychat_history, return_messagesTrue, output_keyoutput ) # 4. 加载ReAct Prompt模板并注入关于工具使用的指令 prompt_template hub.pull(hwchase17/react) # 自定义系统指令告诉Agent优先使用知识库 custom_instructions 你是一个技术问答助手专门回答关于LangChain、RAG、Agent等AI开发技术的问题。 请遵循以下规则 1. 当用户询问技术概念、用法或原理时你必须先调用 search_knowledge_base 工具从知识库中查找信息。 2. 结合工具返回的知识和你的理解来回答问题。 3. 如果知识库中没有相关信息请基于你的通用知识诚实回答并说明这一点。 4. 对于非技术问题如问候、时间请直接回答或使用相应工具。 prompt_template.messages[0].prompt.template custom_instructions prompt_template.messages[0].prompt.template # 5. 创建Agent agent create_react_agent(llm, tools, prompt_template) # 6. 创建Agent执行器并注入记忆 agent_executor AgentExecutor( agentagent, toolstools, memorymemory, verboseTrue, # 生产环境可设为False handle_parsing_errorsTrue, max_iterations5, # 限制最大迭代次数防止死循环 early_stopping_methodgenerate # 当Agent认为任务完成时停止 ) return agent_executor if __name__ __main__: # 测试Agent agent create_tech_agent() questions [ LangChain是什么, 现在几点了, Agent在LangChain中起什么作用 ] for q in questions: print(f\n用户: {q}) result agent.invoke({input: q}) print(f助手: {result[output]}) print(- * 50)运行python agent_setup.py你会看到Agent的完整思考过程对于技术问题它会先调用search_knowledge_base对于时间问题它会调用get_current_time。4.5 构建Web交互界面使用Streamlit# 文件app.py import streamlit as st from agent_setup import create_tech_agent st.set_page_config(page_title技术问答助手, page_icon) st.title( 智能技术问答助手) st.caption(基于LangChain RAG Agent构建可以回答LangChain相关技术问题并获取实时信息。) # 初始化Session State if agent not in st.session_state: with st.spinner(正在初始化AI助手...): st.session_state.agent create_tech_agent() st.session_state.messages [] # 显示历史对话 for message in st.session_state.messages: with st.chat_message(message[role]): st.markdown(message[content]) # 用户输入 if prompt : st.chat_input(请输入您的问题...): # 添加用户消息 st.session_state.messages.append({role: user, content: prompt}) with st.chat_message(user): st.markdown(prompt) # 获取助手回复 with st.chat_message(assistant): with st.spinner(思考中...): response st.session_state.agent.invoke({input: prompt}) answer response[output] st.markdown(answer) # 添加助手消息 st.session_state.messages.append({role: assistant, content: answer})运行streamlit run app.py一个具有记忆和知识库检索能力的Web版智能助手就启动了。你可以在浏览器中与它对话它会结合本地知识库和工具调用来回答你。5. 常见问题与排查思路在开发AI应用过程中你一定会遇到各种问题。下面是一些高频问题及其解决方案。问题现象可能原因排查思路与解决方案ModuleNotFoundError: No module named ‘langchain’1. 未安装LangChain。2. 虚拟环境未激活。3. 存在多个Python环境pip安装到了错误的环境。1. 确认虚拟环境已激活命令行前缀有(env_name)。2. 运行 pip listInvalidRequestError: ... This model’s maximum context length is ...输入给模型的文本Prompt 上下文超过了模型的最大上下文长度限制。1. 检查RAG中检索的文本块是否过大调整chunk_size。2. 使用stuff之外的链类型如map_reduce或refine它们能处理更长的文档。3. 精简Prompt移除不必要的指令。Agent陷入循环不停调用同一个工具1. Agent的停止条件不明确。2. 工具返回的结果未能让Agent判断任务已完成。3.max_iterations设置过大。1. 在Prompt中明确告诉Agent“在得到答案后用最终答案来结束对话”。2. 检查工具返回的格式是否清晰、易于理解。3. 设置合理的max_iterations如3-5并启用early_stopping_method。向量检索结果不相关1. 文本分割策略不佳导致语义断裂。2. 嵌入模型不适合当前语料如中文用英文模型。3. 检索的top-k值不合适。1. 调整chunk_size和chunk_overlap尝试按句子或段落分割。2. 尝试不同的嵌入模型如text-embedding-ada-002、bge-large-zh中文。3. 调整search_kwargs{“k”: 4}增加或减少检索数量。Invalid prompt: your prompt was flagged...Prompt内容被AI服务商的安全策略判定为潜在违规。1.这是最常见的问题之一。避免在Prompt中包含任何涉及暴力、歧视、违法、侵犯隐私等内容。2. 检查是否无意中让模型生成或总结敏感内容。3. 将长Prompt拆解或使用更委婉的表述。4. 如果是在测试尝试更换问题或使用不同的模型。微调时GPU内存不足CUDA out of memory1. 模型太大。2. 批次大小batch size太大。3. 未使用梯度累积或混合精度训练。1. 使用更小的模型或使用QLoRA进行4-bit量化。2. 减小per_device_train_batch_size。3. 增加gradient_accumulation_steps等效增大批次大小但不增加显存。4. 启用FP16混合精度训练 (fp16True)。Agent执行速度慢1. 网络延迟调用云端API。2. 工具本身执行慢如查询大型数据库。3. Agent进行了多次不必要的工具调用。1. 考虑使用本地模型如通过Ollama部署以减少延迟。2. 优化工具函数增加缓存。3. 优化Prompt让Agent的决策更精准减少无效调用。6. 最佳实践与工程建议将原型转化为稳定、可维护的生产级应用需要遵循一些工程最佳实践。1. 提示词Prompt工程化模板化不要将Prompt硬编码在代码中。使用LangChain的PromptTemplate或专门的文件如YAML、JSON来管理Prompt便于迭代和国际化。版本控制像管理代码一样管理重要的Prompt记录每次修改的原因和效果。测试与评估建立Prompt的测试集定期评估其在不同场景下的表现特别是边界情况。2. RAG系统优化分块策略没有“一刀切”的最佳分块大小。对于技术文档按章节或子标题分块可能比固定字符数更有效。可以尝试多种策略并评估检索质量。元数据过滤在存储向量时为每个块添加元数据如来源文件、章节标题、创建日期。检索时可以结合向量相似度和元数据过滤提高精度。重排序Re-ranking在初步检索出N个相关块后使用一个更小、更快的重排序模型对它们进行精排将最相关的1-2个块送给LLM可以提升答案质量并节省上下文窗口。来源引用务必在最终答案中注明信息来源如文档名称、页码这对于技术问答至关重要也方便用户溯源。3. Agent设计原则工具设计清晰每个工具应有明确、单一的功能输入输出类型定义清晰。工具的描述docstring要详细准确这是LLM决定是否调用该工具的主要依据。限制与超时为Agent设置max_iterations最大迭代次数和超时时间防止因逻辑错误或网络问题导致无限循环或长时间挂起。错误处理在Agent执行器中设置handle_parsing_errorsTrue并考虑在工具函数内部进行try-catch返回友好的错误信息供Agent处理。用户确认对于具有“写”操作或不可逆行为的工具如发送邮件、删除数据应在Agent流程中设计用户确认环节或让工具本身包含安全确认逻辑。4. 生产环境部署密钥管理永远不要将API密钥硬编码在代码或提交到版本库。使用环境变量、密钥管理服务如AWS Secrets Manager或配置文件并加入.gitignore。日志与监控记录详细的日志包括用户的输入、Agent的思考过程、工具调用详情、模型的输出以及最终响应。这对于调试、分析和优化至关重要。限流与降级对调用外部API如OpenAI的接口实施限流防止意外流量导致高额费用。设计降级策略例如当RAG检索失败时回退到通用模型回答并给出提示。可观测性考虑集成像LangSmith这样的LLM应用可观测性平台它可以跟踪链和Agent的每一步执行方便地进行性能分析、调试和成本核算。5. 安全与合规输入输出过滤对用户的输入和模型的输出进行必要的过滤和审查防止注入攻击、敏感信息泄露或生成有害内容。数据隐私如果使用云端LLM API需确认其数据隐私政策。处理用户私有数据时考虑使用本地部署的模型和嵌入模型。权限最小化为Agent配备的工具应遵循权限最小化原则。例如一个查询天气的Agent不需要数据库的写权限。掌握从Prompt工程、RAG、LangChain到Agent和微调的完整技术栈你已经具备了构建下一代AI应用的核心能力。这条路的学习曲线虽然陡峭但回报巨大。建议的学习路径是先从Prompt工程和LangChain基础入手构建简单的链然后深入RAG解决知识注入问题接着探索Agent赋予应用行动力在项目有深度定制需求时再研究微调。对于MCP可以保持关注待其生态更成熟时再接入。真正的掌握源于实践。建议你从克隆本文的示例代码开始替换成你自己的数据和API Key逐个模块运行、修改、调试。尝试用这些技术为你自己的工作或兴趣领域构建一个小工具比如个人知识库助手、自动化周报生成器或是智能客服原型。