(UPDATING)LangChain开发框架,Model I/O,Chains,RAG流程,agent
LangChain是2022年10月,由哈佛大学的Harrison Chase(哈里森·蔡斯)发起研发的一个开源框架,用于开发由大语言模型(LLMs)驱动的应用程序。比如,搭建Agent、问答系统(QA)、对话机器人、文档搜索系统等。LangChain是一个帮助你构建LLM应用的全套工具集。这里涉及到prompt构建、LLM接入、记忆管理、工具调用、RAG、Agent开发等模块。LangChain
github地址:https://github.com/langchain-ai/langchain
官网地址:https://www.langchain.com/langchain
官方文档:https://docs.langchain.com/oss/python/langchain/overview
API文档:https://reference.langchain.com/python/langchain/
一、LangChain概述
LangChain是2022年10月,由哈佛大学的Harrison Chase(哈里森·蔡斯)发起研发的一个开源框
架,用于开发由大语言模型(LLMs)驱动的应用程序。比如,搭建Agent、问答系统(QA)、对
话机器人、文档搜索系统等。

LangChain是一个帮助你构建LLM应用的全套工具集。这里涉及到prompt构建、LLM接入、记忆管
理、工具调用、RAG、Agent开发等模块。

LangChain:快速搭建 Agent,灵活适配任意模型提供商。
LangGraph:精细编排 Agent 流程,支持记忆、人工介入与长时间任务管理。
LangSmith:持续测试与改进 AI 的集成平台,提供观测、评估与部署能力。
Deep Agents:构建可规划、调用子 Agent 并操作文件系统的复杂 Agent,灵感源自 Claude Code、Deep Research 与 Manus 等应用。

1、开发架构与开发场景

1、RAG开发
LLM在考试的时候面对陌生的领域,答复能力有限,然后就准备放飞自我了,而此时RAG给了一些
提示和参考,让LLM根据参考回答,最终考试的正确率从60%到了90%!

2、Agent开发
充分利用LLM的推理决策能力,通过增加规划、记忆和工具调用的能力,构造一个能够独立思考、
逐步完成给定目标的Agent。

3、大模型应用开发的4个场景
1 纯 Prompt
通过自然语言与模型交互,一问一答。
2 Agent + Function Calling
Agent 主动提出调用外部功能的需求由 Function Calling 对接外部系统。例如询问天气时,Agent 先引导获取天气信息,再给出建议。
3 RAG(检索增强生成)
通过向量化、向量数据库与相似度检索,从外部知识库中查找相关内容辅助生成回答。广泛用于智能客服,类比考试时查阅资料再作答。
4 微调(Fine-tuning)
在模型基础上进行定制训练,使其长期掌握特定知识或能力。成本最高,仅当前述方式无法满足需求时使用。
2、核心组件
Model I/O、Chains、RAG、Agents。
二、Model I/O

1、大模型在线平台
1)CloseAI:https://platform.closeai-asia.com/
API-Key管理:https://platform.closeai-asia.com/developer/api
API文档:https://doc.closeai-asia.com/tutorial/api/openai.html
模型:https://platform.closeai-asia.com/pricing
2)OpenRouter:https://openrouter.ai/
API-Key管理:https://openrouter.ai/settings/keys
API文档:https://openrouter.ai/docs/community/frameworks-and-integrations-overview
模型:https://openrouter.ai/models
3)阿里云百炼:https://bailian.console.aliyun.com/API-Key管理:https://bailian.console.aliyun.com/?tab=model#/api-key
API文档:https://bailian.console.aliyun.com/?tab=doc#/doc/?type=model
模型:https://bailian.console.aliyun.com/?tab=model#/model-market/all
4)百度千帆:https://console.bce.baidu.com/qianfan/overview
API-Key管理:https://console.bce.baidu.com/qianfan/ais/console/apiKey
API文档:https://cloud.baidu.com/doc/qianfan-docs/s/Mm8r1mejk
模型:https://console.bce.baidu.com/qianfan/modelcenter/model/buildIn/list
5)硅基流动:https://www.siliconflow.cn/
API-Key管理:https://cloud.siliconflow.cn/me/account/ak
API文档:https://docs.siliconflow.cn/cn/userguide/capabilities/text-generation
模型:https://cloud.siliconflow.cn/me/models
2、OpenAI SDK调用模型
1、直接把配置写死
from openai import OpenAI
api_key = "sk-2a44cf0e0e4e438d8c37e770269efc95"
api_base_url = "https://api.deepseek.com"
client = OpenAI(
api_key=api_key,
base_url=api_base_url,
)
response =client.chat.completions.create(model = 'deepseek-chat',messages = [{"role": "system", "content": "You are a helpful assistant."}])
print(response.choices[0].message.content)
2、把配置写到环境里
写到环境变量里,然后文件目录选择当前文件

api_key=os.getenv("OPENAI_API_KEY"),
base_url=os.getenv("OPENAI_API_URL"),
3、通过配置文件配置(推荐)
OPENAI_API_KEY = sk-2a44cf0e0e4e438d8c37e770269efc95
OPENAI_BASE_URL = https://api.deepseek.com
from openai import OpenAI
import os
import dotenv
dotenv.load_dotenv()
openai_api_key = os.getenv('OPENAI_API_KEY')
openai_base_url = os.getenv('OPENAII_BASE_URL')
client = OpenAI(
api_key=openai_api_key,
base_url=openai_base_url,
)
response =client.chat.completions.create(model = 'deepseek-chat',messages = [{"role": "system", "content": "hello."}])
print(response.choices[0].message.content)
3、langchain大模型API调用
init_chat_model参数

from langchain.chat_models import init_chat_model
from langchain_core.messages import AIMessage,SystemMessage,HumanMessage
import dotenv
import os
dotenv.load_dotenv()
api_key = os.getenv("OPENAI_API_KEY")
base_url = os.getenv("OPENAI_BASE_URL")
# 获取大模型实例
model = init_chat_model(
model = 'deepseek-chat',
model_provider = 'deepseek',
api_key=api_key,
base_url = base_url
)
# 构造一个提示词模板
message = [
SystemMessage(content = "你是一个智能助手,可以帮助用户解决问题,你的名字叫小智"),
HumanMessage(content = '你是谁')
]
# 调用model的invoke方法
response = model.invoke(message)
print(response.content)
4、Message
构造消息的几种方式
1、直接使用文本
![]()
2、使用HumanMessage等类的方式构建消息列表
message = [
SystemMessage(content = "你是一个智能助手,可以帮助用户解决问题,你的名字叫小智"),
HumanMessage(content = '你是谁')
]
# 调用model的invoke方法
response = model.invoke(message)
print(response.content)
3、通过字典的方式构建消息列表
message = [
{'role':'system','content':'你是一个智能助手,可以帮助用户解决问题,你的名字叫小智'},
{'role':'human','content':'你是谁'},
]
# 调用model的invoke方法
response = model.invoke(message)
print(response.content)
5、调用方法

1、非流式输出
这是LangChain与LLM交互时的默认行为,是最简单、最稳定的语言模型调用方式。当用户发出请
求后,系统在后台等待模型生成完整响应,然后一次性将全部结果返回。
response = model.invoke(message)
print(response.content)
2、流式输出
返回一个generator
response = model.stream(message)
for chunk in response:
print(chunk.content,end='')
print(response)
你好!我是小智,一个智能助手,随时准备为你提供帮助。无论是回答问题、解决问题,还是陪你聊天,我都在这里!有什么我可以为你做的吗? 😊<generator object BaseChatModel.stream at 0x000002096C888400>
3、批量输出
messages = [
[{"role": "system", "content": "你是一位诗人"},
{"role": "user", "content": "写一首关于春天的诗"},],
[{"role": "system", "content": "你是一位诗人"},
{"role": "user", "content": "写一首关于夏天的诗"},],
[{"role": "system", "content": "你是一位诗人"},
{"role": "user", "content": "写一首关于秋天的诗"},],
]
response = model.batch(messages)
print(response[0].content)
《春日偶成》
东君执彩笔,泼洒到人间。
染绿千山树,催红万圃兰。
莺梭织烟柳,鱼影动春潭。
风暖衣衫薄,斜阳独倚栏。
注:我的仿写以传统手法勾勒春之画卷。通过“东君执笔”的意象,将自然造化喻为艺术创作,随后以“染绿”、“催红”展现春色的动态蔓延。颈联“莺梭”、“鱼影”赋予生灵精巧的灵动感,尾联在暖风与斜阳中收束于闲适的独倚,暗合古典春诗里物我相融的审美意趣。
4、同步/异步调用
同步调用:多次请求串行处理
messages = [
[{"role": "system", "content": "你是一位诗人"},
{"role": "user", "content": "写一首关于春天的诗"},],
[{"role": "system", "content": "你是一位诗人"},
{"role": "user", "content": "写一首关于夏天的诗"},],
[{"role": "system", "content": "你是一位诗人"},
{"role": "user", "content": "写一首关于秋天的诗"},],
]
import time
start_time = time.time()
response = [model.invoke(messages) for messages in messages]
end_time = time.time()
print(f'总耗时:{end_time - start_time}')
总耗时:15.489471912384033
异步调用:model.invoke方法,返回一个协程对象,把多个协程对象打包成一个协程对象,await
最终协程对象,实现异步调用。
import time
import asyncio
async def gather_task(message:list):
tasks = [model.ainvoke(message_list) for message_list in message]
return await asyncio.gather(*tasks)
async def main():
start_time = time.time()
results = await gather_task(messages)
end_time = time.time()
print(f'总耗时{end_time - start_time}')
asyncio.run(main())
总耗时6.741662979125977
5、拓展协程案例
import asyncio
async def func1():
print('func1 开始')
await asyncio.sleep(3)
print('func1 结束')
async def func2():
print('func2 开始')
await asyncio.sleep(5)
print('func2 结束')
async def func3():
print('func3 开始')
await asyncio.sleep(8)
print('func3 结束')
async def main():
await asyncio.gather(func1(), func2(), func3())
import time
start = time.time()
asyncio.run(main())
end = time.time()
func1 开始
func2 开始
func3 开始
func1 结束
func2 结束
func3 结束
6、调用本地模型Ollama
Ollama官方地址:https://ollama.com
Ollama Github开源地址:https://github.com/ollama/ollama
pip install langchain-ollama
首先要在ollama中下载好模型,也可以在ollama的setting中加载已经下好的模型。


model中的模型id必须和ollama中的一样,base_url如果不写就是默认部署在本机。
from langchain_ollama import ChatOllama
# 构造ollama客户端实例
ollama = ChatOllama(
model = 'qwen3:4b',
base_url = 'xxx',
)
ollama.invoke('你好')
7、PromptTemplate的实例化和调用
两种实例化方式
from langchain_core.prompts import PromptTemplate
template1 = PromptTemplate(
template = '你是一个翻译助手,帮助用户将{content}翻译成语言:{lang}',
input_variables = ['content','lang']
)
response = template1.format(content = '什么是LangChain',lang = '英语')
template2 = PromptTemplate.from_template(
template = '你是一个翻译助手,帮助用户将{content}翻译成语言:{lang}'
)
两种调用方式
response1 = template1.format(content = '什么是LangChain',lang = '英语')
response2 = template1.invoke({'content':'什么是langchain','lang':'英语'})
一个简单综合案例
from langchain_openai import ChatOpenAI
from langchain_core.prompts import ChatPromptTemplate
import dotenv
import os
import base64
dotenv.load_dotenv()
api_key = os.getenv("OPENAI_API_KEY")
base_url = os.getenv("OPENAI_BASE_URL")
client = ChatOpenAI(
model = 'gpt-4o-mini',
api_key = api_key,
base_url = base_url,
)
def encode_image(image_path):
with open(image_path, "rb") as f:
return base64.b64encode(f.read()).decode("utf-8")
image_path = r"C:\Users\77485\Desktop\屏幕截图 2026-03-26 214358.png"
image_base64 = encode_image(image_path)
template = ChatPromptTemplate.from_messages([
("system", "用中文简短描述图片内容"),
("user", [
{
"type": "image_url",
"image_url": {
"url": "data:image/png;base64,{image_base64}"
}
}
])
])
prompt = template.format_messages(
image_base64=image_base64
)
res = client.invoke(prompt)
print(res.content)
这张图片中有一个人穿着带有大星星图案的黑色上衣,搭配一件外套,头发披肩,看起来像是在参加某个活动或表演。背景是黑色的,给人一种时尚和活力的感觉。
8、OutputParser
输出解析器:将大模型原始自然语言类型的输出,解析成程序所需要的结构化输出,以下是原始输
出案例。
from langchain_openai import ChatOpenAI
import dotenv
dotenv.load_dotenv()
openai_llm = ChatOpenAI(
model = 'gpt-4o-mini'
)
res = openai_llm.invoke('帮我推荐几部诺兰的电影')
print(res.content)
克里斯托弗·诺兰是一位备受赞誉的导演,以其复杂的叙事结构和出色的视觉效果著称。以下是几部他的代表作品推荐:
1. **《盗梦空间》(Inception, 2010)** - 这部影片围绕梦境与现实的界限展开,讲述了一组盗贼通过侵入他人梦境来盗取信息的故事。影片充满了心理学元素和视觉奇观。
2. **《黑暗骑士三部曲》**
- **《蝙蝠侠:侠影之谜》(Batman Begins, 2005)**
- **《蝙蝠侠:黑暗骑士》(The Dark Knight, 2008)**
- **《蝙蝠侠:黑暗骑士崛起》(The Dark Knight Rises, 2012)** - 这三部影片重新定义了超级英雄电影,特别是《黑暗骑士》,其对反派小丑的刻画备受赞誉。
3. **《记忆碎片》(Memento, 2000)** - 这是一部非线性叙事的惊悚片,讲述了一位失去短期记忆的男子在追寻妻子凶手过程中的故事,思维的复杂性令人深思。
4. **《超能查派》(Interstellar, 2014)** - 这部科幻电影探讨了时间、爱与人类求生的主题,描绘了一场跨越时空的宇宙冒险。
5. **《敦刻尔克》(Dunkirk, 2017)** - 这部影片以二战敦刻尔克大撤退为背景,通过多条时间线展示了士兵们的生存斗争,形式创新且充满紧张感。
6. **《信条》(Tenet, 2020)** - 这是一部涉及时间逆转的科幻动作片,讲述了特工如何利用时间的不同流向来阻止世界大战的故事。
这些电影各有特色,展示了诺兰在讲故事和视觉呈现方面的非凡才华。希望你会喜欢!
1、JSONOutputParser
##通过pydantic类去定义JSON的结构并构造JsonOutputParser的实例
##在system_message中添加需要大模型按照json结构回复的prompt,添加方式通过output_parser.get_format_instructions,接下来大模型就可以回复一个json的字符串
##通过调用output_parser.invoke方法,可以更进一步将大模型输出的字符串解析成字典对象
from langchain_core.output_parsers import JsonOutputParser
from pydantic import BaseModel,Field
from langchain_core.prompts import ChatPromptTemplate
# 构造实例
# 构造参数pydantic_object
# pydantic包的作用:定义一个数据结构schema
# jsonoutputpaser使用pydantic定义的数据结构来定义json当中的key有哪些,分别的结构是什么
class FilmSuggestion(BaseModel):
film_name : str = Field(description='电影名称')
year : str = Field(description='上映年份')
description : str = Field(description='电影概述')
output_paser = JsonOutputParser(pydantic_object=FilmSuggestion)
output_paser.get_format_instructions()
messages = [
('system','回答用户问题,按照以下形式做输出:{output_format}'),
('user','{user_question}')
]
template = ChatPromptTemplate.from_messages(
messages
)
llm_output = openai_llm.invoke(template.invoke({'output_format':output_paser.get_format_instructions(),'user_question':'帮我推荐几部诺兰的电影'}))
output_paser.invoke(llm_output)
{'film_name': '盗梦空间',
'year': '2010',
'description': '讲述了一名专业小偷通过潜入他人的梦境中窃取机密信息的故事。'}
2、StrOutputParser
我们一般情况想要知道内容是调用.content方法,比如:
from langchain_core.output_parsers import StrOutputParser
str_output_parser = StrOutputParser()
res = openai_llm.invoke('你是谁')
print(res.content)
我是一个人工智能助手,旨在回答问题和提供信息。如果你有什么想了解的,欢迎问我!
但是这样很不方便,所以可以使用StrOutputParser
from langchain_core.output_parsers import StrOutputParser
str_output_parser = StrOutputParser()
res = openai_llm.invoke('你是谁')
str_output_parser.invoke(res)
'我是一个人工智能助手,旨在回答问题和提供帮助。如果你有任何问题或需要了解的内容,随时问我!'
3、大模型自身提供的Structured Output
structured_llm = openai_llm.with_structured_output(schema = FilmSuggestion)
structured_llm.invoke('帮我推荐几部诺兰的电影')
FilmSuggestion(film_name='盗梦空间', year='2010', description='讲述了一名专业盗梦者通过进入他人的梦境来窃取信息和植入思想的故事。电影探讨了现实与梦境的界限,视觉效果和复杂的叙事结构令人难以忘怀。')
三、Chains
“链条”用于将多个组件组合成一个完整的流程,方便链式调用。
1、Runnable与LCEL
1、Runnable
Runnable是LangChain中可以调用、批处理、流式传输、转换和组合的工作单元。Runnable接口
是使用LangChain组件的基础,它在许多组件中实现,例如语言模型、输出解析器、检索器、编译
的LangGraph图等。

2、LCEL
LangChain表达式语言(LCEL,LangChain Expression Language)是一种从现有的Runnable构
建新的Runnable的声明式方法,通过“ | ”将langchain中的不同组件组装在一起构成一个chain。
from langchain_core.prompts import PromptTemplate
from langchain_openai import ChatOpenAI
from langchain_core.output_parsers import StrOutputParser
import dotenv
dotenv.load_dotenv()
prompt_template = PromptTemplate(input_variables=['user_info'],template='{user_info}')
openai_llm = ChatOpenAI()
output_parser = StrOutputParser()
chain = prompt_template | openai_llm | output_parser
type(chain)
chain.invoke({"user_info": "你好"})
'你好!有什么可以帮助你的吗?😊'
2、RunnableSequence
构造一个串行的执行链,通过runnable_sequence的实例调用invoke方法,就等于链当中每一个组
件去调用invoke,然后将调用结果传递给下一个组件。
from langchain_core.runnables import RunnableSequence
from langchain_core.prompts import PromptTemplate
from langchain_openai import ChatOpenAI
from langchain_core.output_parsers import StrOutputParser
import dotenv
dotenv.load_dotenv()
prompt_template = PromptTemplate(input_variables=['user_info'],template='{user_info}')
openai_llm = ChatOpenAI()
output_parser = StrOutputParser()
runnable_sequence = RunnableSequence(*[prompt_template, openai_llm, output_parser])
runnable_sequence.invoke('你好,你是谁')
'你好,我是一个人工智能助手,可以和你聊天和回答问题。有什么我可以帮助你的吗?'
3、RunnableParallel
from langchain_core.runnables import RunnableParallel
def fun1(a1):
return a1+'__func1_output'
def fun2(a1):
return a1+'__func2_output'
runnable_parallel = RunnableParallel({'key1': fun1, 'key2': fun2})
runnable_parallel.invoke('你好')
{'key1': '你好__func1_output', 'key2': '你好__func2_output'}
具体应用:对于用户输入的同一个问题,我们想要调用不同的大模型进行回答,用户可以比对不同
大模型回答的效果。
from langchain_openai import ChatOpenAI
from langchain_deepseek import ChatDeepSeek
from langchain_core.prompts import ChatPromptTemplate
openai_llm = ChatOpenAI(
model = 'gpt-4o-mini'
)
deepseek_llm = ChatDeepSeek(
model = 'deepseek-chat',
)
messages = [
('system','你是一个数学家'),
('user','{user_question}')
]
message_template = ChatPromptTemplate.from_messages(messages)
# 结合LCEL和RunnableParallel
chain = message_template | RunnableParallel({'openai_output': openai_llm,'deepseek_output': deepseek_llm})
chain.invoke({'user_question':'什么是哥德巴赫猜想'})
{'openai_output': AIMessage(content='哥德巴赫猜想是一个关于正偶数和素数的数学猜想,最早由德国数学家克里斯蒂安·哥德巴赫在1742年提出。它的表述可以描述为:\n\n任何一个大于2的偶数都可以表示为两个素数之和。\n\n例如:\n- 4 = 2 + 2\n- 6 = 3 + 3\n- 8 = 3 + 5\n- 10 = 5 + 5 或 7 + 3\n\n虽然这个猜想在许多偶数上得到了验证,并且计算机已检查到非常大的数值范围,但到目前为止,仍然没有被证明或反驳。哥德巴赫猜想是数学中最著名的未解难题之一,也是数论中的重要研究主题之一。', additional_kwargs={'refusal': None}, response_metadata={'token_usage': {'completion_tokens': 185, 'prompt_tokens': 24, 'total_tokens': 209, 'completion_tokens_details': {'accepted_prediction_tokens': 0, 'audio_tokens': 0, 'reasoning_tokens': 0, 'rejected_prediction_tokens': 0}, 'prompt_tokens_details': {'audio_tokens': 0, 'cached_tokens': 0}}, 'model_provider': 'openai', 'model_name': 'gpt-4o-mini-2024-07-18', 'system_fingerprint': 'fp_eb37e061ec', 'id': 'chatcmpl-DPqbLvPitLDmvLjlwbFE39GlsmXI5', 'finish_reason': 'stop', 'logprobs': None}, id='lc_run--019d4963-c8bb-7db3-ae77-7d358af7f056-0', tool_calls=[], invalid_tool_calls=[], usage_metadata={'input_tokens': 24, 'output_tokens': 185, 'total_tokens': 209, 'input_token_details': {'audio': 0, 'cache_read': 0}, 'output_token_details': {'audio': 0, 'reasoning': 0}}),
'deepseek_output': AIMessage(content='哥德巴赫猜想是数论中一个著名的未解决问题,由德国数学家克里斯蒂安·哥德巴赫于1742年提出。该猜想的核心内容可以概括为:\n\n**“任何一个大于2的偶数都可以表示为两个素数之和。”**\n\n这个表述通常被称为“强哥德巴赫猜想”或“关于偶数的哥德巴赫猜想”。例如:\n- 4 = 2 + 2\n- 6 = 3 + 3\n- 8 = 3 + 5\n- 10 = 3 + 7 = 5 + 5\n- 100 = 3 + 97 = 11 + 89 = 17 + 83 等等。\n\n---\n\n### 历史背景与相关猜想\n哥德巴赫在与欧拉的通信中提出了两个相关猜想:\n1. **弱哥德巴赫猜想**(或“关于奇数的猜想”):任何大于5的奇数都可以表示为三个素数之和。这个猜想已在2013年由哈洛德·贺欧夫各特等人基本证明(依赖于广义黎曼猜想成立,或对足够大的奇数已无条件证明)。\n2. **强哥德巴赫猜想**(即通常所说的哥德巴赫猜想):如上所述,关于偶数的表述。\n\n---\n\n### 研究进展\n尽管猜想对大量偶数已验证成立(例如计算机已验证到 \\(4 \\times 10^{18}\\) 以内的偶数),但严格的数学证明仍未完成。主要进展包括:\n- **陈景润的工作(1973年)**:证明了“1+2”,即任何一个充分大的偶数都可以表示为一个素数及一个不超过两个素数的乘积之和。这是目前最接近强哥德巴赫猜想的结果。\n- **哈代-李特尔伍德圆法**:为解析数论中研究该猜想提供了重要工具。\n- **筛法的改进**:从布朗的“9+9”逐步推进到陈景润的“1+2”。\n\n---\n\n### 意义与挑战\n哥德巴赫猜想是加法数论的核心问题之一,涉及素数分布的深层结构。其证明可能需要全新的数学工具或对素数理论有更本质的理解。它不仅是数论的标志性难题,也常作为激励数学发展的源泉。', additional_kwargs={'refusal': None}, response_metadata={'token_usage': {'completion_tokens': 455, 'prompt_tokens': 12, 'total_tokens': 467, 'completion_tokens_details': None, 'prompt_tokens_details': {'audio_tokens': None, 'cached_tokens': 0}, 'prompt_cache_hit_tokens': 0, 'prompt_cache_miss_tokens': 12}, 'model_provider': 'deepseek', 'model_name': 'deepseek-chat', 'system_fingerprint': 'fp_eaab8d114b_prod0820_fp8_kvcache_new_kvcache', 'id': 'acca0a80-a22d-4084-8e5d-b9124f48f955', 'finish_reason': 'stop', 'logprobs': None}, id='lc_run--019d4963-c8be-7b50-908a-b8aa4be2013a-0', tool_calls=[], invalid_tool_calls=[], usage_metadata={'input_tokens': 12, 'output_tokens': 455, 'total_tokens': 467, 'input_token_details': {'cache_read': 0}, 'output_token_details': {}})}
4、RunnableLambda
from langchain_core.runnables import RunnableLambda
runnable_lambda = RunnableLambda(lambda x:x+'__lambda_x')
runnable_lambda.invoke('你好')
'你好__lambda_x'
5、RunnablePassThrough
from langchain_core.runnables import RunnablePassthrough
chain = {
"text1": lambda x: x + " world",
"text2": lambda x: x + ", how are you",
} | RunnablePassthrough.assign(word_count=lambda x: len(x["text1"] +
x["text2"]))
result = chain.invoke("hello")
print(result)
# {'text1': 'hello world', 'text2': 'hello, how are you', 'word_count':29}
{'text1': 'hello world', 'text2': 'hello, how are you', 'word_count': 29}
6、RunnableBranch
其实就是一个if_else操作,能够根据我们所写的判断条件,去具体执行某一个分支的逻辑。
传入方式:传入多个分支组成的列表,列表的每一个元素都是一个元组,元组的第一个元素是判断
条件,第二个元素是判断成功之后执行的逻辑。(自上而下判断)
from langchain_core.runnables import RunnableBranch
branch = RunnableBranch(
(lambda x: isinstance(x, str), lambda x: x.upper()),
(lambda x: isinstance(x, int), lambda x: x + 1),
(lambda x: isinstance(x, float), lambda x: x * 2),
lambda x: "goodbye",
)
branch.invoke("hello")
'HELLO'
7、RunnableWithFallbacks
在前面的runnable出现异常时就会执行runnablewithfallbacks,通过调用runnable组件的
with_fallbacks方法,就可以得到一个runnablewithfallbacks的实例。
from langchain_openai import ChatOpenAI
import dotenv
dotenv.load_dotenv()
llm = ChatOpenAI(
model = 'gpt-4o-mini',
)
chain = PromptTemplate.from_template("hello") | llm
# 下面传入列表是因为可以传入多个兜底逻辑
chain_with_fallback = chain.with_fallbacks([RunnableLambda(lambda x:x+"sorry")])
chain_with_fallback.invoke('hello')
'hellosorry'
四、Retrieval
1、RAG介绍
RAG的基本思想为:将传统的生成式大模型和实时信息检索技术相结合,为大模型补充来自外部
的相关数据和上下文,来帮助大模型生成更加准确可靠的内容。

2、RAG流程
索引:从数据源提取数据,构建索引。
索引阶段:从各种数据源加载数据➡️将文档切分为小块➡️对文本块进行嵌入➡️存储嵌入向量。
检索生成:接受用户查询并从索引中检索相关数据,然后将其传递给模型。
检索生成阶段:根据用户输入,使用检索器从存储中检索相关文本块➡️大模型使用包含问题和检
索结果的提示生成回答。
3、加载数据
1、TextLoader
首先要pip install langchain_community
from langchain_community.document_loaders import TextLoader
# 通过textloader创建文件加载器
dataloader = TextLoader(
file_path='assets/sample.txt',
encoding='utf-8',
)
# 调用.load()方法,得到真正的文档对象
loaded_documents = dataloader.load()
print(loaded_documents[0])
print(loaded_documents[0].metadata)
print(loaded_documents[0].page_content)
page_content='LangChain 是一个用于构建基于大语言模型(LLM)应用的开发框架,旨在帮助开发者更高效地集成、管理和增强大语言模型的能力,构建端到端的应用程序。它提供了一套模块化工具和接口,支持从简单的文本生成到复杂的多步骤推理任务。' metadata={'source': 'assets/sample.txt'}
{'source': 'assets/sample.txt'}
LangChain 是一个用于构建基于大语言模型(LLM)应用的开发框架,旨在帮助开发者更高效地集成、管理和增强大语言模型的能力,构建端到端的应用程序。它提供了一套模块化工具和接口,支持从简单的文本生成到复杂的多步骤推理任务。
2、CSVLoader和JSONLoader
CSV文件:
from langchain_community.document_loaders import CSVLoader
csv_loader = CSVLoader(
file_path='assets/sample.csv',
metadata_columns=['title'], # 控制把CSV中的哪一列的数据,也存到Document当中的元素信息里面
content_columns=['content'],
)
loaded_csv = csv_loader.load()
print(loaded_csv[0].metadata)
print(loaded_csv[0].page_content)
{'source': 'assets/sample.csv', 'row': 0, 'title': 'Introduction to Python'}
content: Python is a popular programming language.
JSON文件:
jq_schema是提取json当中对象的一种特定方式,特定的语法。例如:'.' 就是提取整个json对象。
from langchain_community.document_loaders import JSONLoader
json_loader = JSONLoader(
file_path='assets/sample.json',
jq_schema='.data.items[].content',
text_content = False, # 是否是文本
)
loaded_json = json_loader.load()
print(len(loaded_json))
print(loaded_json[0].page_content)
3
This article explains how to parse API responses...
3、加载HTML网页
一个网页组成的元素:html(组成整个网页的布局),css(样式文件),javascript(动态去调用
后端接口获取数据)。
pip install langchain_community beautifulsoup4,bs4是用来解析前端网页的。
import bs4
from langchain_community.document_loaders import WebBaseLoader
document_loader = WebBaseLoader(
#网址序列
web_paths=("https://cn.bing.com",),)
#传给BeautifulSoup的解析参数,parse_only表示只提取指定标签的元素
# bs_kwargs={"parse_only": bs4.SoupStrainer(class_="J-lemma-content")},)
res = document_loader.load()
res[0].page_content
'Search - Microsoft Bing© 2026 Microsoft增值电信业务经营许可证:合字B2-20090007京ICP备10036305号-7京公网安备11010802047360号Privacy and CookiesLegalAdvertiseAbout our adsHelpFeedback'
4、加载MarkDown文件
pip install langchain_community unstructured[md]
传入mode = 'elements'可以按照markdown的标准格式去进行加载。
from langchain_community.document_loaders import UnstructuredMarkdownLoader
markdown_loader = UnstructuredMarkdownLoader(
file_path='assets/sample.md',
mode = 'elements'
)
res = markdown_loader.load()
print(res)
5、加载Docx文件
unstructured加载方式和现在使用的加载方式的区别是,前者结构化解析,适合搭配RAG
# from langchain_community.document_loaders import UnstructuredWordDocumentLoader
# doc_loader = UnstructuredWordDocumentLoader(
# file_path='assets/sample.docx',
# mode = 'single'
# )
# loaded_doc = doc_loader.load()
from langchain_community.document_loaders import Docx2txtLoader
# 加载 docx 文档(和你原来用法完全一样)
loader = Docx2txtLoader("assets/sample.docx")
loaded_doc = loader.load()
print(loaded_doc)
6、加载PDF文件

from langchain_community.document_loaders import PyPDFLoader
pdf_loader = PyPDFLoader(
file_path='assets/sample.pdf',
)
loaded_pdf = pdf_loader.load()
print(loaded_pdf)
2)UnstructuredPDFLoader


4、文档切分
将 Document 切分为 Chunk,主要是为了避免将整个 Document 输入大模型带来的问题:一是无
关内容会干扰生成效果,二是大模型对长上下文中间位置的信息利用能力较弱,三是超长文本可能
被截断导致信息丢失。以 Chunk 为单位进行存储和检索,有助于提升检索精度和模型回答质量。
1、切分策略
-
固定长度切分:按固定字符或Token数切分,实现简单,但可能切断句子。
-
递归分隔符切分:按多个分隔符递归切分,在长度限制内保持句子完整。
-
语义切分:基于句子嵌入向量的相似度识别语义边界(如用余弦距离与阈值比较),切分后合并过短的片段。语义保持好,但速度较慢,块长度不均。
2、 RecursiveCharacterTextSplitter
from langchain_text_splitters import RecursiveCharacterTextSplitter
from langchain_community.document_loaders import UnstructuredWordDocumentLoader
docs = UnstructuredWordDocumentLoader(
file_path='assets/sample.docx',
model = 'single'
).load()
text_spliter = RecursiveCharacterTextSplitter(
separators=['\n\n','\n','。'],
chunk_size=400,#每个块的最大长度
chunk_overlap=50,#每个块重叠的长度
length_function=len,#可选:计算文本长度的函数,默认为字符串长度,可自定义函数来实现按token数切分
add_start_index=True,#可选:块的元数据中添加此块起始索引
)
splitted_res = text_spliter.split_documents(docs)
splitted_res
5、文档嵌入embedding
Sentence-BERT改进了BERT的架构与预训练方式,生成富含语义的句子嵌入,可通过余弦相似度
等指标轻松比较,显著降低了相似句子查找等任务的计算成本。
(1)获取嵌入模型
开源模型:引入HuggingFaceEmbeddings包,传入所使用的模型名称
OpenAI闭源嵌入:引入OpenAIEmbedding类,传入OpenAI的嵌入模型名字,需要注意加载环境
变量。
(2)对文档进行嵌入
调用model.embed_documents()传入由document所构建的列表
import os
from langchain_huggingface import HuggingFaceEmbeddings
#加载嵌入模型
embed_model = HuggingFaceEmbeddings(
model_name=os.path.expanduser(r"C:\Users\77485\.cache\huggingface\hub\bge-base-zh-v1.5")
)
#单文本嵌入
query = "你好,世界"
print(embed_model.embed_query(query))
#多文本嵌入
docs = ["你好,世界", "你好,世界"]
print(embed_model.embed_documents(docs))
6、向量存储
得到了嵌入向量,如何将嵌入向量存储到数据库当中,继而能够进行查询,做语义搜索。
有哪些向量数据库可以供选择?

1、Milvus
(1)在Milvus构建一个Collection(类似于在MySQL中的表)
day3 9
(2)定义这个Collection的schema信息
(3)定义构建索引的逻辑,索引是加速数据查询的一种方式
(4)通过embedding model获取到的向量存储到collection当中
(5)在做语义检索时,通过milvus内置的检索算法,可以检索到相关的向量及其他内容。
DAMO开发者矩阵,由阿里巴巴达摩院和中国互联网协会联合发起,致力于探讨最前沿的技术趋势与应用成果,搭建高质量的交流与分享平台,推动技术创新与产业应用链接,围绕“人工智能与新型计算”构建开放共享的开发者生态。
更多推荐

所有评论(0)