在 AI 大模型技术快速迭代的背景下,开发者面临的核心挑战已不再是模型本身的训练,而是如何高效地将这些模型应用到实际业务中。Prompt 工程、AI Agent、RAG 框架以及像 Cursor 这样的智能编码工具,构成了当前大模型应用开发的核心技术栈。掌握这些工具和方法,意味着能够将前沿的 AI 能力转化为解决实际问题的生产力。
本文将以一个完整的项目实战为主线,手把手带你理解并实践从基础概念到项目落地的全过程。我们将从零开始,搭建一个基于 RAG 的企业知识库问答系统,并在此过程中深度集成 Prompt 工程、AI Agent 和 Cursor 工具的使用。无论你是希望入门 AI 应用开发,还是寻求将现有项目与 AI 能力结合,这篇文章都将提供一条清晰、可复现的路径。
1. 理解核心概念:Prompt、Agent、RAG 与 Cursor
在开始编码之前,必须清晰地理解我们将要使用的几个核心概念及其相互关系。它们不是孤立的技术点,而是一个协同工作的技术体系。
1.1 Prompt 工程:与模型对话的“编程语言”
Prompt 不是简单的提问,而是一种精心设计的指令,用于引导大模型生成符合预期的输出。可以把 Prompt 理解为一种面向大模型的“编程语言”。一个糟糕的 Prompt 会导致模型输出无关或低质量的内容,而一个优秀的 Prompt 则能激发模型的最佳性能。
Prompt 的核心要素:
- 角色设定:明确告诉模型它需要扮演的角色,例如“你是一名资深的 Java 架构师”。
- 任务描述:清晰、具体地说明需要模型完成的任务。
- 上下文信息:提供完成任务所需的背景知识或数据。
- 输出格式:明确规定模型输出的格式,如 JSON、Markdown、代码块等。
- 约束条件:设定规则,例如“不要使用高级库”、“代码不超过 50 行”。
示例:一个糟糕的 Prompt 与一个优秀的 Prompt
// 糟糕的 Prompt: 给我写个排序算法。 // 优秀的 Prompt: 你是一名算法专家。请为我用 Python 实现一个快速排序算法。 要求: 1. 函数名为 `quick_sort`,输入为一个整数列表 `arr`。 2. 实现必须包含递归,并处理基准值(pivot)的选择。 3. 在代码中添加必要的注释说明每一步的逻辑。 4. 最后,提供一个使用示例,对列表 `[64, 34, 25, 12, 22, 11, 90]` 进行排序并打印结果。 请将完整的代码放在一个代码块中。优秀的 Prompt 通过明确的指令,极大地提高了模型输出结果的准确性和可用性。
1.2 AI Agent:具备自主行动能力的智能体
AI Agent 是一个能够理解目标、制定计划并执行行动(例如调用工具、运行代码、访问 API)的智能系统。它超越了简单的问答,具备一定的自主性。一个典型的 AI Agent 由以下几个部分组成:
- 规划:将复杂任务分解为可执行的子任务。
- 记忆:保存对话历史、工具执行结果等上下文信息。
- 工具使用:调用外部工具(如计算器、搜索引擎、数据库)来获取信息或执行操作。
在我们的项目中,AI Agent 将负责理解用户的自然语言问题,决定是否需要从知识库中检索信息,并组织最终的答案。
1.3 RAG:增强大模型的事实性与专业性
RAG 的核心理念是让大模型在回答问题前,先从一个外部的、可控的知识库中检索相关信息。这解决了大模型的两个关键问题:
- 知识幻觉:模型可能会生成看似合理但实际错误的信息。
- 知识滞后:模型的训练数据有截止日期,无法获取最新信息。
RAG 系统的工作流程通常分为三步:
- 检索:将用户问题与知识库文档进行匹配,找出最相关的片段。
- 增强:将检索到的相关文本片段作为上下文,与用户问题一起构成新的 Prompt。
- 生成:大模型基于这个“增强”后的 Prompt 生成最终答案。
1.4 Cursor:AI 驱动的代码编辑器
Cursor 是一款集成了大模型的代码编辑器,它能够通过聊天和代码自动补全来极大地提升开发效率。在本次项目中,我们将使用 Cursor 来:
- 快速生成项目骨架和样板代码。
- 解释和理解复杂的代码逻辑。
- 辅助调试和代码重构。
2. 环境准备与工具配置
工欲善其事,必先利其器。我们将配置一个完整的开发环境,这是项目成功的基础。
2.1 Python 环境与关键依赖
首先,确保你的系统已安装 Python 3.8 或更高版本。推荐使用conda或venv创建独立的虚拟环境以避免包冲突。
# 创建并激活虚拟环境(以 conda 为例) conda create -n ai_rag_agent python=3.10 conda activate ai_rag_agent # 安装核心依赖 pip install openai langchain chromadb tiktoken sentence-transformers pypdf2关键库说明:
langchain: 构建大模型应用的框架,提供了 Chain、Agent、RAG 等高级抽象。chromadb: 轻量级、嵌入式的向量数据库,用于存储和检索文档的向量表示。sentence-transformers: 用于将文本转换为向量(嵌入)。openai: 官方 OpenAI API 客户端。pypdf2: 用于解析 PDF 文档,构建知识库。
2.2 获取并配置 OpenAI API 密钥
本项目使用 OpenAI 的模型(如 gpt-3.5-turbo 或 gpt-4)作为核心 LLM。你需要一个有效的 OpenAI API 密钥。
- 访问 OpenAI Platform 并注册/登录。
- 在 API Keys 页面生成一个新的密钥。
- 重要:将密钥设置为环境变量,切勿直接硬编码在代码中。
# 在 Linux/macOS 的终端中 export OPENAI_API_KEY='你的-api-key-here' # 在 Windows 的 Command Prompt 中 set OPENAI_API_KEY=你的-api-key-here # 在 Windows 的 PowerShell 中 $env:OPENAI_API_KEY='你的-api-key-here'2.3 安装与配置 Cursor 编辑器
- 访问 Cursor 官网 下载并安装对应操作系统的版本。
- 首次启动时,Cursor 会引导你进行基本设置。
- 设置中文界面(可选):Cursor 目前没有官方的全中文界面,但其交互逻辑简单,英文界面不影响使用。核心的 AI 聊天功能支持中文对话。
- 最关键的一步是配置 API Key。在 Cursor 的设置中,找到 AI 相关的配置项,填入你的 OpenAI API Key。这样 Cursor 才能使用强大的模型来辅助你编程。
3. 项目实战:构建企业知识库问答系统
现在,我们开始构建核心项目。这个系统将允许用户用自然语言提问,系统通过 RAG 从企业内部文档(如 PDF、TXT)中查找信息,并由 AI Agent 组织答案。
3.1 项目结构与数据准备
首先创建项目目录结构:
enterprise_rag_agent/ ├── docs/ # 存放原始知识文档(PDF/TXT) ├── vector_db/ # 向量数据库存储目录(由程序自动生成) ├── src/ │ ├── __init__.py │ ├── main.py # 主程序入口 │ ├── rag_chain.py # RAG 核心链 │ └── utils.py # 工具函数(如文档加载) └── requirements.txt将你的企业文档(例如员工手册、产品白皮书、API 文档等 PDF 或 TXT 文件)放入docs目录。
3.2 实现文档加载与向量化
这是 RAG 的“知识入库”阶段。我们编写utils.py来处理文档。
# src/utils.py from langchain.document_loaders import PyPDFLoader, TextLoader from langchain.text_splitter import RecursiveCharacterTextSplitter from langchain.embeddings import OpenAIEmbeddings from langchain.vectorstores import Chroma import os def load_and_split_documents(docs_directory="./docs"): """加载并分割文档""" documents = [] for filename in os.listdir(docs_directory): filepath = os.path.join(docs_directory, filename) if filename.endswith('.pdf'): loader = PyPDFLoader(filepath) elif filename.endswith('.txt'): loader = TextLoader(filepath, encoding='utf-8') else: continue # 跳过不支持的文件类型 documents.extend(loader.load()) # 分割文档为小块,便于检索 text_splitter = RecursiveCharacterTextSplitter( chunk_size=1000, # 每个块约1000字符 chunk_overlap=200 # 块之间重叠200字符,保持上下文 ) splits = text_splitter.split_documents(documents) print(f"已将 {len(documents)} 个文档分割为 {len(splits)} 个文本块。") return splits def create_vector_store(splits, persist_directory="./vector_db"): """创建并持久化向量数据库""" embeddings = OpenAIEmbeddings() # 使用 OpenAI 的嵌入模型 vectordb = Chroma.from_documents( documents=splits, embedding=embeddings, persist_directory=persist_directory ) vectordb.persist() print(f"向量数据库已创建并保存至 {persist_directory}") return vectordb3.3 构建 RAG 链
在rag_chain.py中,我们将检索器和生成器连接起来。
# src/rag_chain.py from langchain.chat_models import ChatOpenAI from langchain.schema.runnable import RunnablePassthrough from langchain.prompts import ChatPromptTemplate from langchain.vectorstores import Chroma from langchain.embeddings import OpenAIEmbeddings def format_docs(docs): """将检索到的文档片段格式化为一个字符串""" return "\n\n".join(doc.page_content for doc in docs) def get_rag_chain(persist_directory="./vector_db"): """构建并返回一个 RAG 链""" # 1. 加载已存在的向量数据库 embeddings = OpenAIEmbeddings() vectordb = Chroma( persist_directory=persist_directory, embedding_function=embeddings ) retriever = vectordb.as_retriever(search_kwargs={"k": 3}) # 检索最相关的3个片段 # 2. 定义 Prompt 模板 template = """你是一个专业的企业知识库助手。请严格根据以下提供的上下文信息来回答问题。 如果上下文信息不足以回答问题,请直接说“根据现有资料,我无法回答这个问题”,不要编造信息。 上下文信息: {context} 问题:{question} 请给出专业、准确的回答:""" prompt = ChatPromptTemplate.from_template(template) # 3. 初始化 LLM llm = ChatOpenAI(model="gpt-3.5-turbo", temperature=0) # temperature=0 使输出更确定 # 4. 构建 RAG 链 rag_chain = ( {"context": retriever | format_docs, "question": RunnablePassthrough()} | prompt | llm ) return rag_chain3.4 创建主程序并集成 Agent 逻辑
在main.py中,我们将一切整合,并加入简单的 Agent 决策逻辑。
# src/main.py from rag_chain import get_rag_chain from utils import load_and_split_documents, create_vector_store import os def initialize_system(): """初始化系统:检查向量数据库是否存在,若不存在则从文档创建""" if not os.path.exists("./vector_db") or not os.listdir("./vector_db"): print("未找到向量数据库,正在从文档创建...") splits = load_and_split_documents() create_vector_store(splits) print("知识库初始化完成!") else: print("检测到现有向量数据库,直接加载。") def simple_agent(question, rag_chain): """一个简单的 Agent,决定是否使用 RAG 以及如何回答""" # 判断问题是否与公司知识相关 company_keywords = ['公司', '员工', '产品', '手册', '政策', '流程'] # 可根据实际情况扩展 requires_knowledge = any(keyword in question for keyword in company_keywords) if requires_knowledge: # 使用 RAG 链获取答案 print("【Agent】判断问题需要查询知识库,正在检索...") answer = rag_chain.invoke(question) return answer.content else: # 对于通用问题,直接让 LLM 回答(也可配置一个不依赖上下文的通用链) print("【Agent】判断此为通用问题。") return "这是一个通用问题,目前我主要专注于解答公司内部知识库相关的问题。" def main(): # 1. 初始化系统 initialize_system() # 2. 获取 RAG 链 rag_chain = get_rag_chain() # 3. 交互循环 print("企业知识库问答系统已启动!输入 '退出' 或 'quit' 来结束程序。") while True: question = input("\n请输入你的问题:").strip() if question.lower() in ['退出', 'quit']: break if not question: continue # 4. 由 Agent 处理问题 answer = simple_agent(question, rag_chain) print(f"\n助手:{answer}") if __name__ == "__main__": main()3.5 运行与验证
- 将你的文档放入
docs文件夹。 - 在项目根目录下,运行主程序:
python src/main.py- 系统会首先初始化知识库(将文档转换为向量并存储),然后进入问答界面。
- 测试用例:
- 问题1:“公司的年假政策是怎样的?”(这是一个需要从知识库中检索的问题)
- 预期:Agent 识别出需要查询知识库,RAG 链会检索相关段落,并生成基于文档内容的答案。
- 问题2:“今天天气怎么样?”(这是一个通用问题)
- 预期:Agent 识别为通用问题,并给出预设的回复。
4. 使用 Cursor 提升开发效率
在整个开发过程中,我们可以充分利用 Cursor 的 AI 能力。
4.1 快速生成代码骨架
当你创建新文件时,可以直接在 Cursor 的聊天框中输入需求。例如,在创建utils.py前,你可以输入: “我需要一个 Python 函数,用 LangChain 加载docs文件夹下的 PDF 和 TXT 文件,并分割成文本块。” Cursor 会生成一个符合要求的函数雏形,你只需进行微调。
4.2 解释和理解代码
如果对 LangChain 的某个类(如RecursiveCharacterTextSplitter)不熟悉,可以选中代码,右键选择“Explain Code”或直接在 Chat 中提问:“这段代码是做什么的?chunk_overlap参数有什么用?” Cursor 会给出清晰的解释。
4.3 调试和错误修复
当程序出现错误时,将错误信息复制到 Cursor 的 Chat 中。例如,如果遇到OpenAI API认证错误,Cursor 可能会提示你:“请检查OPENAI_API_KEY环境变量是否设置正确。”
5. 常见问题与排查指南
在实际开发和运行中,你可能会遇到以下典型问题。
5.1 API 与网络问题
| 问题现象 | 可能原因 | 检查与解决 |
|---|---|---|
AuthenticationError/Invalid API Key | API 密钥错误或未设置 | 1. 检查环境变量名是否为OPENAI_API_KEY。2. 在终端执行 echo $OPENAI_API_KEY(Linux/macOS) 或echo %OPENAI_API_KEY%(Windows) 确认密钥已加载。3. 确认密钥有效且未过期。 |
APIConnectionError/ 超时 | 网络连接问题,特别是无法访问 OpenAI 服务 | 1. 检查本地网络连接。 2. 如果存在网络访问限制,需要配置合规的网络代理。 |
RateLimitError | API 调用频率超限 | 1. 检查 OpenAI 账户的用量和速率限制。 2. 在代码中增加重试逻辑或降低请求频率。 |
5.2 文档处理与检索问题
| 问题现象 | 可能原因 | 检查与解决 |
|---|---|---|
| 程序跳过所有文档 | 文档格式不支持或路径错误 | 1. 确认文档在./docs目录下。2. 确认文档为 PDF 或 TXT 格式。 3. 检查 load_and_split_documents函数中的文件路径处理逻辑。 |
| 检索到的内容不相关 | 文档分割策略不佳或检索参数不合适 | 1. 调整text_splitter的chunk_size和chunk_overlap参数。2. 调整 retriever的k值,增加或减少检索数量。3. 考虑使用更先进的嵌入模型。 |
| 回答未基于上下文(幻觉) | Prompt 设计不够强硬 | 强化 Prompt 中的指令,例如:“必须严格根据上下文回答”,“禁止编造上下文未提及的信息”。 |
5.3 性能与成本优化
- 令牌消耗:大量或长文档会导致嵌入和生成阶段消耗大量 Token。监控 OpenAI API 的使用量,对于大型知识库,可以考虑使用更便宜的嵌入模型(如
text-embedding-3-small)或在本地部署嵌入模型。 - 检索速度:ChromaDB 在本地运行,速度通常很快。如果知识库极大(数十万文档),可以考虑专业的向量数据库如 Pinecone、Weaviate。
- Agent 逻辑:当前的
simple_agent仅通过关键词判断。生产环境中需要更复杂的意图识别模型或规则引擎。
6. 最佳实践与扩展方向
构建一个原型只是第一步,要将其发展为生产可用的系统,还需要考虑更多因素。
6.1 Prompt 工程最佳实践
- 迭代优化:将 Prompt 单独保存在配置文件或数据库中,方便持续测试和优化。
- 少样本学习:在 Prompt 中提供一两个输入输出的例子,能显著提升模型在特定任务上的表现。
- 结构化输出:要求模型输出 JSON 等格式,便于后端程序解析和处理。
6.2 RAG 系统优化
- 混合检索:结合基于向量的语义检索和基于关键词的稀疏检索,提高召回率。
- 重排序:对初步检索到的多个文档块进行二次排序,将最相关的排在前面,提升上下文质量。
- 元数据过滤:为文档块添加来源、章节、日期等元数据,检索时可以进行过滤,提高准确性。
6.3 AI Agent 进阶
- 工具集成:为 Agent 集成更多工具,如查询数据库、调用外部 API、执行代码等,使其能力更强。
- 记忆管理:实现对话记忆,让 Agent 能够理解多轮对话的上下文。
- 验证与安全:对于 Agent 自主执行的操作(如写文件、调用 API),需要增加人工确认或自动验证机制,防止意外后果。
这个项目为你提供了一个坚实的起点,涵盖了 AI 大模型应用开发的核心环节。接下来,你可以沿着上述扩展方向继续探索,例如为系统添加一个 Web 界面,或者集成更复杂的多模态能力,逐步构建出真正强大和实用的 AI 应用。