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

ConversationalRetrievalChain替换Map_Reduce链及响应截断问题求解

电商聊天机器人ConversationalRetrievalChain问题解决方案

1. Stuff链Token超限问题(替换链类型的坑与解决)

问题根源

Stuff链会把所有检索到的文档一次性塞进prompt,当文档量大时必然触发token上限。替换为MapReduce链时,因为该链分为**Map(单文档生成中间结果)和Reduce(合并中间结果)**两个阶段,默认使用两个独立prompt,自定义单个QA prompt会引发参数冲突;且MapReduce链不支持流式输出(多prompt与流输出逻辑不兼容),所以会出现ValueError: Cannot stream results with multiple prompts。

可行解决方案

方案A:优化Stuff链(最简单,适合新手)

不需要更换链类型,通过减少检索文档数量、精简文档内容降低输入token:

  • 调整Redis检索器的search_kwargs参数,减少返回的文档数量(比如设为k=3,只取最相关的3条):
# 初始化Redis检索器时添加搜索参数
retriever = your_redis_vector_store.as_retriever(search_kwargs={"k": 3})

# 构建ConversationalRetrievalChain时使用自定义prompt
chat_chain = ConversationalRetrievalChain.from_llm(
    llm=your_llm_model,
    retriever=retriever,
    combine_docs_chain_kwargs={
        "prompt": your_custom_qa_prompt  # 保留自定义prompt
    },
    streaming=True  # 支持流式输出
)
  • 如果文档本身冗余,可以在存入Redis前做预处理:提取关键信息(比如商品核心参数、售后规则摘要),缩短单文档长度。

方案B:替换为Refine链(兼容自定义prompt,支持复杂文档)

Refine链会先基于第一个文档生成初始回答,再依次用后续文档优化回答,支持自定义两个阶段的prompt,且部分场景下可支持流式输出(取决于LLM支持):

from langchain.chains import RefineDocumentsChain, LLMChain
from langchain.prompts import PromptTemplate

# 自定义初始回答prompt(处理第一个文档)
initial_prompt = PromptTemplate(
    input_variables=["question", "context"],
    template="""你是电商客服机器人,根据以下上下文回答用户问题:
上下文:{context}
问题:{question}
请给出准确详细的回答。"""
)

# 自定义优化prompt(用后续文档优化已有回答)
refine_prompt = PromptTemplate(
    input_variables=["question", "existing_answer", "context"],
    template="""现有回答:{existing_answer}
新增上下文:{context}
问题:{question}
请结合新增上下文优化回答,若新增信息无价值则直接返回原回答。"""
)

# 构建两个阶段的LLM链
initial_llm_chain = LLMChain(llm=your_llm_model, prompt=initial_prompt)
refine_llm_chain = LLMChain(llm=your_llm_model, prompt=refine_prompt)

# 组装RefineDocumentsChain
refine_qa_chain = RefineDocumentsChain(
    initial_llm_chain=initial_llm_chain,
    refine_llm_chain=refine_llm_chain,
    document_variable_name="context",
    return_intermediate_steps=False
)

# 传入ConversationalRetrievalChain
chat_chain = ConversationalRetrievalChain.from_llm(
    llm=your_llm_model,
    retriever=your_redis_retriever,
    combine_docs_chain=refine_qa_chain,
    return_source_documents=True
)

注意:如果需要流式输出,需确认所用LLM支持流式,且部分版本的Refine链可能不兼容流式,此时优先选方案A。

2. Max_tokens=150导致响应截断问题

问题根源

max_tokens是限制LLM输出的token数量,设为150时,超过长度的内容会被强制截断。

解决方案

  • 直接调整max_tokens值:根据所用LLM的上下文窗口设置合理值,比如GPT-3.5-Turbo(4k窗口)可设为5001000,GPT-4(8k/32k窗口)可设为10002000。调整方式:
# 初始化LLM时设置max_tokens
from langchain.chat_models import ChatOpenAI

llm = ChatOpenAI(
    model_name="gpt-3.5-turbo",
    max_tokens=800,  # 调整为合适值
    temperature=0.3
)
  • 用prompt引导精简/分点回答:如果担心输出过长,可在自定义prompt中明确要求分点、简洁回答,避免冗余:
custom_qa_prompt = PromptTemplate(
    input_variables=["question", "context", "chat_history"],
    template="""聊天历史:{chat_history}
上下文:{context}
问题:{question}
请分点给出简洁准确的回答,不要冗余内容。"""
)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.20 06:15:08