You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

LangChain多语言聊天机器人知识库差异问题及配置咨询

瑞士房产领域聊天机器人多语言知识调用问题

问题背景

基于LangChain开发了一款带记忆功能的瑞士房产领域聊天机器人,通过PDF导入自定义领域知识库,支持多语言交互且运行正常。为验证知识范围,做了测试:

  • 用英文提问通用知识(如“瑞士的首都是什么?”),机器人回复“不知道”,判断未调用预训练知识;
  • 用德语提问相同通用知识,机器人能给出正确答案。

咨询问题

  1. 这种多语言下的差异行为是正常现象还是Bug?
  2. 如何配置机器人,使其仅聚焦自定义知识库,或者启用预训练通用知识?

实现代码

import os
import pandas as pd
import matplotlib.pyplot as plt
from transformers import GPT2TokenizerFast
from langchain.document_loaders import PyPDFLoader
from langchain.text_splitter import RecursiveCharacterTextSplitter
from langchain.embeddings import OpenAIEmbeddings
from langchain.vectorstores import FAISS
from langchain.chains.question_answering import load_qa_chain
from langchain.llms import OpenAI
from langchain.chains import ConversationalRetrievalChain
from IPython.display import display
import ipywidgets as widgets

os.environ["OPENAI_API_KEY"] = "..."

# STEP 1: Split by chunk

# Convert PDF to text
import textract
doc = textract.process("./Allgemeine Bedingungen.pdf")

# Save to .txt and reopen
with open('Allgemeine Bedingungen.txt', 'w') as f:
    f.write(doc.decode('utf-8'))

with open('Allgemeine Bedingungen.txt', 'r') as f:
    text = f.read()

# Create function to count tokens
tokenizer = GPT2TokenizerFast.from_pretrained("gpt2")

def count_tokens(text: str) -> int:
    return len(tokenizer.encode(text))

# Split text into chunks
text_splitter = RecursiveCharacterTextSplitter(
    chunk_size = 512,
    chunk_overlap  = 24,
    length_function = count_tokens,
)

chunks = text_splitter.create_documents([text])

# STEP 2: Embed text and store embeddings

# Get embedding model
embeddings = OpenAIEmbeddings()

# Create vector database
db = FAISS.from_documents(chunks, embeddings)

# STEP 3: Setup retrieval function

chain = load_qa_chain(OpenAI(temperature=0), chain_type="stuff")

query = "Was ist die Unterhaltspflicht des Mieters?"
docs = db.similarity_search(query)

chain.run(input_documents=docs, question=query)

# STEP 4: Create chatbot with chat memory

qa = ConversationalRetrievalChain.from_llm(OpenAI(temperature=0.1), db.as_retriever())

chat_history = []

def on_submit(_):
    query = input_box.value
    input_box.value = ""

    if query.lower() == 'stop':
        print("Cheers!")
        return

    result = qa({"question": query, "chat_history": chat_history})
    chat_history.append((query, result['answer']))

    display(widgets.HTML(f'<b>User:</b> {query}'))
    display(widgets.HTML(f'<b><font color="blue">Chatbot:</font></b> {result["answer"]}'))

print("Welcome! Type 'stop' to quit.")

input_box = widgets.Text(placeholder='Enter your question:')
input_box.on_submit(on_submit)

display(input_box)

问题解答

1. 行为是否正常?

这不是Bug,是多语言检索与LLM提示词交互的正常现象,原因如下:

  • 知识库PDF是德语文档(文件名Allgemeine Bedingungen.pdf),生成的嵌入向量基于德语文本。用德语提问通用知识时,检索器可能返回语义看似相关的德语文档片段(哪怕内容和问题无关),LLM处理这些片段时结合自身预训练知识给出了答案;
  • 用英文提问时,检索器找不到语义匹配的英文文档片段,返回结果为空或无关内容,LLM在无上下文支撑的情况下,按默认逻辑回复“不知道”。

2. 配置方案

方案一:强制仅聚焦自定义知识库

修改ConversationalRetrievalChain的提示词,明确要求LLM只能基于提供的文档回答,禁止使用外部知识:

from langchain.prompts import PromptTemplate

prompt_template = """仅根据以下提供的文档内容回答问题,不要使用任何外部知识。如果文档中没有相关信息,直接回复“不知道”。

文档内容:
{context}

问题: {question}
回答:"""

PROMPT = PromptTemplate(
    template=prompt_template,
    input_variables=["context", "question"]
)

# 替换原有链的prompt
qa = ConversationalRetrievalChain.from_llm(
    OpenAI(temperature=0.1),
    db.as_retriever(search_kwargs={"k":1}), # 限制返回1份文档,减少无关片段干扰
    combine_docs_chain_kwargs={"prompt": PROMPT}
)

方案二:启用预训练通用知识

让机器人在知识库无相关内容时调用预训练知识,需修改链的逻辑,判断检索结果是否为空,再决定是否直接调用LLM回答:

from langchain.chains import RetrievalQA

qa = RetrievalQA.from_chain_type(
    llm=OpenAI(temperature=0.1),
    chain_type="stuff",
    retriever=db.as_retriever(),
    return_source_documents=True
)

# 修改交互逻辑
def on_submit(_):
    query = input_box.value
    input_box.value = ""

    if query.lower() == 'stop':
        print("Cheers!")
        return

    result = qa({"query": query})
    # 无相关文档时直接调用LLM回答
    if not result["source_documents"]:
        direct_answer = OpenAI(temperature=0.1)(query)
        result["result"] = direct_answer

    chat_history.append((query, result['result']))

    display(widgets.HTML(f'<b>用户:</b> {query}'))
    display(widgets.HTML(f'<b><font color="blue">聊天机器人:</font></b> {result["result"]}'))

内容的提问来源于stack exchange,提问作者nicoe

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.12 21:00:06