LangChain 与 LLM 的结合使用详解
LangChain 是一个强大的框架,专为开发基于大语言模型(LLM)的应用而设计。本文将详细介绍 LangChain 与 LLM 的结合方式、核心组件以及常见应用场景。
LangChain 核心理念
LangChain 的核心理念是将 LLM 与外部资源(如数据源、工具、API等)连接起来,构建更强大、更实用的 AI 应用。它提供了一系列抽象和工具,使开发者能够轻松地:
- 与各种 LLM 服务进行标准化交互
- 构建复杂的处理流程
- 使 LLM 能够访问外部信息和工具
- 实现记忆和状态管理
LangChain 架构概览
flowchart TB
subgraph "应用层"
A1["智能问答系统"]
A2["对话机器人"]
A3["文档分析工具"]
A4["代码助手"]
end
subgraph "LangChain核心层"
B1["链 Chains"]
B2["代理 Agents"]
B3["记忆 Memory"]
B4["工具 Tools"]
end
subgraph "模型层"
C1["OpenAI GPT"]
C2["Anthropic Claude"]
C3["Google PaLM"]
C4["本地模型"]
end
subgraph "数据层"
D1["向量数据库"]
D2["文档存储"]
D3["API接口"]
D4["知识库"]
end
A1 --> B1
A2 --> B2
A3 --> B3
A4 --> B4
B1 --> C1
B2 --> C2
B3 --> C3
B4 --> C4
B1 --> D1
B2 --> D2
B3 --> D3
B4 --> D4
LangChain 核心组件
1. 模型集成 (Models)
LangChain 支持多种类型的模型,提供统一的接口:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
// 基础 LLM 使用
import { OpenAI } from "@langchain/openai";
const llm = new OpenAI({
temperature: 0.7,
model: "gpt-3.5-turbo"
});
const result = await llm.invoke("什么是人工智能?");
console.log(result);
// 聊天模型使用
import { ChatOpenAI } from "@langchain/openai";
import { HumanMessage, SystemMessage } from "@langchain/core/messages";
const chatModel = new ChatOpenAI();
const messages = [
new SystemMessage("你是一位人工智能专家"),
new HumanMessage("简单解释一下神经网络的工作原理")
];
const response = await chatModel.invoke(messages);
console.log(response);
2. 提示工程 (Prompts)
提供了管理和优化提示的工具:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
import { PromptTemplate } from "@langchain/core/prompts";
// 创建带有变量的提示模板
const promptTemplate = PromptTemplate.fromTemplate(
"请为一家{industry}公司写一个{length}字的{document_type}"
);
const formattedPrompt = await promptTemplate.format({
industry: "人工智能",
length: "500",
document_type: "公司简介"
});
const result = await llm.invoke(formattedPrompt);
3. 链 (Chains)
链是 LangChain 的核心概念,允许组合多个组件:
flowchart LR
A["用户输入"] --> B["提示模板"]
B --> C["LLM处理"]
C --> D["输出解析"]
D --> E["结果返回"]
subgraph "简单链"
B
C
D
end
subgraph "复杂链"
F["步骤1"] --> G["步骤2"]
G --> H["步骤3"]
H --> I["最终输出"]
end
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
import { LLMChain } from "langchain/chains";
// 简单的LLM链
const chain = new LLMChain({
llm: new OpenAI({ temperature: 0.7 }),
prompt: PromptTemplate.fromTemplate("解释{concept},用简单的语言")
});
const result = await chain.invoke({ concept: "量子计算" });
console.log(result);
// 顺序链 - 处理多步骤任务
import { SequentialChain } from "langchain/chains";
const topicChain = new LLMChain({
llm,
prompt: PromptTemplate.fromTemplate("生成一个关于{subject}的研究主题"),
outputKey: "topic"
});
const outlineChain = new LLMChain({
llm,
prompt: PromptTemplate.fromTemplate("为研究主题'{topic}'创建一个大纲"),
outputKey: "outline"
});
const sequentialChain = new SequentialChain({
chains: [topicChain, outlineChain],
inputVariables: ["subject"],
outputVariables: ["topic", "outline"]
});
const result = await sequentialChain.invoke({ subject: "气候变化" });
4. 记忆 (Memory)
实现对话历史和上下文管理:
sequenceDiagram
participant User as 用户
participant Chain as 对话链
participant Memory as 记忆组件
participant LLM as 大语言模型
User->>Chain: 第一个问题
Chain->>Memory: 存储对话
Chain->>LLM: 处理问题
LLM->>Chain: 返回回答
Chain->>User: 显示回答
User->>Chain: 后续问题
Chain->>Memory: 获取历史对话
Memory->>Chain: 返回上下文
Chain->>LLM: 带上下文处理
LLM->>Chain: 上下文感知回答
Chain->>User: 显示回答
1
2
3
4
5
6
7
8
9
10
11
12
13
14
import { ConversationChain } from "langchain/chains";
import { BufferMemory } from "langchain/memory";
const memory = new BufferMemory();
const conversation = new ConversationChain({
llm: new ChatOpenAI(),
memory
});
// 第一轮对话
const response1 = await conversation.invoke({ input: "我叫张三" });
// 第二轮对话 - 模型会记住用户名
const response2 = await conversation.invoke({ input: "你还记得我是谁吗?" });
5. 检索增强生成 (RAG)
将 LLM 与外部知识库结合:
flowchart TB
A["文档集合"] --> B["文档分割"]
B --> C["向量化"]
C --> D["向量存储"]
E["用户查询"] --> F["查询向量化"]
F --> G["相似度搜索"]
D --> G
G --> H["检索相关文档"]
H --> I["构建增强提示"]
I --> J["LLM生成回答"]
style D fill:#e1f5fe
style J fill:#e8f5e8
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
import { TextLoader } from "langchain/document_loaders/fs/text";
import { RecursiveCharacterTextSplitter } from "langchain/text_splitter";
import { OpenAIEmbeddings } from "@langchain/openai";
import { HNSWLib } from "@langchain/community/vectorstores/hnswlib";
import { RetrievalQAChain } from "langchain/chains";
// 加载文档
const loader = new TextLoader("./documents/data.txt");
const docs = await loader.load();
// 分割文档
const textSplitter = new RecursiveCharacterTextSplitter({
chunkSize: 1000,
chunkOverlap: 200
});
const splitDocs = await textSplitter.splitDocuments(docs);
// 创建向量存储
const embeddings = new OpenAIEmbeddings();
const vectorStore = await HNSWLib.fromDocuments(splitDocs, embeddings);
// 创建问答链
const qa = new RetrievalQAChain({
combineDocumentsChain: loadQAStuffChain(new OpenAI()),
retriever: vectorStore.asRetriever()
});
// 提问
const answer = await qa.invoke({ query: "文档中提到了哪些关键概念?" });
6. 代理 (Agents)
赋予 LLM 使用工具和执行任务的能力:
flowchart TD
A["用户任务"] --> B["代理分析"]
B --> C{"选择工具"}
C -->|"计算需求"| D["计算器工具"]
C -->|"搜索需求"| E["搜索工具"]
C -->|"API调用"| F["API工具"]
C -->|"文件操作"| G["文件工具"]
D --> H["执行并获取结果"]
E --> H
F --> H
G --> H
H --> I{"任务完成?"}
I -->|"否"| C
I -->|"是"| J["返回最终结果"]
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
import { initializeAgentExecutorWithOptions } from "langchain/agents";
import { DynamicTool } from "@langchain/core/tools";
import { Calculator } from "langchain/tools/calculator";
// 定义工具
const tools = [
new Calculator(),
new DynamicTool({
name: "天气查询",
description: "获取指定城市的天气信息",
func: async (city) => {
// 这里可以调用实际的天气API
return `${city}今天晴天,温度22-28度`;
}
})
];
// 创建代理
const executor = await initializeAgentExecutorWithOptions(
tools,
new ChatOpenAI({ temperature: 0 }),
{
agentType: "chat-conversational-react-description",
verbose: true
}
);
// 执行任务
const result = await executor.invoke({
input: "北京今天天气怎么样?然后计算 (24+28)/2 是多少?"
});
LangChain 应用场景
1. 智能问答系统
结合 RAG 技术构建能够回答特定领域问题的系统:
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
// 构建文档问答系统
import { PDFLoader } from "langchain/document_loaders/fs/pdf";
import { OpenAIEmbeddings } from "@langchain/openai";
import { Chroma } from "@langchain/community/vectorstores/chroma";
import { RetrievalQAChain } from "langchain/chains";
async function createQASystem(docsPath, question) {
// 加载PDF文件
const loader = new PDFLoader(docsPath);
const docs = await loader.load();
// 创建向量存储
const vectorStore = await Chroma.fromDocuments(
docs,
new OpenAIEmbeddings()
);
// 创建问答链
const qa = RetrievalQAChain.fromLLM(
new ChatOpenAI({ modelName: "gpt-4" }),
vectorStore.asRetriever()
);
// 获取答案
return await qa.invoke({ query: question });
}
2. 多轮对话机器人
使用记忆组件构建能够维持上下文的聊天机器人:
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
import { ChatOpenAI } from "@langchain/openai";
import { ConversationChain } from "langchain/chains";
import { BufferWindowMemory } from "langchain/memory";
import { ChatPromptTemplate, MessagesPlaceholder } from "@langchain/core/prompts";
async function createChatbot() {
// 创建提示模板
const chatPrompt = ChatPromptTemplate.fromMessages([
["system", "你是一个专业的客服助手,负责解答用户关于产品的问题。"],
new MessagesPlaceholder("history"),
["human", "{input}"]
]);
// 创建记忆组件
const memory = new BufferWindowMemory({
memoryKey: "history",
k: 5,
returnMessages: true
});
// 创建对话链
return new ConversationChain({
llm: new ChatOpenAI(),
memory: memory,
prompt: chatPrompt
});
}
3. 结构化数据提取
从非结构化文本中提取结构化信息:
flowchart LR
A[非结构化文本] --> B[LLM分析]
B --> C[结构化输出解析]
C --> D[验证和格式化]
D --> E[JSON/数据库存储]
subgraph "提取过程"
F[实体识别]
G[关系提取]
H[属性提取]
end
B --> F & G & H
F & G & H --> C
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
import { OpenAI } from "@langchain/openai";
import { StructuredOutputParser } from "langchain/output_parsers";
import { PromptTemplate } from "@langchain/core/prompts";
import { z } from "zod";
async function extractStructuredData(text) {
// 定义输出结构
const parser = StructuredOutputParser.fromZodSchema(
z.object({
people: z.array(z.object({
name: z.string().describe("人物姓名"),
age: z.number().optional().describe("人物年龄"),
occupation: z.string().optional().describe("职业")
})),
locations: z.array(z.string()).describe("文本中提到的地点"),
summary: z.string().describe("文本的简要总结")
})
);
// 创建提示模板
const prompt = PromptTemplate.fromTemplate(
`从以下文本中提取关键信息,并按照指定格式输出。
文本: {text}
{format_instructions}
`
);
// 格式说明
const formatInstructions = parser.getFormatInstructions();
// 生成完整提示
const input = await prompt.format({
text: text,
format_instructions: formatInstructions
});
// 获取LLM响应
const model = new OpenAI({ temperature: 0 });
const response = await model.invoke(input);
// 解析结果
return parser.parse(response);
}
4. 工作流自动化
使用代理和工具自动化复杂任务:
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
import { ChatOpenAI } from "@langchain/openai";
import { createOpenAIToolsAgent, AgentExecutor } from "langchain/agents";
import { TavilySearchResults } from "@langchain/community/tools/tavily_search";
import { JsonOutputParser } from "@langchain/core/output_parsers";
import { pull } from "langchain/hub";
async function researchAssistant(topic) {
// 创建工具
const tools = [
new TavilySearchResults({
maxResults: 3,
apiKey: process.env.TAVILY_API_KEY,
}),
];
// 获取代理提示
const prompt = await pull("hwchase17/openai-tools-agent");
// 创建代理
const agent = createOpenAIToolsAgent({
llm: new ChatOpenAI({ temperature: 0, model: "gpt-4" }),
tools,
prompt,
});
// 创建执行器
const agentExecutor = new AgentExecutor({
agent,
tools,
verbose: true,
});
// 执行任务
return agentExecutor.invoke({
input: `做一份关于"${topic}"的详细研究报告,包括最新发展、主要挑战和未来趋势。`,
});
}
高级模式与最佳实践
1. 提示工程最佳实践
flowchart TD
A[提示设计原则] --> B[清晰明确]
A --> C[上下文丰富]
A --> D[示例引导]
A --> E[约束限制]
B --> F[具体指令]
C --> G[背景信息]
D --> H[Few-Shot学习]
E --> I[输出格式]
F & G & H & I --> J[高质量输出]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
// 使用少样本学习(Few-Shot Learning)
const fewShotTemplate = `您是一位情感分析专家。分析文本情感,并分类为"积极"、"中性"或"消极"。
例子:
文本: "今天天气真好,我心情非常愉快"
情感: 积极
文本: "这家餐厅的食物质量一般"
情感: 中性
文本: "服务太差了,我再也不会来这里"
情感: 消极
文本: "{input}"
情感:`;
const fewShotPrompt = PromptTemplate.fromTemplate(fewShotTemplate);
2. 自定义链
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
import { BaseChain } from "langchain/chains";
class CustomTranslationChain extends BaseChain {
constructor(fields) {
super();
this.llm = fields.llm;
}
get inputKeys() {
return ["text", "language"];
}
get outputKeys() {
return ["translation"];
}
async _call(values) {
const { text, language } = values;
const prompt = `将以下文本翻译成${language}:\n\n${text}`;
const translation = await this.llm.invoke(prompt);
return { translation };
}
}
3. 批处理优化
1
2
3
4
5
6
// 批处理嵌入以减少API调用
import { OpenAIEmbeddings } from "@langchain/openai";
const embeddings = new OpenAIEmbeddings();
const texts = ["文本1", "文本2", "文本3", "文本4", "文本5"];
const embedArray = await embeddings.embedDocuments(texts);
4. RAG高级技术
flowchart TB
A[用户查询] --> B[查询重写]
B --> C[多查询生成]
C --> D[并行检索]
D --> E[结果合并]
E --> F[重排序]
F --> G[上下文构建]
G --> H[LLM生成]
subgraph "检索优化"
I[混合搜索]
J[语义分块]
K[元数据过滤]
end
D --> I & J & K
1
2
3
4
5
6
7
8
9
10
11
12
// 使用多查询检索增强文档搜索精度
import { MultiQueryRetriever } from "langchain/retrievers/multi_query";
// 创建多查询检索器
const retriever = MultiQueryRetriever.fromLLM({
llm: new ChatOpenAI(),
retriever: vectorStore.asRetriever(),
queryCount: 3, // 生成3个不同的查询
});
// 使用检索器
const documents = await retriever.getRelevantDocuments("什么是量子计算?");
性能优化与部署
1. 缓存策略
graph TD
A[请求] --> B{缓存检查}
B -->|命中| C[返回缓存结果]
B -->|未命中| D[LLM处理]
D --> E[存储到缓存]
E --> F[返回结果]
subgraph "缓存类型"
G[内存缓存]
H[Redis缓存]
I[数据库缓存]
end
2. 流式输出
1
2
3
4
5
6
7
8
9
10
11
12
13
14
import { ChatOpenAI } from "@langchain/openai";
const streamingLLM = new ChatOpenAI({
streaming: true,
callbacks: [
{
handleLLMNewToken(token) {
process.stdout.write(token);
},
},
],
});
await streamingLLM.invoke("写一篇关于人工智能的文章");
3. 错误处理与重试
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
import { ChatOpenAI } from "@langchain/openai";
import { LLMChain } from "langchain/chains";
const llmWithRetry = new ChatOpenAI({
maxRetries: 3,
timeout: 30000,
});
const chain = new LLMChain({
llm: llmWithRetry,
prompt: promptTemplate,
});
try {
const result = await chain.invoke({ input: "用户输入" });
return result;
} catch (error) {
console.error("处理失败:", error);
// 实现降级策略
return "抱歉,服务暂时不可用,请稍后重试。";
}
总结
LangChain 提供了一个强大的框架,使开发者能够高效地将 LLM 集成到应用程序中,并扩展其功能。主要优势包括:
- 抽象与标准化 - 统一接口简化了与不同 LLM 提供商的交互
- 组件化设计 - 便于构建复杂的 AI 应用流程
- 工具和集成 - 丰富的工具库和第三方集成
- 灵活性 - 可以根据需求自定义和扩展组件
通过合理使用 LangChain 提供的组件和模式,开发者可以构建功能强大、上下文感知的 AI 应用,大幅提升开发效率和应用质量。
关键要点:
- 选择合适的模型和配置参数
- 设计有效的提示模板
- 合理使用记忆和上下文管理
- 利用RAG技术增强知识获取
- 通过代理和工具扩展LLM能力
- 注重性能优化和错误处理
随着LLM技术的不断发展,LangChain也在持续演进,为开发者提供更多强大的功能和工具,助力构建下一代智能应用。