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

如何借助Langchain获取更详细的问答结果来源信息?

解决Langchain RetrievalQAWithSourcesChain返回详细来源的方案

问题根源

RetrievalQAWithSourcesChain返回的来源信息,本质由**加载文档时存入的元数据(metadata)**决定:LLM仅负责从检索到的文档元数据中提取来源字段,链本身仅做组装工作。默认URL加载器只会把完整URL存入元数据的source字段,因此最终返回的只有完整URL。

具体实现步骤

1. 自定义URL加载逻辑,提取章节标题与锚点

手动解析页面结构,提取每个章节的标题、内容及对应锚点URL,将这些信息存入文档元数据:

from langchain.schema import Document
import requests
from bs4 import BeautifulSoup

def load_url_with_chapters(target_url):
    response = requests.get(target_url)
    soup = BeautifulSoup(response.text, 'html.parser')
    docs = []
    
    # 示例:以页面h2标签为章节标题,需根据目标页面结构调整
    for chapter_tag in soup.find_all('h2'):
        chapter_title = chapter_tag.get_text(strip=True)
        anchor_id = chapter_tag.get('id')
        # 拼接带锚点的URL
        source_url = f"{target_url}#{anchor_id}" if anchor_id else target_url
        
        # 提取章节内容(直到下一个h2标签)
        content_list = []
        next_node = chapter_tag.next_sibling
        while next_node and next_node.name != 'h2':
            if hasattr(next_node, 'get_text'):
                content_list.append(next_node.get_text(strip=True))
            next_node = next_node.next_sibling
        chapter_content = '\n'.join(content_list)
        
        # 创建带元数据的Document对象
        docs.append(Document(
            page_content=chapter_content,
            metadata={
                'source': source_url,
                'chapter_title': chapter_title
            }
        ))
    return docs

# 加载带章节信息的文档
docs = load_url_with_chapters("你的目标URL")

如果页面是动态渲染(如JS加载内容),替换requests为SeleniumURLLoader获取页面源码即可。

2. 构建向量库时保留元数据

将自定义加载的文档存入向量库,元数据会被同步存储:

from langchain.embeddings import OpenAIEmbeddings
from langchain.vectorstores import Chroma

embeddings = OpenAIEmbeddings()
vector_store = Chroma.from_documents(docs, embeddings)

3. 自定义链的提示词,指定来源格式

修改默认提示词,让LLM返回包含章节标题和锚点URL的详细来源:

from langchain.chains import RetrievalQAWithSourcesChain
from langchain.prompts import PromptTemplate
from langchain.chat_models import ChatOpenAI

llm = ChatOpenAI(temperature=0, model_name='gpt-3.5-turbo')

# 自定义提示模板,明确要求返回的来源格式
prompt_template = """
使用以下上下文回答用户问题,不知道答案就直接说不知道,不要编造内容。
回答末尾必须按格式列出来源:
Sources:
- [章节标题](锚点URL)

上下文:
{summaries}

问题: {question}
"""

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

# 初始化自定义提示词的链
chain = RetrievalQAWithSourcesChain.from_llm(
    llm=llm,
    retriever=vector_store.as_retriever(),
    prompt=PROMPT
)

# 执行查询
result = chain({"question": "你的问题内容"})
print(result['answer'])

关键注意事项

  • 页面结构解析逻辑需根据目标URL的实际HTML标签调整(比如部分页面用h3或特定class的div作为章节标识)
  • 元数据可灵活扩展,如需添加段落位置、作者等信息,只需在加载时存入元数据,并在提示词中对应提取即可

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.19 02:12:49