news 2026/6/5 8:37:46

LangChain 核心概念与组件

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
LangChain 核心概念与组件

LangChain 是什么?

LangChain 是一个用于构建 LLM 应用的框架,提供了:

  • 组件(Components):可复用的 Prompt、Model、Embedding、Retriever 等

  • 链(Chains):将多个组件串联成一个处理流程

  • 代理(Agents):让 LLM 自主决策调用哪些工具


核心组件

1. Model(模型)

LangChain 支持多种 LLM:

from langchain.chat_models import ChatOpenAI from langchain.llms import OpenAI ​ # ChatGPT chat_model = ChatOpenAI( model="gpt-4", temperature=0.7, max_tokens=1000 ) ​ # GPT-4 llm = OpenAI(model="gpt-4", temperature=0.9) ​ # 通义千问 from langchain.chat_models import Tongyi qwen = Tongyi(temperature=0.9)

2. Prompt(提示词)

from langchain.prompts import PromptTemplate, ChatPromptTemplate ​ # 简单模板 template = PromptTemplate( input_variables=["product"], template="为 {product} 写一个吸引人的广告语" ) prompt = template.format(product="手机") print(prompt) # "为 手机 写一个吸引人的广告语" ​ # 对话模板 chat_template = ChatPromptTemplate.from_messages([ ("system", "你是一个专业的{field}顾问"), ("user", "{question}") ]) messages = chat_template.format_messages(field="法律", question="遗产继承怎么处理")

3. Chain(链)

把多个步骤串联起来:

from langchain.chains import LLMChain ​ chain = LLMChain( llm=chat_model, prompt=template ) ​ # 执行 result = chain.run(product="咖啡机") print(result)

4. Memory(记忆)

from langchain.memory import ConversationBufferMemory ​ memory = ConversationBufferMemory() ​ chain = LLMChain( llm=chat_model, prompt=chat_prompt, memory=memory ) ​ # 对话 chain.run(input="我叫张三") chain.run(input="我叫什麼?") # 能记住"张三"

5. Retriever(检索器)

from langchain.retrievers import Retriever ​ # 从 VectorStore 创建 Retriever retriever = vectorstore.as_retriever( search_kwargs={"k": 3} # 返回Top-3 ) ​ # 使用 docs = retriever.get_relevant_documents("什么是机器学习")

LCEL(LangChain Expression Language)

LCEL 是 LangChain 的链式调用语法,让链的编写更直观。

基础语法

from langchain.prompts import PromptTemplate from langchain.chat_models import ChatOpenAI from langchain.schema import StrOutputParser ​ # 方式1:runnable 接口 chain = ( PromptTemplate.from_template("用一句话解释:{topic}") | ChatOpenAI(model="gpt-4") | StrOutputParser() ) ​ result = chain.invoke({"topic": "量子计算"}) print(result)

什么是 Runnable?

Runnable 是 LangChain 的核心接口,所有组件都实现了这个接口:

class Runnable: def invoke(self, input): ... def batch(self, inputs): ... # 批量 def stream(self, input): ... # 流式 def pipe(self, other): ... # | 操作符

常用 Runnable 组件

from langchain.schema import StrOutputParser from langchain.runnable import RunnableParallel, RunnablePassthrough ​ # StrOutputParser:把输出转为字符串 # RunnablePassthrough:透传输入 # RunnableParallel:并行执行多个任务

并行与串行

from langchain.runnable import RunnableParallel ​ # 串行 chain1 = PromptTemplate.from_template("{topic}是什么?") | model | output ​ # 并行 parallel_chain = RunnableParallel( topic_explain=chain1, topic_examples=( PromptTemplate.from_template("列举3个{topic}的例子") | model | output ) ) ​ result = parallel_chain.invoke({"topic": "人工智能"}) # result = {"topic_explain": "...", "topic_examples": "..."}

RAG 在 LangChain 中的实现

完整 RAG 链

from langchain.chat_models import ChatOpenAI from langchain.prompts import PromptTemplate from langchain.schema import StrOutputParser from langchain.schema.runnable import RunnablePassthrough ​ # 1. 创建 Retriever retriever = vectorstore.as_retriever(search_kwargs={"k": 3}) ​ # 2. 组装 RAG 链 rag_chain = ( { "two": retriever | RunnablePassthrough(), "one": RunnablePassthrough() } | PromptTemplate.from_template( "基于以下上下文回答问题。\n" "如果上下文不足,回答'我无法回答'。\n\n" "上下文:{two}\n\n" "问题:{one}" ) | ChatOpenAI(model="gpt-4", temperature=0) | StrOutputParser() ) ​ # 3. 执行 result = rag_chain.invoke("什么是机器学习?")

带Citations的RAG(可溯源)

from langchain.prompts import PromptTemplate ​ class RagWithCitations: def __init__(self, vectorstore, model): self.retriever = vectorstore.as_retriever(k=3) self.model = model ​ def invoke(self, question): # 检索 docs = self.retriever.get_relevant_documents(question) ​ # 组装上下文(带来源) context_parts = [] for i, doc in enumerate(docs): context_parts.append(f"[{i+1}] {doc.page_content}\n来源:{doc.metadata}") ​ context = "\n".join(context_parts) ​ # 生成回答 prompt = f"""基于以下上下文和编号回答问题。 每个编号对应一个来源,回答时用 [编号] 标注来源。 ​ 上下文: {context} ​ 问题:{question} ​ 请基于上下文回答,回答时用 [编号] 标注来源。""" ​ response = self.model.call(prompt) ​ return { "answer": response, "sources": [doc.metadata for doc in docs] }

自定义组件

自定义 Retriever

from langchain.schema import BaseRetriever from langchain.schema import Document ​ class MyRetriever(BaseRetriever): def __init__(self, vectorstore, top_k=5): self.vectorstore = vectorstore self.top_k = top_k ​ def get_relevant_documents(self, query): # 自定义检索逻辑 docs = self.vectorstore.similarity_search(query, k=self.top_k) ​ # 自定义过滤逻辑 filtered = [doc for doc in docs if self._is_relevant(doc)] ​ return filtered ​ def _is_relevant(self, doc): # 自定义相关性判断 return doc.metadata.get("category") == "tech" ​ async def aget_relevant_documents(self, query): # 异步版本 return self.get_relevant_documents(query)

自定义 Document Transformer

from langchain.schema import Document from langchain.text_splitter import TextSplitter ​ class CustomTextSplitter(TextSplitter): def split_text(self, text): # 自定义切分逻辑 paragraphs = text.split("\n\n") chunks = [] ​ for para in paragraphs: if len(para) > 500: # 大段落再细分 sentences = para.split("。") current = "" for sent in sentences: if len(current) + len(sent) > 300: if current: chunks.append(current) current = sent else: current += sent + "。" if current: chunks.append(current) else: chunks.append(para) ​ return [c.strip() for c in chunks if c.strip()]

自定义 Embedding

from langchain.embeddings import BaseEmbeddings import numpy as np ​ class MyEmbedding(BaseEmbeddings): def __init__(self, model_path): from my_model import load_model self.model = load_model(model_path) ​ def embed_query(self, text): vec = self.model.encode(text) return vec.tolist() ​ def embed_documents(self, texts): vecs = self.model.encode(texts) return vecs.tolist() ​ @property def embedding_dimension(self): return 768

Chain 的高级用法

Router Chain(路由链)

from langchain.chains import RouterChain from langchain.prompts import PromptTemplate ​ # 定义多个子链 math_chain = LLMChain(llm=model, prompt=math_prompt) history_chain = LLMChain(llm=model, prompt=history_prompt) ​ # 路由选择器 router_chain = RouterChain( default_chain=general_chain, router_chain=LLMChain( llm=model, prompt=RouterPromptTemplate.from_template(router_template) ), destination_chains={ "math": math_chain, "history": history_chain } ) ​ # 自动路由 result = router_chain.run(user_input)

Sequential Chain(顺序链)

from langchain.chains import SequentialChain ​ # 链1:翻译 chain1 = LLMChain( llm=model, prompt=PromptTemplate.from_template("把以下中文翻译成英文:{text}") ) ​ # 链2:改写 chain2 = LLMChain( llm=model, prompt=PromptTemplate.from_template("把以下英文改写成更正式的版本:{text}") ) ​ # 串联 full_chain = SequentialChain( chains=[chain1, chain2], input_variables=["text"], output_variables=["formal_text"] ) ​ result = full_chain.run(text="我想请假") # chain1 输出英文 → chain2 输入 → 最终输出正式英文

输出解析器

from langchain.output_parsers import PydanticOutputParser from pydantic import BaseModel ​ class Answer(BaseModel): result: str confidence: float sources: List[str] ​ parser = PydanticOutputParser(pydantic_object=Answer) ​ chain = ( PromptTemplate.from_template("{question}") | model | parser ) ​ result = chain.invoke({"question": "什么是AI?"}) # result 是 Answer 对象,不是字符串

回调与监控

from langchain.callbacks import CallbackManager ​ class MyCallbackHandler(BaseCallbackHandler): def on_llm_start(self, serialized, prompts, **kwargs): print(f"LLM 开始处理 {len(prompts)} 个 prompt") ​ def on_llm_end(self, response, **kwargs): print(f"LLM 完成,输出:{response}") ​ def on_chain_start(self, serialized, inputs, **kwargs): print(f"链开始:{serialized}") ​ chain = LLMChain( llm=model, prompt=prompt, callback_manager=CallbackManager([MyCallbackHandler()]) )

面试常问

Q: LangChain 的核心概念是什么?

A:

  • Model:LLM 调用接口

  • Prompt:提示词模板管理

  • Chain:将多个组件串联成工作流

  • Agent:让 LLM 自主决策的工具调用循环

  • Memory:对话历史管理

Q: LCEL 是什么?有什么优势?

A:

  • LCEL(LangChain Expression Language)是 LangChain 的链式调用语法

  • 使用|操作符串联组件,如prompt | model | output_parser

  • 优势:语法简洁、支持流式、内置异步支持、方便调试

Q: LangChain 的缺点是什么?

A:

  • 抽象层多,调试困难(问题定位不清晰)

  • 版本迭代快,API 不稳定

  • 对于简单场景,过于复杂

  • 性能开销(多了很多中间层)

  • 依赖过多,部署复杂

Q: 如何自定义 Retriever?

A:

  • 继承 BaseRetriever

  • 实现get_relevant_documents(query)方法

  • 可以组合多个检索器(Ensemble Retriever)

  • 可以加后处理过滤逻辑

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/6/5 8:36:58

智印 · Zebra RFID 标签设计器(zebra-rfid-zpl-designer) 文档包

zebra-rfid-zpl-designer 文档包 智印 Zebra RFID 标签设计器(npm:zebra-rfid-zpl-designer)— 面向 Web 与 Node 的 RFID 标签 ZPL 设计、生成、校验、预览与打印插件。 👉 产品背景、能力与场景说明见 产品介绍.md 本目录为…

作者头像 李华
网站建设 2026/6/5 8:36:02

HsMod:基于BepInEx的炉石传说模块化改造框架技术解析

HsMod:基于BepInEx的炉石传说模块化改造框架技术解析 【免费下载链接】HsMod Hearthstone Modification Based on BepInEx 项目地址: https://gitcode.com/GitHub_Trending/hs/HsMod HsMod是一个基于BepInEx框架构建的炉石传说游戏增强插件,采用非…

作者头像 李华
网站建设 2026/6/5 8:34:04

购买大批量广告账号 vs. 自主养号:核算 ROI 与潜在风险

数字广告生态系统通常像是一场老鼠躲避猫的游戏,而平台始终占据着高地。对于媒介投放人员(Media Buyers)和联盟营销人员(Affiliate Marketers)而言,"账号"是生产的基本单位。然而,一个…

作者头像 李华
网站建设 2026/6/5 8:33:07

实战virtualbox搭建攻防靶场:快马ai生成完整网络拓扑与渗透脚本

快速体验 打开 InsCode(快马)平台 https://www.inscode.net输入框内输入如下内容: 请生成一个基于virtualbox的实战项目:构建一个小型企业级网络攻防靶场。项目需包含:第一,使用virtualbox虚拟机组网功能,构建一个包…

作者头像 李华
网站建设 2026/6/5 8:31:38

Java线程及线程池的相关的问题

1、线程池有哪些状态线程池在Java中有五种状态:RUNNING(运行状态)线程创建后默认进入此状态,能够接受新任务并处理任务队列中的任务。如果不调用关闭方法,线程池会一直保持此状态。SHUTDOWN(关闭状态&#…

作者头像 李华
网站建设 2026/6/5 8:28:40

手把手教你用Python解析Intel HEX文件(附完整代码)

用Python构建工业级Intel HEX解析器:从文件结构到自动化转换实战在嵌入式开发中,Intel HEX文件就像一位严谨的邮差——它将二进制数据分装进带有地址标签的信封(记录行),确保每个字节都能准确送达芯片存储器的指定位置…

作者头像 李华