将JSON数据转为向量库,优化LangChain大学聊天机器人响应速度
问题背景
我正在为大学网站开发聊天机器人项目,目前用LangChain结合JSON数据实现了功能(代码如下),但每次查询都要遍历JSON所有层级,响应速度很慢。需要将复杂的文凭信息JSON转换为向量数据库,提升响应速度。
现有实现代码
from langchain_google_genai import ChatGoogleGenerativeAI from langchain.agents import create_json_agent from langchain.agents.agent_toolkits import JsonToolkit from langchain.tools.json.tool import JsonSpec import json with open(r'...formation_initial.json','r') as f: data = json.load(f) f.close() spec = JsonSpec(dict_=data, max_value_length=4000) toolkit = JsonToolkit(spec=spec) agent = create_json_agent(llm=llm, toolkit=toolkit, verbose=True) print(agent.run('quelle sont les modules de master intelligence artificielle et sciences de donnees semestre 1'))
示例JSON数据片段
{ "DEUST": { "Analytique des données": { "objectif": "La Licence Science et Techniques en analytique des données permet aux étudiants de doter de compétences en matière d'outils informatiques, de techniques et des méthodes statistiques pour permettre d'organiser, de synthétiser et de traduire efficacement les données métier d'une organisation. L'étudiant doit être en mesure d'apporter un appui analytique à la conduite d'exploration et à l'analyse complexe de données. ", "COMPETENCES VISEES ET DEBOUCHES": "Masters en sciences de données: fouille de données, business analytiques, blockchain,Masters orientés e-Technologies: e-Business, e-Administration et e-LogistiqueFormations d'Ingénieurs dans une école d'ingénieurs à l'issue de la deuxième ou de la troisième année de licenceData scientistTechnicien supérieur en SGBD R : installation, configuration et administration des SGBDWebMaster et développeur de sites web dynamiquesIntégration du monde du travail dans les entreprises et les bureaux d'études ", "coordinateur": {"nom": "Pr.BAIDA Ouafae", "email": "wbaida@uae.ac.ma"}, "semesters": [ {"Semestre 5": [" Mathématiques pour la science des données", " Structures des données avancées et théorie des graphes", " Fondamentaux des bases de données", " Algorithmique avancée et programmation", " Développement WEB", " Développement personnel et intelligence émotionnelle (Soft skills)"]}, {"Semestre 6": [" Analyse et fouille de données", " Systèmes et réseaux", " Ingénierie des données ", " PFE"]} ] } } }
可行解决方案
核心思路是将嵌套JSON拆分为独立的、有意义的文本块,生成向量后存入向量数据库,查询时通过向量检索快速定位相关内容,再传给LLM生成回答。
1. 数据扁平化与文本转换
将嵌套的JSON结构拆分为多个独立的信息单元,每个单元转换为自然语言文本,同时保留元数据(用于后续过滤)。例如:
- 专业基础信息块:
"文凭类型:DEUST,专业:Analytique des données,培养目标:[objectif文本],就业方向:[COMPETENCES VISEES ET DEBOUCHES文本],协调人:Pr.BAIDA Ouafae,邮箱:wbaida@uae.ac.ma" - 学期课程信息块:
"文凭类型:DEUST,专业:Analytique des données,学期:Semestre 5,课程列表:Mathématiques pour la science des données、Structures des données avancées et théorie des graphes、Fondamentaux des bases de données、Algorithmique avancée et programmation、Développement WEB、Développement personnel et intelligence émotionnelle (Soft skills)"
自动生成文本块的示例代码:
def flatten_json(data, parent_keys=[], chunks=[]): if isinstance(data, dict): for key, value in data.items(): new_keys = parent_keys + [key] if isinstance(value, (dict, list)): flatten_json(value, new_keys, chunks) else: # 组合基础信息文本 text_parts = [] for p in parent_keys: if isinstance(data.get(p), str): text_parts.append(f"{p}: {data.get(p)}") text_parts.append(f"{key}: {value}") text = " | ".join(text_parts) chunks.append({"text": text, "metadata": {"path": ".".join(new_keys)}}) elif isinstance(data, list): for idx, item in enumerate(data): new_keys = parent_keys + [f"item_{idx}"] if isinstance(item, (dict, list)): flatten_json(item, new_keys, chunks) else: text = f"{' > '.join(parent_keys)}: {item}" chunks.append({"text": text, "metadata": {"path": ".".join(new_keys)}}) return chunks # 处理示例JSON flattened_chunks = flatten_json(data)
2. 生成嵌入向量并存储到向量数据库
使用与LLM配套的嵌入模型(如GoogleGenerativeAIEmbeddings)将文本块转换为向量,存入LangChain支持的向量数据库(以轻量本地的Chroma为例):
from langchain_google_genai import GoogleGenerativeAIEmbeddings from langchain.vectorstores import Chroma from langchain.text_splitter import CharacterTextSplitter from langchain.docstore.document import Document # 将文本块转换为LangChain Document对象 documents = [Document(page_content=chunk["text"], metadata=chunk["metadata"]) for chunk in flattened_chunks] # 初始化嵌入模型 embeddings = GoogleGenerativeAIEmbeddings(model="models/embedding-001", google_api_key="YOUR_API_KEY") # 将文档存入Chroma向量库 vector_db = Chroma.from_documents( documents=documents, embedding=embeddings, persist_directory="./university_embeddings" ) vector_db.persist()
3. 构建快速查询流程
查询时先通过向量检索获取最相关的文本块,再将这些文本作为上下文传给LLM生成回答:
from langchain.chains import RetrievalQA # 构建检索链 qa_chain = RetrievalQA.from_chain_type( llm=llm, chain_type="stuff", retriever=vector_db.as_retriever(search_kwargs={"k": 3}), # 取最相关的3个结果 return_source_documents=True ) # 执行查询 query = "quelle sont les modules de master intelligence artificielle et sciences de donnees semestre 1" result = qa_chain({"query": query}) print(result["result"])
优化建议
- 元数据过滤:存储时添加更丰富的元数据(如
diploma_type、major、semester),查询时可通过元数据过滤缩小检索范围,进一步提升速度。 - 文本块优化:避免过于细碎的文本块,将相关信息组合成连贯的段落,提升LLM回答的准确性。
- 向量数据库选择:如果数据量较大,可选择云端向量数据库或高性能本地库(如FAISS)。
内容的提问来源于stack exchange,提问作者Ayman Ait
相关产品推荐
相关产品推荐

