《60天AI学习计划启动 | Day 11: LangChain 框架 - 提升 AI 开发效率》
Day 11: LangChain 框架 - 提升 AI 开发效率
学习目标
核心学习内容
1. LangChain 简介
什么是 LangChain?
- AI 应用开发框架
- 简化 LLM 应用构建
- 提供组件和工具链
- 支持多种 LLM 和工具
核心优势:
- 模块化设计
- 丰富的组件库
- 易于扩展
- 社区活跃
核心概念:
Components(组件)
↓
Chains(链)
↓
Agents(代理)
↓
Memory(记忆)
2. 核心组件
主要组件:
- LLMs:语言模型封装
- Prompts:提示词管理
- Chains:调用链
- Agents:智能代理
- Memory:记忆管理
- Tools:工具集成
3. Chain 概念
什么是 Chain?
- 将多个组件串联
- 顺序执行任务
- 数据在链中传递
示例:
输入 → LLM → 处理 → 输出
实践作业
作业1:安装和配置 LangChain
安装依赖:
npm install langchain @langchain/openai
基础配置:
// src/config/langchain.js
import { ChatOpenAI } from '@langchain/openai';
import { OpenAIEmbeddings } from '@langchain/openai';
// 配置 LLM
export const llm = new ChatOpenAI({
modelName: 'gpt-3.5-turbo',
temperature: 0.7,
openAIApiKey: process.env.OPENAI_API_KEY
});
// 配置 Embeddings
export const embeddings = new OpenAIEmbeddings({
openAIApiKey: process.env.OPENAI_API_KEY
});
作业2:实现基础 Chain
src/chains/simple-chain.js:
import { ChatOpenAI } from '@langchain/openai';
import { PromptTemplate } from '@langchain/core/prompts';
import { LLMChain } from 'langchain/chains';
/**
* 简单 Chain 示例
*/
export async function createSimpleChain() {
const llm = new ChatOpenAI({
temperature: 0.7,
openAIApiKey: process.env.OPENAI_API_KEY
});
// 定义提示词模板
const prompt = PromptTemplate.fromTemplate(
`你是一个专业的前端开发助手。
回答以下问题:{question}
请提供:
1. 简要回答
2. 代码示例(如适用)
3. 最佳实践建议`
);
// 创建 Chain
const chain = new LLMChain({
llm: llm,
prompt: prompt
});
return chain;
}
// 使用示例
export async function useSimpleChain() {
const chain = await createSimpleChain();
const result = await chain.call({
question: '如何实现防抖函数?'
});
console.log(result.text);
}
作业3:实现 Sequential Chain
src/chains/sequential-chain.js:
import { ChatOpenAI } from '@langchain/openai';
import { PromptTemplate } from '@langchain/core/prompts';
import { LLMChain, SimpleSequentialChain } from 'langchain/chains';
/**
* 顺序 Chain:先总结,再生成代码
*/
export async function createSequentialChain() {
const llm = new ChatOpenAI({
temperature: 0.7,
openAIApiKey: process.env.OPENAI_API_KEY
});
// Chain 1: 总结需求
const summaryPrompt = PromptTemplate.fromTemplate(
`总结以下开发需求,提取关键信息:
需求:{requirement}
总结:`
);
const summaryChain = new LLMChain({
llm: llm,
prompt: summaryPrompt
});
// Chain 2: 生成代码
const codePrompt = PromptTemplate.fromTemplate(
`根据以下需求总结,生成 JavaScript 代码:
总结:{summary}
代码:`
);
const codeChain = new LLMChain({
llm: llm,
prompt: codePrompt
});
// 组合 Chain
const chain = new SimpleSequentialChain({
chains: [summaryChain, codeChain],
verbose: true // 显示执行过程
});
return chain;
}
// 使用示例
export async function useSequentialChain() {
const chain = await createSequentialChain();
const result = await chain.run(
'实现一个用户登录功能,包含用户名和密码验证'
);
console.log(result);
}
作业4:实现 RAG Chain
src/chains/rag-chain.js:
import { ChatOpenAI } from '@langchain/openai';
import { OpenAIEmbeddings } from '@langchain/openai';
import { MemoryVectorStore } from 'langchain/vectorstores/memory';
import { RetrievalQAChain } from 'langchain/chains';
import { PromptTemplate } from '@langchain/core/prompts';
/**
* RAG Chain:检索增强生成
*/
export class RAGChain {
constructor() {
this.vectorStore = null;
this.chain = null;
}
/**
* 初始化向量存储
*/
async initializeVectorStore(documents) {
const embeddings = new OpenAIEmbeddings({
openAIApiKey: process.env.OPENAI_API_KEY
});
// 创建向量存储
this.vectorStore = await MemoryVectorStore.fromTexts(
documents.map(doc => doc.text),
documents.map(doc => doc.metadata),
embeddings
);
}
/**
* 创建 RAG Chain
*/
async createRAGChain() {
const llm = new ChatOpenAI({
temperature: 0.7,
openAIApiKey: process.env.OPENAI_API_KEY
});
// 自定义提示词
const prompt = PromptTemplate.fromTemplate(
`基于以下文档内容回答问题。如果文档中没有相关信息,请说明。
文档内容:
{context}
问题:{question}
回答:`
);
// 创建检索 QA Chain
this.chain = RetrievalQAChain.fromLLM(llm, this.vectorStore.asRetriever(), {
prompt: prompt,
returnSourceDocuments: true
});
return this.chain;
}
/**
* 回答问题
*/
async answer(question) {
if (!this.chain) {
throw new Error('Chain 未初始化');
}
const result = await this.chain.call({
query: question
});
return {
answer: result.text,
sourceDocuments: result.sourceDocuments
};
}
}
// 使用示例
export async function useRAGChain() {
const ragChain = new RAGChain();
// 准备文档
const documents = [
{
text: 'Vue.js 是一个渐进式 JavaScript 框架',
metadata: { source: 'vue-docs' }
},
{
text: 'React 是 Facebook 开发的 UI 库',
metadata: { source: 'react-docs' }
}
];
// 初始化
await ragChain.initializeVectorStore(documents);
await ragChain.createRAGChain();
// 提问
const result = await ragChain.answer('Vue.js 是什么?');
console.log('回答:', result.answer);
console.log('来源:', result.sourceDocuments);
}
作业5:实现 Agent
src/agents/simple-agent.js:
import { ChatOpenAI } from '@langchain/openai';
import { initializeAgentExecutorWithOptions } from 'langchain/agents';
import { DynamicTool } from '@langchain/core/tools';
/**
* 简单 Agent 示例
*/
export async function createSimpleAgent() {
const llm = new ChatOpenAI({
temperature: 0.7,
openAIApiKey: process.env.OPENAI_API_KEY
});
// 定义工具
const tools = [
new DynamicTool({
name: 'get_weather',
description: '获取指定城市的天气信息。输入:城市名称',
func: async (input) => {
// 模拟天气查询
return `${input}的天气:晴天,22°C`;
}
}),
new DynamicTool({
name: 'calculate',
description: '执行数学计算。输入:数学表达式',
func: async (input) => {
try {
const result = Function(`"use strict"; return (${input})`)();
return `计算结果:${result}`;
} catch (error) {
return '计算失败';
}
}
}),
new DynamicTool({
name: 'search_web',
description: '搜索网络信息。输入:搜索关键词',
func: async (input) => {
return `关于"${input}"的搜索结果:...`;
}
})
];
// 创建 Agent
const executor = await initializeAgentExecutorWithOptions(tools, llm, {
agentType: 'zero-shot-react-description',
verbose: true
});
return executor;
}
// 使用示例
export async function useSimpleAgent() {
const agent = await createSimpleAgent();
const result = await agent.invoke({
input: '北京今天天气怎么样?然后计算 123 * 456'
});
console.log(result.output);
}
作业6:使用 LangChain 重构 RAG 服务
src/services/rag-langchain.js:
import { ChatOpenAI } from '@langchain/openai';
import { OpenAIEmbeddings } from '@langchain/openai';
import { MemoryVectorStore } from 'langchain/vectorstores/memory';
import { RetrievalQAChain } from 'langchain/chains';
import { PromptTemplate } from '@langchain/core/prompts';
import { documentProcessor } from './document-processor.js';
import { logger } from '../utils/logger.js';
/**
* 使用 LangChain 实现的 RAG 服务
*/
export class RAGServiceLangChain {
constructor() {
this.vectorStore = null;
this.chain = null;
this.embeddings = null;
this.llm = null;
}
/**
* 初始化
*/
async initialize() {
// 初始化 Embeddings
this.embeddings = new OpenAIEmbeddings({
openAIApiKey: process.env.OPENAI_API_KEY
});
// 初始化 LLM
this.llm = new ChatOpenAI({
modelName: 'gpt-3.5-turbo',
temperature: 0.7,
openAIApiKey: process.env.OPENAI_API_KEY
});
// 创建空的向量存储
this.vectorStore = await MemoryVectorStore.fromTexts(
[],
[],
this.embeddings
);
// 创建 RAG Chain
await this.createChain();
}
/**
* 添加文档
*/
async addDocument(text, metadata = {}) {
try {
// 处理文档(分块)
const chunks = documentProcessor.chunkText(text, 500, 50);
const texts = chunks.map(chunk => chunk.text);
const metadatas = chunks.map((chunk, index) => ({
...metadata,
chunkIndex: index
}));
// 添加到向量存储
await this.vectorStore.addTexts(texts, metadatas);
logger.info(`添加了 ${texts.length} 个文档块`);
} catch (error) {
logger.error('添加文档失败:', error);
throw error;
}
}
/**
* 创建 Chain
*/
async createChain() {
const prompt = PromptTemplate.fromTemplate(
`你是一个智能文档助手,基于提供的文档内容回答问题。
文档内容:
{context}
问题:{question}
回答要求:
1. 只基于文档内容回答
2. 如果文档中没有相关信息,明确说明
3. 回答要准确、简洁、有条理
4. 使用 Markdown 格式化
回答:`
);
this.chain = RetrievalQAChain.fromLLM(
this.llm,
this.vectorStore.asRetriever({
k: 5 // 返回最相关的5个文档
}),
{
prompt: prompt,
returnSourceDocuments: true
}
);
}
/**
* 回答问题
*/
async answerQuestion(question) {
try {
if (!this.chain) {
await this.initialize();
}
const result = await this.chain.call({
query: question
});
return {
answer: result.text,
sources: result.sourceDocuments.map(doc => ({
text: doc.pageContent.substring(0, 200) + '...',
metadata: doc.metadata
}))
};
} catch (error) {
logger.error('RAG 回答失败:', error);
throw error;
}
}
/**
* 流式回答
*/
async streamAnswerQuestion(question, callbacks = {}) {
const { onChunk, onComplete, onError } = callbacks;
try {
if (!this.chain) {
await this.initialize();
}
// 检索相关文档
const retriever = this.vectorStore.asRetriever({ k: 5 });
const docs = await retriever.getRelevantDocuments(question);
// 组装上下文
const context = docs.map(doc => doc.pageContent).join('\n\n');
// 流式生成回答
const stream = await this.llm.stream(
`基于以下文档内容回答问题:\n\n${context}\n\n问题:${question}`
);
let fullContent = '';
for await (const chunk of stream) {
const content = chunk.content || '';
if (content) {
fullContent += content;
if (onChunk) {
onChunk(content);
}
}
}
if (onComplete) {
onComplete({
answer: fullContent,
sources: docs.map(doc => ({
text: doc.pageContent.substring(0, 200) + '...',
metadata: doc.metadata
}))
});
}
} catch (error) {
logger.error('流式 RAG 失败:', error);
if (onError) {
onError(error);
}
}
}
}
export const ragServiceLangChain = new RAGServiceLangChain();
作业7:创建 LangChain 路由
src/routes/langchain.js:
import express from 'express';
import { ragServiceLangChain } from '../services/rag-langchain.js';
import { createSimpleAgent } from '../agents/simple-agent.js';
import { logger } from '../utils/logger.js';
export const langchainRouter = express.Router();
// 初始化 LangChain 服务
ragServiceLangChain.initialize().catch(err => {
logger.error('LangChain 初始化失败:', err);
});
// POST /api/langchain/rag/answer
langchainRouter.post('/rag/answer', async (req, res) => {
try {
const { question } = req.body;
if (!question) {
return res.status(400).json({
success: false,
error: '问题不能为空'
});
}
const result = await ragServiceLangChain.answerQuestion(question);
res.json({
success: true,
data: result
});
} catch (error) {
logger.error('LangChain RAG 错误:', error);
res.status(500).json({
success: false,
error: error.message
});
}
});
// POST /api/langchain/rag/add-document
langchainRouter.post('/rag/add-document', async (req, res) => {
try {
const { text, metadata = {} } = req.body;
if (!text) {
return res.status(400).json({
success: false,
error: '文本内容不能为空'
});
}
await ragServiceLangChain.addDocument(text, metadata);
res.json({
success: true,
message: '文档添加成功'
});
} catch (error) {
logger.error('添加文档错误:', error);
res.status(500).json({
success: false,
error: error.message
});
}
});
// POST /api/langchain/agent
langchainRouter.post('/agent', async (req, res) => {
try {
const { question } = req.body;
if (!question) {
return res.status(400).json({
success: false,
error: '问题不能为空'
});
}
const agent = await createSimpleAgent();
const result = await agent.invoke({ input: question });
res.json({
success: true,
data: {
answer: result.output
}
});
} catch (error) {
logger.error('Agent 错误:', error);
res.status(500).json({
success: false,
error: error.message
});
}
});
遇到的问题
问题1:LangChain 版本兼容
解决方案:
# 使用稳定版本
npm install langchain@^0.1.0 @langchain/openai@^0.0.14
问题2:Memory 使用
解决方案:
import { ConversationBufferMemory } from 'langchain/memory';
const memory = new ConversationBufferMemory();
const chain = new ConversationChain({
llm: llm,
memory: memory
});
学习总结
今日收获
- ✅ 理解 LangChain 核心概念
- ✅ 掌握 Chain 和 Agent
- ✅ 实现工具链集成
- ✅ 使用 LangChain 重构项目
- ✅ 学习最佳实践
关键知识点
- LangChain 简化开发,提供丰富的组件
- Chain 串联组件,实现复杂流程
- Agent 智能决策,自动选择工具
- 模块化设计,易于扩展和维护
LangChain 优势
- ✅ 代码更简洁
- ✅ 功能更强大
- ✅ 易于扩展
- ✅ 社区支持好
明日计划
明天将学习:
期待明天的学习! 🚀
参考资源
代码仓库
项目已更新:
- ✅ LangChain 集成
- ✅ Chain 实现
- ✅ Agent 实现
- ✅ RAG 重构
GitHub 提交: Day 11 - LangChain 框架学习
标签: #AI学习 #LangChain #框架学习 #Chain #Agent #学习笔记
写在最后
今天学习了 LangChain 框架,这是一个强大的 AI 应用开发工具。
通过 LangChain,可以更高效地构建 AI 应用,代码更简洁,功能更强大。
明天将学习本地模型部署,实现离线 AI 功能!
继续加油! 💪
快速检查清单
完成这些,第十一天就达标了! ✅

浙公网安备 33010602011771号