ai
  • outline
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116
  • 117
  • 118
  • 119
  • 120
  • 121
  • 122
  • 123
  • 124
  • 125
  • 126
  • 127
  • 128
  • 129
  • 130
  • 131
  • 132
  • 133
  • 134
  • 135
  • 136
  • 137
  • 138
  • 1. 面试题目
  • 2. 参考答案
    • 2.1 系统架构设计
    • 2.2 核心组件实现
    • 2.3 系统工作流程
    • 2.4 系统优化策略
    • 2.5 技术要点总结

1. 面试题目 #

请设计并实现一个基于LangChain的文档问答系统,要求能够处理用户上传的文档(如PDF、文本文件等),并回答用户基于文档内容提出的问题。请详细说明系统架构、核心组件、实现步骤,并考虑系统的优化策略。

2. 参考答案 #

2.1 系统架构设计 #

文档问答系统主要包含两个核心阶段:

索引阶段(Indexing Phase):

  • 文档加载:使用Document Loader加载各种格式的文档
  • 文本分割:使用Text Splitter将大文档分割成小块,便于检索和适配LLM上下文窗口
  • 向量化存储:将文本块转换为向量表示并存储到向量数据库中

检索生成阶段(Retrieval & Generation Phase):

  • 相关文档检索:根据用户问题从向量数据库中检索最相关的文档块
  • 答案生成:将检索到的文档块和用户问题输入LLM生成答案

2.2 核心组件实现 #

import "dotenv/config";
import { TextLoader } from "langchain/document_loaders/fs/text";
import { MemoryVectorStore } from "langchain/vectorstores/memory";
import { OpenAIEmbeddings, ChatOpenAI } from "@langchain/openai";
import { RecursiveCharacterTextSplitter } from "langchain/text_splitter";
import { ChatPromptTemplate } from "@langchain/core/prompts";
import { RunnableSequence } from "@langchain/core/runnables";
import { StringOutputParser } from "@langchain/core/output_parsers";

// 1. 初始化模型和嵌入
const chatModel = new ChatOpenAI({
  configuration: {
    baseURL: process.env.OPENAI_API_BASE_URL,
  },
  apiKey: process.env.OPENAI_API_KEY,
  modelName: "Doubao-1.5-pro-320K-256K",
});

const embeddings = new OpenAIEmbeddings({
  configuration: {
    baseURL: process.env.OPENAI_API_BASE_URL,
  },
  apiKey: process.env.OPENAI_API_KEY,
  modelName: "Doubao-embedding-text-240715",
});

// 2. 文档加载和分割
const loader = new TextLoader("data/qiu.txt");
const docs = await loader.load();

const splitter = new RecursiveCharacterTextSplitter({
  chunkSize: 1000,
  chunkOverlap: 100,
});
const splitDocs = await splitter.splitDocuments(docs);

// 3. 向量化存储
const vectorStore = await MemoryVectorStore.fromDocuments(
  splitDocs,
  embeddings
);

// 4. 构建RAG链
const retriever = vectorStore.asRetriever(2);
const contextRetrieverChain = RunnableSequence.from([
  (input) => input.question,
  retriever,
  (documents) => documents.map(doc => doc.pageContent).join("\n"),
]);

const TEMPLATE = `你是一个有用的问答助手。请基于提供的上下文回答问题。如果无法从上下文中找到答案,请说明你不知道,不要编造答案。

相关上下文:
{context}

请基于原文回答以下问题:
{question}`;

const prompt = ChatPromptTemplate.fromTemplate(TEMPLATE);

const ragChain = RunnableSequence.from([
  {
    context: contextRetrieverChain,
    question: (input) => input.question,
  },
  prompt,
  chatModel,
  new StringOutputParser(),
]);

// 5. 使用示例
const answer = await ragChain.invoke({
  question: "什么是球状闪电?",
});
console.log(answer);

2.3 系统工作流程 #

索引阶段流程:

  1. 用户上传文档 → DocumentQA系统
  2. DocumentQA调用PDFLoader读取文档内容
  3. 对文档内容进行文本分割
  4. 将分割后的文本块存储到向量数据库

查询阶段流程:

  1. 用户提出问题 → DocumentQA系统
  2. DocumentQA从向量数据库检索相关内容
  3. 将检索到的内容和问题发送给LLM
  4. LLM生成答案并返回给用户

2.4 系统优化策略 #

检索优化:

  • 算法多样性:使用语义搜索、混合搜索等多种检索算法
  • 参数调优:调整检索参数如k值、相似度阈值等
  • 重排序:使用专门的排序模型对检索结果进行二次排序

答案生成优化:

  • 链类型选择:根据任务特点选择合适的Chain类型(stuff、map_reduce、refine等)
  • 提示工程:优化提示模板,提供更好的示例和指令
  • 记忆集成:添加记忆功能支持多轮对话

2.5 技术要点总结 #

  • 向量数据库:用于存储文档的向量表示,支持快速相似度搜索
  • 文本分割:平衡检索精度和计算效率的关键技术
  • RAG架构:结合检索和生成的混合架构,提高答案准确性
  • 提示工程:通过精心设计的提示模板引导LLM生成高质量答案

这个系统设计充分体现了现代AI应用中检索增强生成(RAG)的核心思想,通过结合传统信息检索和生成式AI的优势,实现了高效准确的文档问答功能。

访问验证

请输入访问令牌

Token不正确,请重新输入