如何在Python中为Azure OpenAI聊天机器人添加.npz向量化数据
问题分析与修复方案
核心问题
你的代码根本没把ID对应的实际文本内容传给OpenAI,只是传了个ID占位符,模型自然没法基于你的数据回答。另外还有向量匹配一致性、消息格式的问题,具体如下:
1. 缺失ID到原始文本的映射
你加载了vectors和ids,但没有保存/加载每个ID对应的原始文本内容。现在代码里生成的relevant_content只是一句无意义的占位符,没有实际信息。
2. 向量生成模型不匹配(潜在问题)
必须确保combined_vectors.npz里的向量是用同一个SentenceTransformer模型(all-MiniLM-L6-v2)生成的,否则向量空间不兼容,搜索到的内容完全不相关。
3. 上下文消息格式不合理
你把上下文作为system消息塞进聊天历史,容易被模型忽略,重复添加还会导致上下文混乱。正确做法是把上下文放在用户提问前,明确提示模型基于该内容回答。
修复步骤与代码修改
第一步:更新npz文件,加入原始文本
生成向量时,要把原始文本也存入npz文件,示例代码:
# 生成向量时的逻辑(需替换成你自己的原始文本数据) from sentence_transformers import SentenceTransformer import numpy as np model = SentenceTransformer('all-MiniLM-L6-v2') texts = ["产品A的参数是XX", "服务B的流程为XX", ...] # 你的原始业务数据 vectors = model.encode(texts) ids = np.arange(len(texts)) # 自定义ID或自增索引均可 # 保存时新增texts字段 np.savez("combined_vectors.npz", vectors=vectors, ids=ids, texts=texts)
第二步:修改加载与检索逻辑
更新加载函数,把文本一起加载,并直接返回最相关的文本内容:
def load_vector_data(file_path="combined_vectors.npz"): data = np.load(file_path) vectors = data['vectors'] ids = data['ids'] texts = data['texts'] # 新增加载原始文本 index = faiss.IndexFlatL2(vectors.shape[1]) index.add(vectors) return index, ids, texts # 返回文本集合 def find_relevant_data(user_input_vector, index, all_texts): # 搜索最相似的向量,返回对应文本 D, I = index.search(np.array([user_input_vector]), k=1) relevant_text = all_texts[I[0][0]] return relevant_text
第三步:调整消息格式,正确传入上下文
修改聊天函数,把上下文嵌入用户提问中,明确提示模型使用该内容:
async def chat_with_bot(user_input, index, all_texts, model): global chat_history_chunk user_input_vector = model.encode([user_input])[0] relevant_text = find_relevant_data(user_input_vector, index, all_texts) # 构造带上下文的用户消息,明确告知模型基于上下文回答 user_message_content = f"""基于以下上下文回答我的问题: {relevant_text} 我的问题:{user_input}""" chat_history_chunk.append({"role": "user", "content": user_message_content}) if len(chat_history_chunk) > var_past_messages_included: chat_history_chunk = chat_history_chunk[-var_past_messages_included:] messages = system_message_chunk + few_shot_chunk + chat_history_chunk response = await openai.ChatCompletion.acreate( deployment_id=AZURE_OPENAI_API_MODEL, messages=messages, temperature=var_temperature, max_tokens=var_max_tokens, top_p=var_top_p, frequency_penalty=var_frequency_penalty, presence_penalty=var_presence_penalty ) chat_history_chunk.append({"role": "assistant", "content": response['choices'][0]['message']['content']}) return response['choices'][0]['message']['content']
第四步:更新主函数参数
async def main(): index, all_ids, all_texts = load_vector_data() # 接收文本参数 model = SentenceTransformer('all-MiniLM-L6-v2') while True: user_input = input("You: ") if user_input.lower() == "exit": break response = await chat_with_bot(user_input, index, all_texts, model) # 传入文本集合 print(f"Bot: {response}") asyncio.run(main())
额外检查项
- 确认
combined_vectors.npz里确实有texts字段,且每个向量对应正确的文本。 - 如果你的ID是自定义非自增格式,需要维护ID到文本的映射字典,加载时根据ID查找对应文本。
- 可以将
k=1调整为更大的值(比如k=3),返回多个相关文本,让模型获得更丰富的上下文。
内容的提问来源于stack exchange,提问作者JustSkadi
相关产品推荐
相关产品推荐

