1. 从零到一我的生成式AI实战入门心路最近几年生成式AIGenerative AI的热度可以说是席卷了全球。从能写诗作画的ChatGPT到能生成代码的GitHub Copilot再到各种图像生成工具我们仿佛一夜之间被推入了一个由AI驱动的“魔法时代”。作为一个在技术领域摸爬滚打了十多年的开发者我最初面对这股浪潮时心情是复杂的既兴奋于技术的无限可能又焦虑于知识的快速迭代生怕自己一不留神就被时代抛下。这种感觉我称之为“AI时代的Day Zero”——一个全新的、充满未知的起点。相信很多同行无论是刚入行的新人还是像我一样有一定经验但想转型的老兵都曾有过类似的迷茫生成式AI到底该怎么学那么多模型、框架、概念从哪里开始才不跑偏网上的教程要么过于学术化要么就是简单的API调用很难形成一个从理论到实践、从零到一的完整知识体系。正是在这种背景下我决定系统性地梳理自己的学习路径并开源了GenAI_DayZero这个项目。它不是一个简单的代码仓库更像是我个人学习旅程的“实战笔记”和“工具箱”。我的目标很明确把复杂的生成式AI概念拆解成可理解、可操作、可复现的模块让任何一个有编程基础的人都能沿着这条路径从“零”成长为能够解决实际问题的“英雄”。这个项目聚焦于几个我认为当前最核心、也最具商业价值的领域大语言模型LLM的应用、检索增强生成RAG系统的构建以及向量数据库特别是AstraDB的实战。我不会从枯燥的数学公式讲起而是直接从“我们要用AI解决什么问题”出发带你一步步搭建起能跑起来的系统。你会学到如何用LangChain这样的框架来编排AI工作流如何用Cursor这样的AI编程助手来提升开发效率以及如何将Google的Gemini API或Vertex AI等强大的模型能力与你自己的数据存储在MongoDB或向量数据库中结合起来创造出真正有用的应用。无论你是想为自己的产品增加一个智能客服还是想构建一个能理解内部文档的知识库助手亦或是单纯想掌握这门未来十年的核心技能我相信这份从实战中总结出来的指南都能为你提供一个坚实的起点。接下来就让我们抛开焦虑从“Day Zero”开始一起动手把AI知识从种子培育成参天大树。2. 核心战场为什么是LLM、RAG与向量数据库在开始敲代码之前我们必须先搞清楚战场在哪里以及为什么要选择这些武器。生成式AI领域广阔无垠盲目学习只会事倍功半。经过大量的项目实践和行业观察我坚定地认为对于大多数希望快速应用AI创造价值的开发者和团队来说LLM应用开发、RAG系统构建和向量数据库是必须攻克的“铁三角”。2.1 大语言模型从“黑箱”到“工具箱”大语言模型LLM是这一切的基础。你可以把它理解为一个博览群书、知识渊博但有时会“信口开河”的超级大脑。它的核心能力是理解和生成人类语言。几年前我们使用LLM可能需要自己训练一个模型成本高昂且技术门槛极高。但现在情况完全不同了。以Google Gemini API和Vertex AI为例它们将最先进的LLM能力封装成了易用的云服务。这意味着我们不再需要关心模型内部那数以万亿计的参数是如何运作的而是可以像调用一个普通API一样让AI帮我们完成总结、创作、翻译、对话等任务。这极大地降低了应用AI的门槛。那么为什么选择它们作为学习重点第一生态成熟且稳定。Google的AI平台提供了从模型托管、版本管理到监控调优的一整套工具非常适合生产环境。第二多模态能力。Gemini原生支持文本、图像、音频等多种输入为构建更丰富的应用如分析带图的报告、生成视频脚本打开了大门。第三可控的成本。按需调用的付费方式让我们可以在项目早期低成本试错。实操心得在项目初期不要纠结于哪个模型“最强”。更重要的是理解不同模型如Gemini Pro, Gemini Ultra的特性、上下文长度限制、Token计价方式以及速率限制。先基于一个模型比如Gemini Pro把整个应用流水线跑通再考虑优化和升级。2.2 检索增强生成给AI装上“事实检查官”LLM很强但它有一个致命的弱点它可能会“幻觉”Hallucinate即生成看似合理但完全错误或虚构的信息。当你问它“我公司2023年的销售额是多少”时它无法访问你的内部数据只能根据训练数据“编造”一个答案。这对于企业应用来说是灾难性的。检索增强生成RAG就是为了解决这个问题而生的范式。它的核心思想很简单在让LLM回答问题之前先从一个可靠的、最新的知识库比如你的公司文档、产品手册、数据库中检索出相关的信息片段然后将这些信息片段和用户的问题一起交给LLM让它基于这些“证据”来生成答案。这个过程就像在考试时允许你带一本指定的参考书进去。LLM不再依赖模糊的记忆而是基于你提供的“参考书”检索到的文档来作答答案的准确性和可靠性大幅提升。RAG系统让AI应用从“聊天玩具”变成了可以处理专业知识的“智能助理”。2.3 向量数据库让机器理解“相似性”的钥匙RAG系统需要一个高效的知识库来存储和检索信息。传统数据库通过精确匹配比如WHERE name ‘xxx’来查找数据但这不适用于语义搜索。我们需要的不是“完全相同的字符串”而是“意思相近的文本”。这就是向量数据库的用武之地。它的核心是向量化和相似性搜索。我们使用一个嵌入模型Embedding Model将一段文本如一个句子、一个段落转换成一个高维度的数字向量可以理解为一串有特定含义的数字。这个向量在数学空间中的位置就代表了这段文本的语义。Astra DBDataStax Astra DB是我在项目中主要使用的向量数据库它有几个突出优点原生多模它基于Apache Cassandra构建不仅能存向量还能高效存储原始的JSON文档非常适合将元数据如文件名、作者、日期和向量存储在一起。Serverless架构无需操心服务器运维按实际使用的读写操作和存储量付费起步成本低扩展性强。集成度高与LangChain等AI框架有深度集成几行代码就能完成向量存储和检索的配置。当用户提问时我们将问题也转换成向量然后在向量数据库中快速找到与这个问题向量“距离最近”即最相似的文档向量这些文档就是最相关的“证据”。这个“铁三角”是如何协同工作的知识入库将你的文档PDF、Word、网页通过嵌入模型转换成向量存入Astra DB。用户提问用户输入一个问题。检索将问题转换成向量在Astra DB中执行相似性搜索找到最相关的几个文档片段。增强生成将检索到的文档片段作为上下文和用户问题一起构造一个详细的提示Prompt发送给Gemini API。智能回复Gemini基于提供的上下文生成准确、可靠的答案。这套组合拳是目前构建可信、可控、可追溯的企业级AI应用最主流和实用的架构。接下来我们就进入实战环节看看如何亲手搭建这个系统。3. 环境搭建与工具链打造高效的AI开发工作台工欲善其事必先利其器。一个顺手的开发环境能极大提升学习和实验的效率。我的这套工具链经过多个项目的磨合在易用性、效率和功能上达到了很好的平衡特别适合生成式AI应用的快速原型开发和迭代。3.1 核心武器Cursor——你的AI结对编程伙伴首先要隆重介绍的是Cursor。它不仅仅是一个代码编辑器基于VS Code更是一个深度集成AI的编程伴侣。在生成式AI项目开发中我们经常需要快速理解新库的API、编写样板代码、或者调试复杂的逻辑链。Cursor的“Chat”和“Edit”功能几乎是为这个场景量身定做的。快速理解与生成当你打开一个陌生的LangChain模块时可以直接用Cursor询问“这个VectorStoreRetriever是干什么的给我一个使用Astra DB的例子”。它能结合上下文代码给出非常精准的解释和示例。安全重构与调试你可以选中一段代码让Cursor“检查这段代码是否有潜在的错误”或“用更高效的方式重写它”。它在处理AI应用特有的异步调用、错误处理时尤其有用。项目级理解Cursor能对你整个项目代码库建立索引因此它的建议是基于你的全部代码而不仅仅是当前文件。这在构建由多个模块组成的RAG系统时能帮你理清模块间的依赖关系。避坑指南虽然Cursor很强但切忌完全依赖它生成核心业务逻辑。它生成的代码有时会忽略一些边界条件或最新的API变更。最佳实践是把它当作一个超级智能的“实习生”。让它帮你写第一版草稿、写文档注释、或者提供思路但关键的架构决策、核心算法和安全相关的代码一定要自己审核和测试。3.2 基础环境Python与虚拟环境生成式AI的生态几乎都建立在Python之上。为了避免不同项目间的依赖冲突使用虚拟环境是必须养成的习惯。# 1. 确保使用Python 3.8或更高版本 python --version # 2. 创建项目目录并进入 mkdir my_genai_project cd my_genai_project # 3. 创建虚拟环境强烈推荐使用venv它是Python标准库的一部分 python -m venv venv # 4. 激活虚拟环境 # 在 macOS/Linux 上 source venv/bin/activate # 在 Windows 上 .\venv\Scripts\activate # 激活后命令行提示符前通常会显示 (venv)3.3 依赖管理requirements.txt的学问一个清晰的requirements.txt文件是项目可复现的基石。对于AI项目依赖库的版本尤其重要因为相关生态更新极快API变动可能造成代码崩溃。# 核心AI编排框架 langchain0.1.0 langchain-community0.0.10 # 社区贡献的组件如各种VectorStore langchain-google-genai0.0.2 # Google Gemini的LangChain集成 # 向量数据库驱动 astrapy0.7.0 # DataStax Astra DB的官方Python驱动 # 嵌入模型与LLM google-generativeai0.3.0 # Gemini API的官方SDK # 可选如果你使用OpenAI的嵌入模型 # openai1.3.0 # 文档加载与处理 pypdf3.17.0 # 处理PDF python-docx1.1.0 # 处理Word beautifulsoup44.12.2 # 解析HTML tiktoken0.5.1 # 用于计算Token非OpenAI专属也可用于估算 # 开发与工具 jupyter1.0.0 # 用于实验和演示 python-dotenv1.0.0 # 管理环境变量非常重要使用pip install -r requirements.txt一键安装所有依赖。这里有一个关键细节永远不要将你的API密钥等敏感信息硬编码在代码中或提交到requirements.txt。我们使用python-dotenv来管理。3.4 密钥管理与配置安全第一在项目根目录创建一个名为.env的文件并把它加入.gitignore。# .env 文件内容示例 GOOGLE_API_KEYyour_actual_gemini_api_key_here ASTRA_DB_APPLICATION_TOKENyour_astra_db_token_here ASTRA_DB_API_ENDPOINThttps://your-database-id-your-region.apps.astra.datastax.com ASTRA_DB_KEYSPACEyour_keyspace_name然后在你的Python代码中这样加载# config.py import os from dotenv import load_dotenv load_dotenv() # 从 .env 文件加载环境变量 GOOGLE_API_KEY os.getenv(GOOGLE_API_KEY) ASTRA_DB_APPLICATION_TOKEN os.getenv(ASTRA_DB_APPLICATION_TOKEN) ASTRA_DB_API_ENDPOINT os.getenv(ASTRA_DB_API_ENDPOINT) ASTRA_DB_KEYSPACE os.getenv(ASTRA_DB_KEYSPACE) # 验证关键变量是否已加载 if not all([GOOGLE_API_KEY, ASTRA_DB_APPLICATION_TOKEN, ASTRA_DB_API_ENDPOINT]): raise ValueError(请在 .env 文件中配置必要的API密钥和数据库连接信息。)这套配置方法保证了代码的安全性也方便在不同环境开发、测试、生产间切换配置。至此我们的开发工作台就准备就绪了。接下来我们将进入最激动人心的部分用代码让这个“铁三角”真正运转起来。4. 实战构建一个完整的RAG问答系统理论说得再多不如一行代码。现在我们将一步步构建一个完整的、基于Gemini和Astra DB的RAG问答系统。这个系统能够读取你的本地知识文档比如公司手册、技术文档并智能地回答相关问题。我会详细解释每一步的意图和关键参数让你不仅能复制更能理解。4.1 第一步连接向量数据库——Astra DB初始化首先我们需要在Astra DB上创建一个数据库。登录DataStax官网在控制台创建一个Serverless数据库选择Google Cloud或AWS的区域记下生成的API Endpoint和Application Token并填入之前的.env文件。在代码中我们使用LangChain的集成来连接Astra DB向量存储。# rag_system/core/vector_store.py from langchain.vectorstores import AstraDB from langchain.embeddings import OpenAIEmbeddings # 注意这里为了示例通用性先使用OpenAI的嵌入模型。 # 实际上Gemini也提供了嵌入模型我们稍后会切换。 import os from config import ASTRA_DB_APPLICATION_TOKEN, ASTRA_DB_API_ENDPOINT, ASTRA_DB_KEYSPACE def get_astra_vector_store(embedding_model, collection_namedocs_collection): 初始化并返回Astra DB向量存储连接。 参数: embedding_model: 用于生成文本向量的嵌入模型实例。 collection_name: Astra DB中的集合名称类似于表名。 返回: AstraDB向量存储对象。 # 初始化AstraDB向量存储 vector_store AstraDB( embeddingembedding_model, collection_namecollection_name, api_endpointASTRA_DB_API_ENDPOINT, tokenASTRA_DB_APPLICATION_TOKEN, namespaceASTRA_DB_KEYSPACE, ) print(f已成功连接到Astra DB集合: {collection_name}) return vector_store # 初始化嵌入模型示例使用OpenAI需设置OPENAI_API_KEY环境变量 # from langchain.embeddings import OpenAIEmbeddings # embedding OpenAIEmbeddings(modeltext-embedding-3-small) # astra_vs get_astra_vector_store(embedding)关键点解析collection_name这是Astra DB中存储向量的逻辑容器。你可以为不同类型的文档创建不同的集合例如product_docs、legal_docs。namespace在Astra DB中对应keyspace是一个顶层的数据库命名空间。Serverless实例通常会提供一个默认的keyspace。嵌入模型选择这里先用OpenAI的嵌入模型做演示因为它通用且稳定。但请注意这会产生额外的API调用成本。后续我们会切换到免费的本地模型或Gemini的嵌入模型以优化成本。4.2 第二步处理你的知识——文档加载与分块原始文档如PDF不能直接存入向量数据库。我们需要将其转换成纯文本并切割成适合检索的“块”。# rag_system/core/document_processor.py from langchain.document_loaders import PyPDFLoader, TextLoader, UnstructuredWordDocumentLoader from langchain.text_splitter import RecursiveCharacterTextSplitter from typing import List, Union from langchain.schema import Document class DocumentProcessor: def __init__(self, chunk_size1000, chunk_overlap200): 初始化文档处理器。 参数: chunk_size: 每个文本块的最大字符数。 chunk_overlap: 相邻文本块之间的重叠字符数用于保持上下文连贯。 self.text_splitter RecursiveCharacterTextSplitter( chunk_sizechunk_size, chunk_overlapchunk_overlap, length_functionlen, separators[\n\n, \n, 。, , , , , , ] ) def load_and_split(self, file_path: str) - List[Document]: 根据文件后缀名加载文档并进行分块。 参数: file_path: 本地文档文件的路径。 返回: 分割后的Document对象列表。 # 根据文件类型选择加载器 if file_path.endswith(.pdf): loader PyPDFLoader(file_path) elif file_path.endswith(.docx): loader UnstructuredWordDocumentLoader(file_path) elif file_path.endswith(.txt): loader TextLoader(file_path) else: raise ValueError(f不支持的文件格式: {file_path}) print(f正在加载文档: {file_path}) documents loader.load() print(f文档加载完成共{len(documents)}页。开始分块...) chunks self.text_splitter.split_documents(documents) print(f分块完成共得到{len(chunks)}个文本块。) return chunks # 使用示例 processor DocumentProcessor(chunk_size800, chunk_overlap150) chunks processor.load_and_split(./knowledge_base/公司产品手册.pdf)参数选择与经验chunk_size这是最重要的参数。太小如200会丢失上下文导致检索到的信息碎片化太大如2000可能包含无关信息干扰LLM判断。对于技术文档800-1200是个不错的起点对于对话或小说可以更小一些。需要根据你的文档内容和后续问答效果进行调整。chunk_overlap重叠是为了避免一个完整的句子或概念被硬生生切在两块中间。通常设置为chunk_size的10%-20%。RecursiveCharacterTextSplitter它会按你指定的分隔符列表separators递归地尝试分割尽量保证块的完整性是LangChain中最常用且效果较好的分块器。4.3 第三步知识入库——生成向量并存储将分块后的文本转换成向量并存入Astra DB。# rag_system/core/knowledge_ingest.py from .vector_store import get_astra_vector_store from .document_processor import DocumentProcessor from langchain.embeddings import OpenAIEmbeddings def ingest_knowledge_to_astra(file_paths: List[str], collection_name: str): 将多个文档的知识注入到Astra DB向量存储中。 参数: file_paths: 文档路径列表。 collection_name: 目标集合名称。 # 1. 初始化嵌入模型和处理器 embedding_model OpenAIEmbeddings(modeltext-embedding-3-small) processor DocumentProcessor() all_chunks [] for fp in file_paths: chunks processor.load_and_split(fp) all_chunks.extend(chunks) print(f总共处理了{len(file_paths)}个文件得到{len(all_chunks)}个文本块。) # 2. 获取向量存储并添加文档 vector_store get_astra_vector_store(embedding_model, collection_name) # 注意add_documents 方法会为每个Document生成向量并存入数据库 # 这个过程可能需要一些时间取决于文档数量和网络速度。 print(正在生成向量并存入Astra DB请稍候...) vector_store.add_documents(all_chunks) print(知识注入完成) # 3. 可选创建一个检索器测试一下 retriever vector_store.as_retriever(search_kwargs{k: 4}) # 检索最相关的4个块 return retriever # 执行知识注入 if __name__ __main__: docs [./knowledge_base/手册1.pdf, ./knowledge_base/FAQ.docx] retriever ingest_knowledge_to_astra(docs, product_knowledge)重要提示add_documents是异步操作对于大量文档可以考虑使用批量接口或异步函数来提升效率。同时要监控Astra DB控制台的用量避免超出免费额度。4.4 第四步组装大脑——构建RAG链这是最核心的一步我们将检索器Retriever和语言模型LLM用LangChain的“链”组合起来。# rag_system/core/rag_chain.py from langchain.chains import RetrievalQA from langchain.prompts import PromptTemplate from langchain_google_genai import ChatGoogleGenerativeAI from langchain.embeddings import OpenAIEmbeddings from .vector_store import get_astra_vector_store import os from config import GOOGLE_API_KEY def create_rag_qa_chain(collection_name: str): 创建并返回一个配置好的RAG问答链。 参数: collection_name: 知识库对应的集合名称。 返回: 一个可以直接进行问答的RetrievalQA链。 # 1. 初始化LLM (使用Gemini Pro) llm ChatGoogleGenerativeAI( modelgemini-pro, google_api_keyGOOGLE_API_KEY, temperature0.2, # 控制创造性越低答案越确定 convert_system_message_to_humanTrue ) # 2. 初始化检索器 (使用相同的嵌入模型) embedding_model OpenAIEmbeddings(modeltext-embedding-3-small) vector_store get_astra_vector_store(embedding_model, collection_name) retriever vector_store.as_retriever(search_kwargs{k: 5}) # 检索5个相关片段 # 3. 定义自定义提示模板 # 一个好的提示模板能显著提升答案质量 prompt_template 请严格根据以下提供的上下文信息来回答问题。如果上下文信息中没有明确答案请直接说“根据现有资料我无法回答这个问题”不要编造信息。 上下文信息 {context} 问题{question} 请基于上下文给出清晰、准确、有用的答案 PROMPT PromptTemplate( templateprompt_template, input_variables[context, question] ) # 4. 创建检索问答链 qa_chain RetrievalQA.from_chain_type( llmllm, chain_typestuff, # 最常用的类型将所有检索到的上下文“塞”进提示 retrieverretriever, chain_type_kwargs{prompt: PROMPT}, return_source_documentsTrue # 非常重要返回来源文档便于追溯和调试 ) return qa_chain # 使用示例 if __name__ __main__: qa_chain create_rag_qa_chain(product_knowledge) # 进行问答 question 我们产品的高级版和企业版在数据存储容量上有什么区别 result qa_chain({query: question}) print(f问题{question}) print(f答案{result[result]}) print(\n--- 来源文档 ---) for i, doc in enumerate(result[source_documents]): print(f[片段 {i1}] {doc.page_content[:200]}...) # 打印前200个字符核心参数深度解析temperature这是控制LLM“创造力”的核心参数。在问答场景下我们追求准确性因此设置为较低的值如0.1-0.3。如果用于创意写作可以调高到0.7-0.9。search_kwargs{“k”: 5}决定每次检索返回多少个相关文档片段。太少可能信息不足太多可能引入噪声并增加Token消耗。通常4-8是一个平衡点。chain_type“stuff”这是最简单的RAG链类型它把检索到的所有文档内容拼接起来一次性发送给LLM。优点是简单直接缺点是可能受限于LLM的上下文窗口长度。对于超长文档可以考虑“map_reduce”或“refine”等更复杂的链类型。提示工程prompt_template是灵魂。清晰的指令“严格根据上下文”、明确的格式要求、以及对未知问题的处理方式“直接说无法回答”能极大减少LLM的“幻觉”。在实际项目中需要反复调试和优化这个模板。至此一个功能完整的RAG问答系统就构建完成了。你可以通过一个简单的循环或构建一个Web界面例如用Gradio或Streamlit来与它交互。但构建成功只是第一步要让系统稳定可靠我们还需要面对和解决一系列实际问题。5. 避坑指南与性能优化从“能用”到“好用”在实际部署和使用的过程中我踩过不少坑也总结出一些让系统更健壮、更高效的技巧。这部分内容往往是官方文档不会详细提及的但对于构建生产级应用至关重要。5.1 常见问题与排查技巧实录问题1检索结果不相关导致答案质量差。排查思路检查分块策略这是最常见的原因。用几个典型问题打印出检索到的source_documents看看内容是否真的相关。如果块太大包含了无关信息如果块太小丢失了关键上下文。调整chunk_size和chunk_overlap。检查嵌入模型不同的嵌入模型对语义的理解有差异。对于中文场景可以尝试text-embedding-3-small的多语言版本或者专门的中文嵌入模型如BGE系列的开源模型。检查检索参数尝试调整search_kwargs比如增加k的值或者尝试不同的相似度算法如similarity_score_threshold来设置最低相似度阈值。解决方案建立一个小的评估集10-20个问题及其在文档中的标准答案通过脚本自动化测试不同分块和检索参数下的答案准确率进行量化调优。问题2LLM回答“根据上下文无法回答”但明明文档里有。排查思路检查提示词可能是提示词过于严格或者上下文信息组织方式让LLM难以定位。尝试简化提示词或明确指示“请从上下文中找出相关信息”。检查上下文长度如果检索到的文档总长度超过LLM的上下文限制如Gemini Pro 1.0是30K Token后面的内容会被截断。需要减少k或使用能处理长上下文的模型/链类型如“map_reduce”。检查信息密度检索到的文档片段可能包含太多无关文本如页眉页脚、代码注释淹没了关键信息。需要在文档加载和分块前进行清洗Cleanup。解决方案在提示词中加入更明确的指令例如“请仔细阅读以下上下文并提取与问题直接相关的所有事实来组织答案。”问题3系统响应速度慢。瓶颈分析向量检索慢Astra DB Serverless在冷启动时可能有延迟。对于高频应用可以考虑预热的专业集群或确保你的应用保持活跃连接。LLM API调用慢Gemini API的响应时间受网络和模型负载影响。实现请求超时和重试机制并考虑使用流式响应Streaming来提升用户体验。嵌入生成慢如果在问答时实时为问题生成嵌入这是标准流程通常很快。但如果是在知识注入阶段慢可以考虑使用批量异步处理或者使用更快的本地嵌入模型。优化方案缓存对常见问题FAQ的答案进行缓存可以极大减少对LLM和向量数据库的调用。异步处理使用asyncio并发处理多个文档的上传或批量问题的回答。监控与日志记录每个环节检索、LLM调用的耗时便于定位瓶颈。5.2 进阶优化从基础RAG到智能RAG基础RAG搭建完成后可以考虑以下进阶优化让系统更智能1. 混合搜索Hybrid Search单纯的向量相似度搜索语义搜索有时会漏掉关键词完全匹配的重要文档。混合搜索结合了语义搜索和关键词搜索如BM25。Astra DB和一些高级向量库如Weaviate, Qdrant支持此功能。这能同时捕获语义相关性和字面匹配提高召回率。2. 查询重写Query Rewriting/Expansion用户的问题可能很短或不精确。在检索前先用一个小型LLM如Gemini Flash对原始查询进行改写或扩展。例如将“怎么退款”扩展为“产品的退款政策是什么退款流程有哪些步骤退款需要多长时间”。这能帮助检索到更全面的信息。3. 元数据过滤在存储文档时除了文本和向量还可以存入元数据如文档类型、部门、更新时间等。在检索时可以添加过滤器例如“只从2024年更新的技术白皮书中检索”。这能确保答案的时效性和准确性。Astra DB的向量存储支持灵活的元数据过滤。4. 切换至本地/低成本嵌入模型为了降低成本和对网络API的依赖可以考虑使用开源的本地嵌入模型。例如使用Sentence Transformers库和BGE模型。# 示例使用本地BGE模型 from langchain.embeddings import HuggingFaceEmbeddings local_embedding_model HuggingFaceEmbeddings( model_nameBAAI/bge-small-zh-v1.5, # 一个优秀的中英文双语模型 model_kwargs{device: cpu}, # 或 cuda encode_kwargs{normalize_embeddings: True} # 归一化有利于相似度计算 ) # 然后用这个模型初始化你的AstraDB向量存储5. 评估与迭代建立一个持续的评估体系。除了人工抽查可以设计一些自动化评估指标如答案相关性生成的答案是否直接回答了问题事实一致性答案中的事实是否与检索到的源文档一致引用准确性答案声称引用的来源是否真的支持该说法可以使用LLM本身如Gemini作为裁判对少量测试用例进行自动评分从而在调整参数或升级模型后快速评估系统效果是变好还是变差了。构建一个RAG系统不是一蹴而就的它更像是一个需要持续调优的“活系统”。从最简单的原型出发通过不断观察、分析问题、应用上述优化技巧你的AI助手会变得越来越聪明、可靠。这个过程本身就是生成式AI工程化中最有价值的部分。