尧图建网站 尧图建网站 YAOTU WEB BUILD 免费咨询
ARTICLE DETAIL

资讯详情

深耕网站建设与建站编程的一线实战洞察。

从零搭建RAG语义搜索系统:让AI听懂弦外之音

从零搭建RAG语义搜索系统:让AI听懂弦外之音 1. 项目概述为什么“听懂弦外之音”是AI的下一站最近和几个做产品、搞内容的朋友聊天大家不约而同地都在吐槽同一个问题现在的AI助手你说东它绝不往西但问题是它也只懂“东”。你问“最近有什么值得关注的行业动态”它可能会给你列出一堆过时的新闻标题你提一个模糊的需求比如“帮我找找那个关于用户增长策略的PDF”如果文件名不叫“用户增长策略.pdf”它大概率就懵了。这感觉就像和一个非常认真但理解力有限的新手同事沟通你得把指令拆解得极其精确它才能完成任务完全谈不上“默契”。这背后的核心矛盾就在于传统的关键词匹配搜索已经无法满足我们对信息智能检索的深层需求。我们人类交流充满了上下文、意图和“弦外之音”。而要让AI具备这种能力RAG检索增强生成结合语义搜索就成了当下最务实、最有效的技术路径。这不是一个遥远的概念而是任何一个希望提升信息处理效率的团队或个人都应该掌握的核心技能。今天我就从一个实践者的角度带你从零开始亲手搭建一个能“听懂弦外之音”的RAG语义搜索系统。我们不止步于调用API而是要深入原理搞懂每一个环节为什么这么做以及如何做得更好。2. 核心思路拆解RAG如何让搜索变得“智能”在开始敲代码之前我们必须把核心思路理清楚。RAG不是一个单一的技术而是一个精巧的“流水线”工程。它的目标很明确利用外部知识库来增强大语言模型LLM的生成能力使其回答更准确、更相关、更“有据可查”。2.1 从关键词到语义搜索范式的根本转变传统的搜索引擎无论是数据库里的LIKE查询还是Elasticsearch的倒排索引本质都是关键词匹配。你搜索“苹果”它返回所有包含“苹果”这个词的文档。至于这个“苹果”是水果、手机公司还是电影它并不关心。这导致了两个主要问题词汇鸿沟和缺乏语义理解。比如你搜索“深度学习框架”可能不会返回标题为“PyTorch教程”的文档因为字面上不匹配。语义搜索则试图解决这个问题。它的核心思想是将查询和文档都转换成高维空间中的向量也叫Embedding然后通过计算向量之间的相似度如余弦相似度来寻找最相关的文档。在这个向量空间里“苹果”和“iPhone”、“深度学习”和“神经网络”会因为语义相近而距离很近。这样即使查询和文档没有相同的字词只要意思相近就能被检索出来。这就是“听懂弦外之音”的数学基础。2.2 RAG的工作流水线检索、增强、生成一个标准的RAG流程可以分解为三个核心阶段我习惯称之为“准备、检索、回答”索引构建准备阶段这是离线进行的。我们将自己的知识库一堆PDF、TXT、网页、数据库记录进行预处理包括文本提取、清洗、分割成合适大小的“块”Chunk然后使用Embedding模型将每一块文本转换成向量。最后将这些向量及其对应的原始文本存储到向量数据库中。这就好比为你的知识库建立了一个“语义地图”。检索理解阶段当用户提出一个问题Query时在线流程启动。首先使用同一个Embedding模型将用户的问题也转换成向量。然后将这个查询向量送入向量数据库进行相似度搜索通常叫similarity_search或kNN找出前k个比如前5个最相关的文本块。这一步就是系统在“听懂”你的问题并从海量知识中找出最可能包含答案的片段。增强生成回答阶段检索到的相关文本块被作为“上下文”或“参考依据”和用户的原始问题一起构造成一个详细的提示词Prompt提交给大语言模型如GPT、ChatGLM、Qwen等。Prompt通常会这样设计“请基于以下背景信息回答问题{检索到的文本}。问题是{用户问题}”。LLM基于这个增强了上下文的Prompt来生成最终答案从而确保答案不仅通顺而且与你的私有知识库高度相关、事实准确。这个流程的精妙之处在于它巧妙地将LLM强大的生成能力和向量检索的精准性结合了起来既弥补了LLM知识可能过时或虚构的缺点又克服了传统检索无法深入理解语义的短板。3. 工具选型与核心组件解析工欲善其事必先利其器。搭建RAG系统我们需要在每一个环节做出合适的技术选型。这里没有银弹只有权衡。3.1 Embedding模型文本的“翻译官”Embedding模型负责把文本变成计算机能理解的“语义向量”。它的质量直接决定了检索的准确性。选型时主要看几点维度通常有384维、768维、1024维等。维度越高表征能力越强但计算和存储开销也越大。对于大多数通用场景768维是一个很好的平衡点。上下文长度模型单次能处理的最大文本长度。对于长文档分割需要确保模型支持足够长的长度如512或1024 token。中英文能力如果你的资料主要是中文必须选择对中文优化好的模型。直接用英文模型处理中文效果会大打折扣。当前主流选择BGEBAAI General Embedding系列由智源研究院开源在中文社区表现非常出色。例如BAAI/bge-large-zh和更新的BAAI/bge-large-zh-v1.5都是768维专门为中文优化是中文RAG项目的首选。OpenAI的text-embedding-ada-002效果稳定使用简单但需要API调用有成本和网络考虑。本地轻量级模型如moka-ai/m3e-base在中文任务上也有不错的表现且更轻量。实操心得对于从零开始的项目我强烈建议从BAAI/bge-large-zh-v1.5开始。它开源、免费、中文能力强而且Hugging Face上直接可用社区支持也好。先把它跑通建立起对整个流程的感性认识比纠结选型更重要。3.2 向量数据库语义的“记忆宫殿”检索阶段需要快速进行海量向量的相似度计算传统关系型数据库无法胜任。向量数据库为此而生。Milvus功能最全、性能最强的开源向量数据库之一支持多种索引类型IVF_FLAT, HNSW等适合生产环境的大规模数据。但部署和运维相对复杂。Chroma轻量级、嵌入优先的向量数据库API极其简单可以和LangChain等框架无缝集成。特别适合原型开发、实验和小型应用。它甚至可以直接将数据持久化到本地磁盘无需单独服务。PGVectorPostgreSQL的扩展如果你的技术栈重度依赖PG希望向量数据和业务数据共存于同一数据库这是最自然的选择。Qdrant另一个性能优秀的开源向量数据库用Rust编写提供丰富的API和云服务。选型建议快速验证和原型开发毫不犹豫选Chroma。它的易用性会让你专注于流程本身而不是基础设施。准备上生产数据量巨大百万级以上认真评估Milvus或Qdrant。已有PostgreSQL且向量规模不大十万级PGVector是最省事的集成方案。3.3 大语言模型LLM最终的“答题者”LLM是生成答案的“大脑”。你可以选择云端API如OpenAI GPT系列、Anthropic Claude、国内深度求索的API等。优势是能力强大、稳定劣势是持续产生费用、有网络延迟、数据隐私需要考虑。本地部署如ChatGLM3、Qwen1.5/2、Llama 3等开源模型。优势是数据完全私有、无网络延迟、一次部署长期使用劣势是对硬件GPU有要求且模型能力可能略逊于顶级商用API。注意事项对于企业内部知识库等对数据隐私要求极高的场景本地部署是唯一选择。7B70亿参数级别的模型在消费级显卡如RTX 4060 16G上已经可以流畅运行并能提供相当不错的生成质量完全能满足许多RAG场景的需求。3.4 框架与胶水LangChain和LlamaIndex这两个框架能极大地简化开发流程它们封装了文档加载、文本分割、向量化、检索、Prompt构建等通用步骤。LangChain更像一个“乐高”工具箱提供了极其丰富的组件Chains, Agents, Tools和集成灵活性极高但学习曲线稍陡。LlamaIndex更专注于RAG和数据索引本身API设计可能更直观在复杂查询和索引结构上有独特优势。对于初学者我建议前期可以不用框架或用最轻量的方式。先用手写代码把整个流程加载-分割-向量化-存储-检索-提问走一遍你会对每个环节有更深刻的理解。之后为了提升开发效率再引入框架。本文的实践部分我们将采用“核心环节手写辅助功能用库”的方式确保你能看清每一步。4. 从零开始手把手搭建RAG语义搜索系统下面我们抛开复杂的框架用最直接的Python代码构建一个最小可用的RAG系统。假设我们的知识库是几篇关于机器学习的Markdown文档。4.1 环境准备与依赖安装首先创建一个干净的Python环境推荐使用conda或venv然后安装核心依赖。# 创建并激活环境以conda为例 conda create -n rag_demo python3.10 conda activate rag_demo # 安装核心库 pip install sentence-transformers # 用于加载BGE等Embedding模型 pip install chromadb # 轻量级向量数据库 pip install pypdf2 # 用于读取PDF如果知识库有PDF pip install markdown # 用于解析Markdown pip install beautifulsoup4 # 用于清理HTML标签如果需要 # 如果需要本地LLM例如Qwen # pip install transformers accelerate4.2 知识库预处理与向量化这是最需要细心的一步。垃圾进垃圾出。如果原始文本处理得不好后续检索质量会大受影响。4.2.1 文档加载与文本提取我们写一个简单的函数来加载不同格式的文档。import os from pathlib import Path import markdown from bs4 import BeautifulSoup import PyPDF2 def load_documents(directory_path): 从指定目录加载所有支持格式的文档返回纯文本列表。 texts [] for file_path in Path(directory_path).glob(*): if file_path.suffix.lower() .txt: with open(file_path, r, encodingutf-8) as f: texts.append(f.read()) elif file_path.suffix.lower() .md: with open(file_path, r, encodingutf-8) as f: md_text f.read() # 将markdown转换为html再提取纯文本 html markdown.markdown(md_text) soup BeautifulSoup(html, html.parser) texts.append(soup.get_text()) elif file_path.suffix.lower() .pdf: with open(file_path, rb) as f: reader PyPDF2.PdfReader(f) pdf_text for page in reader.pages: pdf_text page.extract_text() texts.append(pdf_text) # 可以继续添加对.docx, .html等的支持 return texts # 使用示例 doc_texts load_documents(./knowledge_base) print(f共加载了 {len(doc_texts)} 篇文档)4.2.2 文本分割Chunking这是预处理中最关键的技巧之一。不能简单按固定字符数切割那样可能会把一个完整的句子或概念拦腰斩断。from langchain.text_splitter import RecursiveCharacterTextSplitter # 这里我们借用LangChain一个非常好用的分割器避免重复造轮子 def split_documents(texts, chunk_size500, chunk_overlap50): 使用递归字符分割器将长文本分割成小块。 chunk_size: 每个块的大致字符数。 chunk_overlap: 块与块之间的重叠字符数防止上下文断裂。 text_splitter RecursiveCharacterTextSplitter( chunk_sizechunk_size, chunk_overlapchunk_overlap, separators[\n\n, \n, 。, , , , , , ] # 中文优先的分隔符 ) all_chunks [] for text in texts: chunks text_splitter.split_text(text) all_chunks.extend(chunks) return all_chunks # 使用示例 chunks split_documents(doc_texts, chunk_size300, chunk_overlap30) print(f文档被分割成 {len(chunks)} 个文本块)实操心得Chunk大小是门艺术。chunk_size没有绝对标准。太小如100可能丢失上下文检索到的信息碎片化太大如1000可能包含无关噪声稀释核心信息且增加LLM处理负担。我的经验是事实性问答适合较小的块200-400答案通常集中在一两句话里。概念解析、总结适合较大的块500-800需要更完整的上下文。法律、合同文档可能需要按章节或条款分割而不是单纯按字符数。 从300-500开始实验根据检索结果的质量进行调整。chunk_overlap设置chunk_size的10%-20%能有效改善边界问题。4.2.3 生成向量并存入数据库现在我们将每个文本块转化为向量并存储到ChromaDB中。from sentence_transformers import SentenceTransformer import chromadb from chromadb.config import Settings # 1. 初始化Embedding模型 print(正在加载Embedding模型...) # 使用BGE中文模型第一次运行会自动从Hugging Face下载 embed_model SentenceTransformer(BAAI/bge-large-zh-v1.5) # 2. 初始化Chroma客户端数据持久化到本地目录 ./chroma_db chroma_client chromadb.PersistentClient(path./chroma_db) # 3. 创建或获取一个集合Collection相当于一个命名空间下的向量表 collection chroma_client.get_or_create_collection(namemy_knowledge_base) # 4. 为每个文本块生成ID、向量并存入集合 print(正在生成向量并存入数据库...) batch_size 32 # 批量处理提高效率 for i in range(0, len(chunks), batch_size): batch_chunks chunks[i:ibatch_size] batch_ids [fchunk_{j} for j in range(i, min(ibatch_size, len(chunks)))] # 生成向量 batch_embeddings embed_model.encode(batch_chunks, normalize_embeddingsTrue).tolist() # normalize_embeddingsTrue 会将向量归一化方便使用余弦相似度 # 存入数据库 collection.add( embeddingsbatch_embeddings, documentsbatch_chunks, # 同时存储原始文本 idsbatch_ids ) print(f已处理 {min(ibatch_size, len(chunks))}/{len(chunks)} 个块) print(知识库向量化完成)关键点解析normalize_embeddingsTrue这是关键一步它将向量归一化为单位长度模长为1。此时向量间的点积dot product就等于余弦相似度cosine similarity。余弦相似度是衡量语义相似度更常用的指标范围在[-1,1]之间值越大越相似。ChromaDB在存储向量的同时也存储了原始的documents。这样在检索时我们不仅能拿到最相似的向量ID还能直接拿到对应的原始文本片段用于后续构造Prompt。4.3 实现语义检索与问答索引建好了现在来实现核心的问答流程。def rag_query(query_text, top_k3): 执行RAG查询检索 - 构造Prompt - 生成回答这里模拟LLM调用。 # 1. 将用户查询转换为向量 query_embedding embed_model.encode([query_text], normalize_embeddingsTrue).tolist()[0] # 2. 在向量数据库中检索最相似的top_k个文本块 results collection.query( query_embeddings[query_embedding], n_resultstop_k ) retrieved_docs results[documents][0] # 取第一个查询的结果 print(f\n 检索到的相关文本片段Top {top_k}) for i, doc in enumerate(retrieved_docs): print(f\n【片段 {i1}】\n{doc[:200]}...) # 打印前200字符预览 # 3. 构造Prompt context \n\n.join(retrieved_docs) prompt f基于以下背景信息请回答问题。如果信息不足以回答问题请说明。 背景信息 {context} 问题{query_text} 请给出详细、准确的回答 print(f\n 构造的Prompt前500字符\n{prompt[:500]}...\n) # 4. 调用LLM生成答案此处为模拟实际需接入真实LLM # 模拟一个简单的基于规则的“回答”真实场景替换为LLM API调用 simulated_answer f模拟LLM回答根据提供的背景信息问题的核心要点是{query_text} 涉及了机器学习中的相关概念。具体来说检索到的资料提到了相关内容。 # 真实调用示例以OpenAI API为例需安装openai库 # import openai # response openai.ChatCompletion.create( # modelgpt-3.5-turbo, # messages[{role: user, content: prompt}] # ) # real_answer response.choices[0].message.content return simulated_answer, retrieved_docs # 进行查询 question 机器学习中监督学习和无监督学习的主要区别是什么 answer, contexts rag_query(question, top_k2) print(f\n 最终回答 \n{answer})4.4 接入真实的大语言模型上面的simulated_answer只是个占位符。让我们接入一个真实的LLM。这里以使用本地部署的Qwen1.5-7B-Chat模型为例展示如何闭环。from transformers import AutoModelForCausalLM, AutoTokenizer import torch # 加载本地Qwen模型和分词器确保你有足够的GPU内存约15GB print(正在加载本地Qwen模型...) model_name Qwen/Qwen1.5-7B-Chat # 也可以是本地路径 tokenizer AutoTokenizer.from_pretrained(model_name, trust_remote_codeTrue) model AutoModelForCausalLM.from_pretrained( model_name, torch_dtypetorch.float16, # 半精度减少内存占用 device_mapauto, # 自动分配GPU/CPU trust_remote_codeTrue ) def generate_answer_with_llm(prompt): 使用本地Qwen模型生成回答 messages [{role: user, content: prompt}] # 使用模型特定的聊天模板 text tokenizer.apply_chat_template(messages, tokenizeFalse, add_generation_promptTrue) model_inputs tokenizer([text], return_tensorspt).to(model.device) # 生成参数 generated_ids model.generate( **model_inputs, max_new_tokens512, # 最大生成token数 do_sampleTrue, # 启用采样使回答更多样 temperature0.7, # 采样温度控制随机性 top_p0.9, # 核采样参数 ) generated_ids [ output_ids[len(input_ids):] for input_ids, output_ids in zip(model_inputs.input_ids, generated_ids) ] response tokenizer.batch_decode(generated_ids, skip_special_tokensTrue)[0] return response # 修改rag_query函数使用真实的LLM def rag_query_with_llm(query_text, top_k3): query_embedding embed_model.encode([query_text], normalize_embeddingsTrue).tolist()[0] results collection.query( query_embeddings[query_embedding], n_resultstop_k ) retrieved_docs results[documents][0] context \n\n.join(retrieved_docs) prompt f你是一个专业的AI助手请严格根据以下提供的背景信息来回答问题。如果信息中没有明确答案请直接说“根据已有信息无法回答”不要编造信息。 背景信息 {context} 问题{query_text} 请根据以上背景信息回答 print(正在调用LLM生成回答...) answer generate_answer_with_llm(prompt) return answer, retrieved_docs # 现在可以进行真实的问答了 real_question 梯度下降算法是如何工作的 real_answer, _ rag_query_with_llm(real_question) print(f\n问题{real_question}) print(f\nRAG系统回答\n{real_answer})至此一个完整的、从文本处理到向量检索再到本地大模型生成答案的RAG系统就搭建完成了。你可以用自己的知识库文档替换./knowledge_base下的内容体验它如何“听懂”你的问题并从资料中寻找答案。5. 效果优化与高级技巧实录一个能跑通的系统只是起点要让其真正好用还需要大量的“调优”。下面分享几个我踩过坑才总结出的核心优化点。5.1 检索质量优化不止是相似度单纯的向量相似度检索有时会出问题比如检索到的片段虽然语义相关但并不是问题直接需要的答案或者有多篇相关文档时排序不合理。1. 重排序Re-ranking 这是提升答案精度的“杀手锏”。在向量数据库进行初筛例如取出top 20个相关块后使用一个更精细的、专门用于评判“问题-段落”相关性的重排序模型对这20个结果进行重新打分和排序只保留最相关的top 3-5个送入LLM。为什么有效Embedding模型是“无监督”的它衡量的是段落之间的通用语义相似度。而重排序模型如BGE-reranker是“有监督”的专门针对“query和document是否相关”这个任务进行训练判断更精准。如何做# 假设已安装FlagEmbedding库 from FlagEmbedding import FlagReranker reranker FlagReranker(BAAI/bge-reranker-large, use_fp16True) # 加载重排序模型 # 初步检索得到docs和scores initial_results collection.query(...) pairs [[query_text, doc] for doc in initial_results[documents][0]] # 计算重排序分数 rerank_scores reranker.compute_score(pairs) # 根据新分数对docs进行排序和筛选实操心得重排序会显著增加延迟因为要多一次模型推理但能极大提升最终答案的质量尤其是在知识库文档众多、内容交叉的情况下。对于生产系统强烈建议加入此环节。2. 混合搜索Hybrid Search 结合语义搜索向量和关键词搜索全文的结果。例如先用BM25一种经典的关键词评分算法搜一遍再用向量搜一遍最后融合两者的结果。这可以缓解语义搜索有时会遗漏某些精确关键词匹配的重要文档的问题。ChromaDB等数据库已开始支持混合搜索。5.2 Prompt工程优化给LLM清晰的指令Prompt是引导LLM正确利用上下文的关键。糟糕的Prompt会导致LLM忽略上下文或胡编乱造。明确指令开头就强调“严格根据以下信息回答”。提供格式如果需要结构化输出可以指定格式如“请用分点列举的方式回答”。处理未知明确告诉LLM“如果信息不足请说明”这比让它猜要好得多。上下文管理如果检索到的文本块太多可能超出LLM的上下文窗口。需要做截断或摘要。一个技巧是让LLM先对每个检索到的片段做一个一句话摘要然后再基于摘要进行最终回答两步法。5.3 系统性能与稳定性考量索引构建加速对于大规模知识库Embedding过程可能非常耗时。可以使用多进程/多线程批量编码或者利用GPU进行加速。缓存策略对于常见、热点问题可以将“问题-答案”对缓存起来直接返回避免重复的检索和生成开销。异步处理在Web服务中使用异步框架如FastAPI async/await来处理耗时的Embedding和LLM调用避免阻塞。监控与评估建立评估体系定期用一批标准问题测试系统的回答准确率、相关性和延迟。记录每次检索到的文档和生成的答案便于分析bad case。6. 常见问题与排查技巧实录在开发和运维RAG系统的过程中你一定会遇到各种各样的问题。这里列出一个“急救手册”。问题现象可能原因排查步骤与解决方案检索结果完全不相关1. Embedding模型不匹配如用英文模型处理中文。2. 文本分割不合理破坏了语义。3. 向量未归一化相似度计算方式错误。1. 确认使用与文本语言匹配的Embedding模型。2. 检查分割后的chunk看是否把完整的句子拆散了。调整chunk_size和separators。3. 确保生成和检索时都使用了归一化向量并使用余弦相似度。LLM回答无视检索到的上下文开始“胡言乱语”1. Prompt指令不够强硬。2. 检索到的上下文质量太差或无关。3. LLM本身“幻觉”倾向强。1. 强化Prompt如“你必须且只能根据以下背景信息回答”。2. 先检查检索阶段返回的文本是否真的相关。优化检索见5.1。3. 在Prompt中要求列出引用来源或换用“幻觉”更少的模型。回答总是“根据已有信息无法回答”1. 知识库中确实没有相关信息。2. 检索的top_k值太小相关文档没被召回。3. Embedding模型对特定领域如专业术语表征能力弱。1. 扩充知识库。2. 适当增大top_k如从3调到5或10。3. 考虑使用在该领域数据上微调过的Embedding模型或尝试不同的模型。系统响应速度很慢1. Embedding模型推理慢。2. 向量数据库索引未优化或数据量大。3. LLM生成速度慢。1. 考虑使用更轻量的Embedding模型如m3e-base或使用GPU加速。2. 为向量数据库创建合适的索引如HNSW。3. 对LLM回答进行缓存或使用更小、更快的模型。处理长文档时效果差1.chunk_size设置不当上下文断裂。2. 检索时丢失了跨块的关键信息。1. 尝试增大chunk_size或采用按章节/段落的分割策略。2. 在Prompt中提供更多上下文块增大top_k或使用能处理长上下文的LLM。引入重排序筛选最相关的部分。一个典型的Debug流程当答案不满意时不要直接去调LLM的参数。应该按以下顺序排查看输入打印出检索到的原始文本片段。它们真的和问题相关吗如果不相关问题出在检索之前。看Prompt打印出发送给LLM的完整Prompt。指令清晰吗上下文完整吗看输出如果输入和Prompt都没问题再考虑调整LLM的参数如temperature或更换模型。7. 项目总结与未来展望走完这一趟从零开始的实现之旅你应该已经深刻体会到让AI“听懂弦外之音”的RAG语义搜索并不是一个神秘的黑盒子而是一系列可理解、可操控的技术组件的有机结合。它的核心价值在于为我们提供了一种将静态知识库动态化、智能化的低成本路径。回顾整个项目有几个关键决策点决定了系统的上限Embedding模型的选择决定了语义理解的基线能力文本分割的策略决定了知识“封装”的粒度检索与重排序的搭配决定了找到正确答案的概率而最终的Prompt设计则决定了LLM能否妥当地运用这些找到的知识。从我个人的实践经验来看RAG系统上线后真正的挑战才刚刚开始。你需要像一个数据产品经理一样持续地收集用户的实际提问分析那些回答不好或出错的案例bad cases。你会发现很多问题源于知识库本身的缺失或歧义这时就需要反哺知识库的建设和清洗。另一些情况可能需要对检索策略进行微调比如针对某些特定类型的问题是否需要单独建立索引或采用不同的分割方式。未来这个基础的RAG框架还可以向多个方向演进多轮对话让系统记住之前的对话历史实现连贯的、上下文相关的问答。多模态RAG不仅处理文本还能处理图片、表格、音频中的信息进行跨模态检索。Agentic RAG让RAG系统具备自主决策能力例如当一次检索结果不理想时能自动改写查询词再次检索或者决定去调用某个计算工具来辅助生成答案。但无论如何演进其根本——用检索找到相关知识用生成组织自然语言回答——这一核心思想不会变。掌握了今天这套从数据准备、向量化、检索到生成的完整流程你就已经拿到了进入更智能信息处理世界的大门钥匙。接下来就是用你的业务数据和具体场景去不断打磨和迭代它让它真正成为你或你团队的高效“第二大脑”。
返回列表