大家好,今天给大家带来的主题是:检索增强生成系统RAG。
引言:AI的“知识瓶颈”与我们的尴尬
不知道大家在使用ChatGPT等大语言模型时,有没有遇到过这样的尴尬:问它一些最新的新闻,它答非所问;或者让它推荐一家你所在城市新开的餐厅,它开始胡编乱造。
更可怕的是在专业领域,比如医疗、法律、金融。如果你问它:“我最近头痛、流清鼻涕、怕冷,是什么感冒?该吃什么药?”它可能会给你一个看似合理但完全错误的答案,比如推荐你吃用于风热感冒的板蓝根,而你的症状其实是风寒感冒。
为什么无所不能的AI会“胡说八道”?
核心原因在于:大模型的知识来源于其训练时的数据,它无法感知和学习训练截止日期之后的新知识,也无法访问它“不知道”的私有或特定领域数据。 这种现象我们称之为“模型幻觉”或“胡说八道”。
那么,有没有办法让AI在回答问题时,能像我们人类一样,先去“翻书”查阅最新的、可靠的资料,然后再结合自己的理解来回答呢?
有!这就是今天的主角——检索增强生成。
第一部分:理论篇 - RAG,AI的“实时百科全书”
1. 什么是RAG?
RAG,全称Retrieval-Augmented Generation,即“检索增强生成”。你可以把它理解成给AI配了一个智能的、即时的“随身百科全书”。
当AI收到一个问题时,它不再仅仅依赖自己内存(训练数据)中的知识,而是会执行以下三个步骤:
-
检索:先去一个指定的、可信的“知识库”(比如你的公司文档、最新的行业报告、权威医学典籍)里,查找与问题最相关的内容片段。
-
增强:把找到的相关内容片段和用户的原始问题“打包”在一起,形成一个新的、信息更丰富的提示。
-
生成:基于这个“增强后”的提示,生成最终的回答。
简单比喻:
-
没有RAG的AI:像一个参加闭卷考试的学生,只能靠自己背过的东西答题,超纲了就瞎蒙。
-
有RAG的AI:像一个参加开卷考试的学生,允许他带一本指定的百科全书进去。遇到不确定的,先翻书查证,再组织语言写出答案。
2. RAG的核心工作流程
一个典型的RAG系统包含两个核心环节:
环节一:知识库准备(给“百科全书”排版印刷)
-
加载:收集你的知识源,如PDF、Word、网页内容等。
-
切分:将长文档切成小块,方便后续检索。
-
向量化:使用Embedding模型将每个文本块转换成数学上的“向量”。这个向量可以理解为文本在数字世界里的“DNA指纹”,语义相近的文本,其向量也相似。
-
存储:将这些向量及其对应的原始文本存入“向量数据库”。
环节二:问答流程(学生开卷答题)
-
用户提问:“头痛、流清鼻涕、怕冷,是什么感冒?”
-
检索:
-
将用户的问题也通过同样的Embedding模型转换成向量。
-
在向量数据库中,搜索与“问题向量”最相似的几个“知识块向量”。
-
(底层原理:通过计算向量之间的余弦相似度或点积,找到语义上最接近的内容。)
-
-
增强:
-
将检索到的知识块(例如,从《中医内科学》中检索到关于“风寒感冒”和“风热感冒”的鉴别诊断条文)和用户原始问题一起,组合成一个新的提示词给大模型。
-
提示词模板示例:
请根据以下背景知识来回答问题。
【背景知识】
{这里是检索到的关于感冒辨证的知识}
【问题】
{用户的原始问题}
【要求】
请严格依据背景知识进行回答,如果背景知识中没有提到,请明确告知“根据现有资料无法确定”。
-
-
生成:
-
大模型接收到这个“增强后”的提示,它会严格依据你提供的背景知识来生成答案,从而大大减少了胡说八道的可能。
-
第二部分:实战篇 - 用Python打造一个AI“老中医”
现在,我们以“中医感冒问诊”为例,亲手搭建一个简单的RAG系统。
场景设定:我们有一个关于感冒辨证的权威知识库(一个TXT文件),我们希望AI能基于这个知识库来回答用户关于感冒症状的问题。
步骤1:准备知识库(模拟权威医书)
我们创建一个 knowledge_base.txt 文件,内容如下:
【感冒的辨证分型与治疗】
1. 风寒感冒
主要症状:恶寒重,发热轻,无汗,头痛,肢节酸疼,鼻塞声重,或鼻痒喷嚏,时流清涕,咽痒,咳嗽,痰吐稀薄色白。
舌苔:薄白。
脉象:浮或浮紧。
病因病机:风寒外束,卫阳被郁,腠理闭塞,肺气不宣。
治法:辛温解表。
常用方剂:荆防达表汤或荆防败毒散。
药物组成:荆芥、防风、苏叶、豆豉、葱白、生姜等。
2. 风热感冒
主要症状:身热较著,微恶风,汗泄不畅,头胀痛,面赤,咳嗽,痰黏或黄,咽燥,或咽喉乳蛾红肿疼痛,鼻塞,流黄浊涕。
舌苔:薄白微黄,舌边尖红。
脉象:浮数。
病因病机:风热犯表,热郁肌腠,卫表失和,肺失清肃。
治法:辛凉解表。
常用方剂:银翘散、葱豉桔梗汤。
药物组成:银花、连翘、栀子、豆豉、薄荷、荆芥等。
3. 暑湿感冒
主要症状:身热,微恶风,汗少,肢体酸重或疼痛,头昏重胀痛,咳嗽痰黏,鼻流浊涕,心烦口渴,或口中黏腻,渴不多饮,胸闷脘痞,恶心,腹胀。
舌苔:薄黄而腻。
脉象:濡数。
病因病机:暑湿遏表,湿热伤中,表卫不和,肺气不清。
治法:清暑祛湿解表。
常用方剂:新加香薷饮。
药物组成:香薷、银花、鲜扁豆花、厚朴、连翘等。
4. 体虚感冒
主要症状:发热不高,反复发作,自汗,面色晄白,恶风怕冷,鼻塞流清涕,肢软乏力,胃纳不香。
舌苔:薄白。
脉象:浮而无力。
病因病机:体质虚弱,卫外不固,风寒乘袭。
治法:扶正解表。
常用方剂:参苏饮、玉屏风散。
【鉴别诊断要点】
风寒感冒:以恶寒重、发热轻、无汗、流清涕为特征。
风热感冒:以发热重、恶寒轻、咽喉肿痛、流黄涕为特征。
暑湿感冒:多发于夏季,以身热不扬、头身困重、胸闷脘痞为特征。
【治疗注意事项】
1. 辨证要准确,用药要对证
2. 服药期间忌食生冷、油腻、辛辣食物
3. 注意休息,多饮温水
4. 如病情加重或出现新症状,应及时就医
步骤2:代码实现(附详细注释)
# 导入必要的库
import os
import json
import requests
from typing import List, Dict, Any
import chromadb
from chromadb.config import Settings
import hashlib
import time
from dotenv import load_dotenv
# 加载.env文件
load_dotenv()
class TCMRAGSystem:
"""中医RAG系统 - 使用HTTP请求直接调用API"""
def __init__(self, api_key: str = None, base_url: str = None, persist_directory: str = "./chroma_db"):
"""
初始化RAG系统
Args:
api_key: OpenAI兼容API密钥,如果为None则从环境变量读取
base_url: API基础URL,如果为None则从环境变量读取
persist_directory: 向量数据库存储目录
"""
# 从参数或环境变量获取API配置
self.api_key = api_key or os.getenv("OPENAI_API_KEY")
self.base_url = base_url or os.getenv("OPENAI_BASE_URL")
# 验证配置
if not self.api_key:
raise ValueError("未找到API密钥,请设置OPENAI_API_KEY环境变量或在代码中提供")
if not self.base_url:
raise ValueError("未找到API基础URL,请设置OPENAI_BASE_URL环境变量或在代码中提供")
# 初始化Chroma向量数据库
self.chroma_client = chromadb.PersistentClient(path=persist_directory)
# 创建或获取集合
self.collection = self.chroma_client.get_or_create_collection(
name="tcm_knowledge",
metadata={"description": "中医感冒辨证知识库"}
)
# 使用兼容性更好的embedding模型
self.embedding_model = "text-embedding-ada-002" # 更通用的模型
print(" RAG系统初始化完成")
def create_text_chunks(self, text: str, chunk_size: int = 500, chunk_overlap: int = 50) -> List[str]:
"""
将文本分割成块
Args:
text: 原始文本
chunk_size: 块大小
chunk_overlap: 重叠大小
Returns:
文本块列表
"""
sentences = text.replace('\n', ' ').split('。')
chunks = []
current_chunk = ""
for sentence in sentences:
sentence = sentence.strip()
if not sentence:
continue
# 如果当前块加上新句子不会超过大小,就添加
if len(current_chunk) + len(sentence) <= chunk_size:
current_chunk += sentence + "。"
else:
# 保存当前块并开始新块
if current_chunk:
chunks.append(current_chunk.strip())
current_chunk = sentence + "。"
# 添加最后一个块
if current_chunk:
chunks.append(current_chunk.strip())
print(f" 文本分割完成,共{len(chunks)}个块")
return chunks
def make_api_request(self, endpoint: str, data: Dict) -> Dict:
"""
发送API请求
Args:
endpoint: API端点
data: 请求数据
Returns:
响应数据
"""
# 确保base_url不以斜杠结尾
base_url = self.base_url.rstrip('/')
url = f"{base_url}/{endpoint}"
headers = {
"Content-Type": "application/json",
"Authorization": f"Bearer {self.api_key}"
}
try:
response = requests.post(url, headers=headers, json=data, timeout=60)
response.raise_for_status()
return response.json()
except requests.exceptions.RequestException as e:
print(f" API请求失败: {e}")
if hasattr(e, 'response') and e.response is not None:
print(f"响应状态码: {e.response.status_code}")
print(f"响应内容: {e.response.text}")
raise
def get_embedding(self, text: str) -> List[float]:
"""
获取文本的向量嵌入
Args:
text: 输入文本
Returns:
向量嵌入列表
"""
try:
# 确保文本是UTF-8编码
if isinstance(text, str):
text = text.encode('utf-8', 'ignore').decode('utf-8')
# 如果文本为空,返回默认向量
if not text.strip():
return [0.0] * 1536
# 准备请求数据
data = {
"model": self.embedding_model,
"input": text
}
# 发送请求
response = self.make_api_request("embeddings", data)
# 提取embedding
if "data" in response and len(response["data"]) > 0:
return response["data"][0]["embedding"]
else:
raise ValueError("响应中未找到embedding数据")
except Exception as e:
print(f" 获取embedding失败: {e}")
# 返回一个空向量作为fallback
return [0.0] * 1536 # 默认维度是1536
def load_knowledge_to_vector_db(self, file_path: str):
"""
将知识库文件加载到向量数据库
Args:
file_path: 知识库文件路径
"""
try:
# 检查文件是否存在
if not os.path.exists(file_path):
raise FileNotFoundError(f"知识库文件不存在: {file_path}")
# 读取知识库文件,使用UTF-8编码
with open(file_path, 'r', encoding='utf-8') as f:
content = f.read()
# 分割文本
chunks = self.create_text_chunks(content)
# 准备数据
documents = []
metadatas = []
ids = []
embeddings = []
print(" 正在生成文档向量...")
for i, chunk in enumerate(chunks):
print(f"处理文档块 {i + 1}/{len(chunks)}")
# 生成唯一ID
chunk_hash = hashlib.md5(chunk.encode('utf-8')).hexdigest()[:8]
doc_id = f"chunk_{i}_{chunk_hash}"
# 获取embedding
embedding = self.get_embedding(chunk)
documents.append(chunk)
metadatas.append({"chunk_id": i, "source": file_path})
ids.append(doc_id)
embeddings.append(embedding)
# 批量添加到向量数据库
print(" 保存到向量数据库...")
self.collection.add(
embeddings=embeddings,
documents=documents,
metadatas=metadatas,
ids=ids
)
print(f" 知识库加载完成,共{len(documents)}个文档块")
except Exception as e:
print(f" 加载知识库失败: {e}")
def search_similar_documents(self, query: str, n_results: int = 3) -> List[Dict[str, Any]]:
"""
在向量数据库中搜索相似文档
Args:
query: 查询文本
n_results: 返回结果数量
Returns:
相似文档列表
"""
try:
# 获取查询的embedding
query_embedding = self.get_embedding(query)
# 在向量数据库中搜索
results = self.collection.query(
query_embeddings=[query_embedding],
n_results=n_results
)
# 整理结果
similar_docs = []
if results['documents']:
for i, doc in enumerate(results['documents'][0]):
similar_docs.append({
'content': doc,
'distance': results['distances'][0][i] if results['distances'] else 0,
'metadata': results['metadatas'][0][i] if results['metadatas'] else {}
})
print(f" 检索到{len(similar_docs)}个相关文档")
return similar_docs
except Exception as e:
print(f" 搜索失败: {e}")
return []
def safe_text(self, text: str) -> str:
"""
安全处理文本,确保不包含编码问题
Args:
text: 输入文本
Returns:
安全处理后的文本
"""
if not isinstance(text, str):
return ""
# 移除可能的不可见字符
text = text.replace('\ufeff', '') # 移除BOM标记
# 确保UTF-8编码
try:
text = text.encode('utf-8', 'ignore').decode('utf-8')
except:
# 如果仍然有问题,使用更保守的方法
text = ''.join(char for char in text if ord(char) < 55296 or (ord(char) > 57343 and ord(char) < 65534))
return text
def build_rag_prompt(self, question: str, context_docs: List[Dict]) -> str:
"""
构建RAG提示词
Args:
question: 用户问题
context_docs: 相关文档
Returns:
构建好的提示词
"""
# 安全处理所有文本
safe_question = self.safe_text(question)
safe_context = "\n\n".join([self.safe_text(doc['content']) for doc in context_docs])
prompt = f"""你是一位专业的中医AI助手,请严格根据以下提供的医学知识来回答用户的问题。
【相关医学知识】
{safe_context}
【用户问题】
{safe_question}
【回答要求】
1. 必须基于上述医学知识进行回答,不能编造知识以外的信息
2. 如果医学知识中没有相关信息,请明确告知"根据现有医学资料,我无法判断您的情况,建议咨询专业医师"
3. 回答要专业、准确、有条理
4. 如果涉及具体方剂,请注明出处和适用症状
5. 最后必须加上免责声明:以上建议仅供参考,具体诊疗请咨询专业医师
请开始回答:"""
return prompt
def chat_completion(self, messages: List[Dict], model: str = "gpt-3.5-turbo", temperature: float = 0.1,
max_tokens: int = 1000) -> str:
"""
调用聊天补全API
Args:
messages: 消息列表
model: 模型名称
temperature: 温度参数
max_tokens: 最大token数
Returns:
AI回复内容
"""
try:
# 准备请求数据
data = {
"model": model,
"messages": messages,
"temperature": temperature,
"max_tokens": max_tokens
}
# 发送请求
response = self.make_api_request("chat/completions", data)
# 提取回复内容
if "choices" in response and len(response["choices"]) > 0:
return response["choices"][0]["message"]["content"]
else:
raise ValueError("响应中未找到回复内容")
except Exception as e:
raise Exception(f"聊天补全API调用失败: {e}")
def ask_question(self, question: str) -> str:
"""
向RAG系统提问
Args:
question: 用户问题
Returns:
AI回答
"""
print(f"\n 用户提问: {question}")
# 1. 检索相关文档
similar_docs = self.search_similar_documents(question)
if not similar_docs:
return "抱歉,在知识库中没有找到相关信息,建议咨询专业医师。"
# 2. 构建增强提示词
rag_prompt = self.build_rag_prompt(question, similar_docs)
# 3. 调用大模型生成回答
try:
# 确保提示词安全
safe_prompt = self.safe_text(rag_prompt)
# 准备消息
messages = [
{"role": "system", "content": "你是一位专业的中医助手。"},
{"role": "user", "content": safe_prompt}
]
# 调用聊天补全API
answer = self.chat_completion(
messages=messages,
model="gpt-3.5-turbo",
temperature=0.1,
max_tokens=1000
)
return answer
except Exception as e:
return f"生成回答时出现错误: {e}"
def get_collection_info(self) -> Dict[str, Any]:
"""获取集合信息"""
try:
count = self.collection.count()
return {
"document_count": count,
"collection_name": self.collection.name
}
except:
return {"document_count": 0, "collection_name": "unknown"}
def create_sample_knowledge_file():
"""创建示例知识库文件"""
content = """
【感冒的辨证分型与治疗】
1. 风寒感冒
主要症状:恶寒重,发热轻,无汗,头痛,肢节酸疼,鼻塞声重,或鼻痒喷嚏,时流清涕,咽痒,咳嗽,痰吐稀薄色白。
舌苔:薄白。
脉象:浮或浮紧。
病因病机:风寒外束,卫阳被郁,腠理闭塞,肺气不宣。
治法:辛温解表。
常用方剂:荆防达表汤或荆防败毒散。
药物组成:荆芥、防风、苏叶、豆豉、葱白、生姜等。
2. 风热感冒
主要症状:身热较著,微恶风,汗泄不畅,头胀痛,面赤,咳嗽,痰黏或黄,咽燥,或咽喉乳蛾红肿疼痛,鼻塞,流黄浊涕。
舌苔:薄白微黄,舌边尖红。
脉象:浮数。
病因病机:风热犯表,热郁肌腠,卫表失和,肺失清肃。
治法:辛凉解表。
常用方剂:银翘散、葱豉桔梗汤。
药物组成:银花、连翘、栀子、豆豉、薄荷、荆芥等。
3. 暑湿感冒
主要症状:身热,微恶风,汗少,肢体酸重或疼痛,头昏重胀痛,咳嗽痰黏,鼻流浊涕,心烦口渴,或口中黏腻,渴不多饮,胸闷脘痞,恶心,腹胀。
舌苔:薄黄而腻。
脉象:濡数。
病因病机:暑湿遏表,湿热伤中,表卫不和,肺气不清。
治法:清暑祛湿解表。
常用方剂:新加香薷饮。
药物组成:香薷、银花、鲜扁豆花、厚朴、连翘等。
4. 体虚感冒
主要症状:发热不高,反复发作,自汗,面色晄白,恶风怕冷,鼻塞流清涕,肢软乏力,胃纳不香。
舌苔:薄白。
脉象:浮而无力。
病因病机:体质虚弱,卫外不固,风寒乘袭。
治法:扶正解表。
常用方剂:参苏饮、玉屏风散。
【鉴别诊断要点】
风寒感冒:以恶寒重、发热轻、无汗、流清涕为特征。
风热感冒:以发热重、恶寒轻、咽喉肿痛、流黄涕为特征。
暑湿感冒:多发于夏季,以身热不扬、头身困重、胸闷脘痞为特征。
【治疗注意事项】
1. 辨证要准确,用药要对证
2. 服药期间忌食生冷、油腻、辛辣食物
3. 注意休息,多饮温水
4. 如病情加重或出现新症状,应及时就医
"""
with open("tcm_knowledge_base.txt", "w", encoding="utf-8") as f:
f.write(content)
print(" 示例知识库文件创建完成: tcm_knowledge_base.txt")
def check_env_file():
"""检查.env文件配置"""
env_path = ".env"
if os.path.exists(env_path):
print(f" 找到.env文件: {os.path.abspath(env_path)}")
else:
print(" 未找到.env文件,将使用系统环境变量")
# 检查必要的环境变量
api_key = os.getenv("OPENAI_API_KEY")
base_url = os.getenv("OPENAI_BASE_URL")
if not api_key:
print(" 错误: 未设置OPENAI_API_KEY环境变量")
return False
if not base_url:
print(" 错误: 未设置OPENAI_BASE_URL环境变量")
return False
print(f" 环境变量检查通过")
return True
def main():
"""主函数"""
print("=" * 70)
print(" 中医RAG问诊系统 ")
print("=" * 70)
# 检查环境配置
print("\n 检查环境配置...")
if not check_env_file():
print("\n 请创建.env文件并添加以下配置:")
print("OPENAI_API_KEY=你的API密钥")
print("OPENAI_BASE_URL=https://api.你的服务商.com/v1")
return
# 创建示例知识库文件
if not os.path.exists("tcm_knowledge_base.txt"):
create_sample_knowledge_file()
# 初始化RAG系统
print("\n 正在初始化RAG系统...")
try:
rag_system = TCMRAGSystem() # 不传参数,从环境变量读取
# 加载知识库到向量数据库(首次运行需要)
collection_info = rag_system.get_collection_info()
if collection_info["document_count"] == 0:
print("\n 正在加载知识库到向量数据库...")
rag_system.load_knowledge_to_vector_db("tcm_knowledge_base.txt")
else:
print(f"\n 向量数据库中已有 {collection_info['document_count']} 个文档")
# 演示问诊
print("\n" + "=" * 70)
print(" 开始问诊演示")
print("=" * 70)
# 测试用例
test_cases = [
"我头痛,流清鼻涕,怕冷,不出汗,这是什么类型的感冒?该用什么方子?",
"感冒咳嗽,痰是白色的,很稀,有点气喘,该怎么办?"
]
for i, question in enumerate(test_cases, 1):
print(f"\n{'=' * 50}")
print(f"案例 {i}:")
print(f"{'=' * 50}")
# 获取回答
answer = rag_system.ask_question(question)
print(f"\n AI中医回答:")
print("-" * 30)
print(answer)
print("-" * 30)
# 在案例之间暂停
if i < len(test_cases):
input("\n 按回车继续下一个案例...")
print(f"\n{'=' * 70}")
print(" 问诊演示结束")
print(f"{'=' * 70}")
# 显示系统信息
final_info = rag_system.get_collection_info()
print(f"\n 系统统计:")
print(f" - 向量数据库文档数量: {final_info['document_count']}")
print(f" - 集合名称: {final_info['collection_name']}")
print(f" - 知识库文件: tcm_knowledge_base.txt")
print(f" - Embedding模型: {rag_system.embedding_model}")
print(f" - API基础URL: {rag_system.base_url}")
except Exception as e:
print(f" 系统初始化失败: {e}")
print("\n 可能的解决方案:")
print("1. 检查.env文件配置是否正确")
print("2. 检查网络连接是否正常")
print("3. 检查API服务是否可用")
if __name__ == "__main__":
main()
步骤3:运行结果
======================================================================
中医RAG问诊系统
======================================================================
检查环境配置...
找到.env文件: E:\Py-Spaces\PythonProject\ai_project\rag\.env
环境变量检查通过
正在初始化RAG系统...
RAG系统初始化完成
向量数据库中已有 2 个文档
======================================================================
开始问诊演示
======================================================================
==================================================
案例 1:
==================================================
用户提问: 我头痛,流清鼻涕,怕冷,不出汗,这是什么类型的感冒?该用什么方子?
检索到2个相关文档
AI中医回答:
------------------------------
根据您描述的症状:头痛、流清鼻涕、怕冷、不出汗,这符合风寒感冒的特征。风寒感冒的主要症状包括恶寒重、发热轻、无汗、流清涕等。
针对风寒感冒,推荐使用的方剂是荆防达表汤或荆防败毒散。这些方剂的主要药物组成包括荆芥、防风、苏叶、豆豉、葱白、生姜等,具有辛温解表的作用。
请注意以下治疗注意事项:
1. 辨证要准确,用药要对证。
2. 服药期间忌食生冷、油腻、辛辣食物。
3. 注意休息,多饮温水。
4. 如病情加重或出现新症状,应及时就医。
以上建议仅供参考,具体诊疗请咨询专业医师。
------------------------------
按回车继续下一个案例...
实战总结:看!通过RAG,我们成功地将AI的回答“锁定”在了我们提供的权威知识范围内。它不再凭空想象一个“风热感冒”出来,而是有理有据地给出了“风寒感冒”的诊断和方剂建议。
第三部分:总结与展望
RAG的优势:
-
知识实时性:只需更新知识库,AI就能获取最新知识,无需重新训练模型,成本极低。
-
答案准确性 & 可信度:基于事实来源生成答案,减少幻觉,特别适合专业领域。
-
可解释性:可以要求AI列出其回答所引用的来源,方便追溯和验证。
-
处理私有数据:可以将公司内部文档、个人笔记作为知识库,打造专属AI助手。
RAG的应用场景远不止中医问诊:
-
智能客服:基于最新的产品文档回答用户问题。
-
企业知识库助手:员工可以随时询问公司制度、项目历史。
-
法律顾问:快速检索法律条文和案例。
-
学术研究:基于最新的论文库进行问答和文献综述。
结语
RAG技术巧妙地将大语言模型强大的理解生成能力与外部知识库的准确性和实时性结合在一起,是解决AI“胡说八道”问题的一剂良药。它让AI从“闭卷考试”变成了“开卷考试”,为我们构建可靠、可信、专业的AI应用打开了新的大门。
希望本文的理论讲解和代码实战能帮助你彻底理解RAG。赶紧动手,为你自己的AI项目也配上一本“实时百科全书”吧!
源代码如需获取,请关注公众号(优趣AI),发送消息ufunai-rag获取,扫一扫即可获取!
创作不易,码字更不易,如果觉得这篇文章对你有帮助,记得点个关注、在看或收藏,给作者一点鼓励吧~

被折叠的 条评论
为什么被折叠?



