npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

langchain-rag-chat

v1.0.0

Published

A RAG chat library built with LangChain

Readme

langchain-rag-chat

参见文档:English | 中文

一个基于 LangChain 生态的 TypeScript RAG(检索增强生成)聊天库。它将文档加载、向量检索、问题扩展、分类检索和答案生成整合到一个 RAGChat 类中。

特性

  • 支持从网页、PDF 或纯文本加载文档,并自动进行结构感知分块(保留 Markdown 标题层级,标题与其内容不分离)
  • 可插拔的向量存储(默认为内存存储)
  • 问题扩展(Multi-Query)以提升检索召回率
  • 可选的问题分类 + 按元数据过滤的检索
  • 多问题输入的自动拆分(问题分解)
  • 检索结果的去重与压缩
  • 支持流式和非流式答案生成
  • 通过 onStep 提供生命周期回调,便于观察运行过程
  • 通过 RAGOptions 提供完整的类型化配置
  • 模型无关:自行传入 LangChain 的聊天模型与 embedding 模型

安装

npm install langchain-rag-chat @langchain/classic @langchain/core langchain

自行选择模型提供方。下面的示例使用 @langchain/openai,但任意实现了 LangChain BaseChatModel / Embeddings 的模型都可以:

npm install @langchain/openai

本包同时提供 ESM 与 CommonJS 两种构建产物,可兼容 import 与 require。

快速开始

import { RAGChat } from "langchain-rag-chat";
import { ChatOpenAI, OpenAIEmbeddings } from "@langchain/openai";

const rag = new RAGChat({
  model: new ChatOpenAI({
    model: "gpt-4o-mini",
    apiKey: process.env.OPENAI_API_KEY,
  }),
  embeddings: new OpenAIEmbeddings({
    model: "text-embedding-3-small",
    apiKey: process.env.OPENAI_API_KEY,
  }),
  category: ["biology", "physics"] as const,
  enhancePrompt: 3,
});

// 加载并索引文档。每个资源会打上对应的分类标签。
await rag.load({
  resource: [
    { url: "https://example.com/biology.html", type: "biology" },
    { url: "https://example.com/physics.pdf", type: "physics" },
  ],
});

// 提问并获取最终答案(非流式)。
const answer = await rag.invoke({ question: "什么是光合作用?" });
console.log(answer);

// 或流式输出答案。
for await (const chunk of rag.stream("什么是光合作用?")) {
  process.stdout.write(chunk);
}

配置项

所有配置项都通过 RAGOptions 接口传入 RAGChat 构造函数。

export interface RAGOptions<Q extends string> {
  model: BaseChatModel;
  vectorStore?: VectorStoreFactory;
  embeddings: Embeddings;
  enhancePrompt?: number;
  retrieverOptions?: RetrieverOptions;
  category?: Q[];
  enableClassification?: boolean;
  questionCategory?: [Q, string][];
  onStep?: (step: RAGStep, payload?: any) => void;
  preRetrieve?: RunnableLike;
  postRetrieve?: RunnableLike;
  loader?: CustomLoader<Q>;
}

配置项说明

| 配置项 | 类型 | 必填 | 默认值 | 作用 | | ---------------------- | -------------------------- | ---- | ------------------- | ---------------------------------------------------------------------- | | model | BaseChatModel | ✅ | — | 已创建好的 LangChain 聊天模型,用于问题分类、问题扩展和答案生成。 | | vectorStore | VectorStoreFactory | ❌ | MemoryVectorStore | 自定义向量存储工厂 (embeddings) => VectorStore。 | | embeddings | Embeddings | ✅ | — | 已创建好的 LangChain embedding 模型,用于向量化文档与查询。 | | enhancePrompt | number | ❌ | 3 | 由原始问题生成的扩展查询数量(Multi-Query)。小于 1 时不进行扩展。 | | retrieverOptions | RetrieverOptions | ❌ | { k: 3 } | 传给底层向量存储检索器的选项(如 { k, filter, searchType })。 | | category | Q[] | ❌ | [] | 允许的问题分类数组,用于问题分类。为空时,load() 会从加载的资源类型中推断。 | | enableClassification | boolean | ❌ | true | 是否在检索前对问题进行分类。关闭后检索将不再按分类过滤。 | | questionCategory | [Q, string][] | ❌ | [] | [分类, 描述] 的配对数组,为分类提示词描述每个分类的含义。 | | onStep | (step, payload?) => void | ❌ | — | 生命周期回调,在各阶段携带当前 payload 触发(见 RAGStep)。 | | preRetrieve | RunnableLike | ❌ | — | 在检索之前应用的 runnable,例如重写查询或注入上下文。 | | postRetrieve | RunnableLike | ❌ | — | 在检索/压缩之后应用的 runnable,例如重排或转换文档。 | | loader | CustomLoader<Q> | ❌ | — | 按文件后缀(如 .txt)注册的自定义文档加载器,可覆盖内置加载器。 |

ℹ️ model 与 embeddings 均为必填。本库与模型提供方无关:可传入任意实现了 LangChain BaseChatModel / Embeddings 的模型(OpenAI、Anthropic、本地模型等), 不再与 OpenAI 深度绑定。

RAGStep

onStep 回调会收到以下某个阶段名称:

export type RAGStep =
  | "classification" // 问题分类
  | "vectorStore" // 文档已写入向量存储(load 之后)
  | "retrieve" // 检索完成
  | "compress" // 去重/压缩完成
  | "answer"; // 开始生成答案

相关类型

LoadOptions

RAGChat.load() 加载与索引文档时使用的配置。

export interface LoadOptions<Q extends string> {
  resource: Resource<Q>[];
  concurrencyCount?: number; // 默认 3
  splitterOptions?: Partial<RecursiveCharacterTextSplitterParams>;
  loader?: CustomLoader<Q> | null;
}

Resource

描述单个文档来源。

export interface Resource<Q extends string = string> {
  url: string; // 网页或 PDF 的 http(s) URL;其他后缀作为纯文本来源(非 http 的 PDF 需自定义 loader)
  type?: Q; // 写入文档元数据的分类标签(用于分类过滤)
  selector?: string; // 网页 CSS 选择器(默认 "body")
  text?: string; // 纯文本内容(当 url 无对应加载器时使用)
}

CustomLoader

后缀 → 加载函数 的映射,键为文件后缀(如 .md)。

export interface CustomLoader<Q extends string = string> {
  [suffix: string]: (resource: Resource<Q>) => Promise<Document<any>[]>;
}

VectorStoreFactory / RetrieverOptions / InputQuestion

export type VectorStoreFactory = (embeddings: Embeddings) => VectorStore;

export type RetrieverOptions<
  V extends VectorStoreInterface = VectorStoreInterface,
> = Exclude<Parameters<V["asRetriever"]>[0], number | undefined>;

export interface InputQuestion {
  question: string;
  retrieverOptions?: RetrieverOptions; // 每次查询的检索器覆盖项
}

API

constructor(options: RAGOptions<Q>)

创建 RAGChat 实例,并准备检索链与答案生成链。

load(loadOptions: LoadOptions<Q>)

加载资源、将每个资源的 type 写入文档的 metadata._type、分块(结构感知,保留标题层级)并写入向量存储。当 category 为空时,会从加载的资源类型中推断。

retrieveDocuments(question: string[], kOrFields?)

在向量存储中检索给定问题,返回匹配的 Document[]。

invoke(input: string | InputQuestion, options?)

执行完整 RAG 流程并返回生成的答案字符串。

stream(input: string | InputQuestion, options?)

执行 RAG 流程并以异步生成器流式输出答案。

classification(question, category?, questionCategory?)

将问题分类到某个已配置的分类(或 "other")。

splitQuestion(question)

使用语言模型将一个包含多个问题的问题拆分为子问题,每个子问题独立检索与回答。

expandQuestion(question, queryCount?)

从原始问题生成 queryCount 个扩展查询(Multi-Query)。原始问题始终作为第一个结果保留,确保日期、ID 等精确词不会被改写丢失。

执行流程

问题
  → 问题拆分(拆成子问题)
  → 问题分类(可选)
  → 问题扩展
  → preRetrieve
  → 检索(按分类过滤)
  → 去重与压缩
  → postRetrieve
  → 答案生成

许可证

MIT