LangChain:4.LangChain 能力详解

LangChain核心能力与快速入门

LangChain 能力详解

一.本章节环境说明

  1. Python 3.13

  2. 本章节使用到的 LangChain 相关包:第一部分

    requirements.txt 如下所示:

    langchain-openai==0.3.33
    langchain==0.3.27
    langchain-deepseek==0.1.4
    langchain-ollama==0.3.6
    langchain-tavily==0.2.12
    langchain-chroma==0.2.5
    langchain-community==0.3.22
    nltk==3.9.2
    langchain-redis==0.2.4
    unstructured==0.18.15
    markdown==3.9
    redisvl==0.10.0
    

    安装命令: pip install -r requirements.txt

  3. 本章节使用到的 LangChain 相关包:第二部分

    pinecone==7.3.0
    langchain-pinecone==0.2.12
    

    注意:

    • 这部分需要学习到【三、核心组件-7.3.4 Pinecone 向量存储】后才可安装。原因是安装langchain-pinecone 时,会同时安装依赖包simsimd 。安装此包后,会导致【三、核心组件-7.3.3 Redis 向量存储】的 MMR 搜索不可用。该问题目前官方尚未解决。
    • 若安装langchain-pinecone 高版本,如0.2.3 (支持 Python 3.13),可能会无法成功。原因是其依赖包numpy 要求numpy<2.0.0,>=1.26.4 ,而该范围的numpy 不支持 Python3.13。该问题目前官方尚未解决。

二.快速上手

1. 内容与目标

对于 LangChain,它是一个用于开发 由大语言模型 (LLM) 驱动的应用程序的框架。

通过前几个章节,我们已经说明尽管大模型的在某些方面表现振奋人心,但使用原生 LLM 可能会存在一些问题,例如将其当作搜索引擎去使用,LLM 生成的答案可能要比其他搜索引擎查到的答案更符合你的预期,但要是在复杂的场景下使用,如将 LLM 嵌入应用程序时却遭遇了全新难题:

  • 简单提示词(Prompt)得到的答案经常出现幻觉?
  • 提示词结构是否可以统一规范?
  • 如何实现开发过程中大模型的轻松、灵活切换?
  • 大模型输出是非结构化的,怎样与要求结构化数据的程序接口交互?
  • 如何克服预训练模型知识陈旧的问题,引入实时更新?
  • 如何连接模型与外部工具或系统,执行具体任务?

LangChain 框架的核心目标就是应对这些挑战。它通过将自然语言处理流程拆解为标准化组件,让开发者能够自由组合并高效定制工作流。

本节目标:

本节主要演示如何使用 LangChain 接入大模型组件,以及与大模型进行简单对话的能力。

掌握了基本用法后,将会引出 LangChain 相关前置概念,以便后续深入学习 LangChain 标准化组件。

2. 详细过程

(1).步骤1:申请 API key 并配置环境变量
①.申请 API key

以 OpenAI为例,官网地址:https://platform.openai.com/(魔法上网)

1_大模型介绍.md中已经讲解不再赘述

②.配置环境变量

将 API Key 配置在环境变量中主要是为了保证其隐私性。由于 api key 比较隐私,为避免在程序中暴露,可提前将各个 api key 配置在环境变量中,这样在程序中就可以通过获取对应环境变量拿到 api key,保证了 api key 的隐私。

image-20251113161524438

(2).步骤2:定义大模型
①.安装 OpenAI 包
pip install -U langchain-openai
②.定义大模型

核心代码:

# 定义大模型
from langchain_openai import ChatOpenAI
model = ChatOpenAI(model="gpt-5-mini")
(3).步骤3:定义消息列表

核心代码:

# 定义消息列表
from langchain_core.messages import HumanMessage, SystemMessage
messages = [
    SystemMessage(content="Translate the following from English into Chinese"),
    HumanMessage(content="hi!"),
]

参数说明:

  • SystemMessage :表示 系统角色 消息,系统消息通常作为输入消息序列中的第一条传入,是用来启动 AI 行为的消息。
  • HumanMessage :表示 用户角色 消息,是来自用户的、从用户传递到模型的消息。
(4).步骤4:调用大模型

model 是 LangChain Runnable (可运行)接口的实例,这意味着model 提供了一个标准接口供我们与之交互。要简单地调用模型,我们可以将消息列表传递给.invoke 方法。

使用 .invoke 方法进行大模型调用,核心代码:

result = model.invoke(messages)
print(result)

输出结果(调试可以看见 result 类型为 AIMessage):

content='你好!' additional_kwargs={'refusal': None} response_metadata=
{'token_usage': {'completion_tokens': 2, 'prompt_tokens': 20, 'total_tokens':
22, '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_name': 'gpt-5-mini-2024-07-18', 'system_fingerprint': 'fp_560af6e559',
'id': 'chatcmpl-C5l29mi6KkQSFO3qaElDJD5Lj9nBn', 'service_tier': 'default',
'finish_reason': 'stop', 'logprobs': None} id='run--777ef0be-55c2-411a-a4ab-
104a45c22f20-0' usage_metadata={'input_tokens': 20, 'output_tokens': 2,
'total_tokens': 22, 'input_token_details': {'audio': 0, 'cache_read': 0},
'output_token_details': {'audio': 0, 'reasoning': 0}}

输出说明:

  • AIMessage :来自 AI 的消息。从聊天模型返回,作为对提示(输入)的响应。

    • content :消息的内容。

    • additional_kwargs :与消息关联的其他有效负载数据。对于来自 AI 的消息,可能包括模型提供程序编码的工具调用。

    • response_metadata :响应元数据。例如:响应标头、logprobs、令牌计数、模型名称。

      image-20251113162434770

      • 侧重于 “响应”本身的信息,比如这次请求的 ID、使用的模型版本、以及服务提供商返回的所有原始元数据。它主要用于调试、日志记录和获取请求的上下文信息。
    • usage_metadata :消息的使用元数据,例如令牌计数。

      image-20251113162448007

      • 侧重于 “资源消耗”的量化信息,即这次请求消耗了多少 Token。它主要用于成本计算、监控和预算控制。
(5).步骤5:输出解析

若只想输出聊天模型返回的结果字符串,可以使用 StrOutputParser 输出解析器组件,将大模型输出结果解析为最可能的字符串。核心代码:

# 定义str字符串输出解析器
from langchain_core.output_parsers import StrOutputParser
parser = StrOutputParser()
print(parser.invoke(result))

输出结果:

你好!
(6).步骤6:链式执行

通过上述步骤,无论是调用大模型,还是输出解析,我们发现,每次都调用了一个 invoke() 方法,最终才会得到我们想要的结果。

对于 LangChain,它给我们提供了链式执行的能力,即我们只需要定义各个“组件”,将它们“链起来”,一次性执行即可得到最终效果。

注意:以上描述只是为了好理解,并不是其真正定义。等到示例看完,我们会引出最终定义。

核心代码如下:

# 定义大模型
model = ChatOpenAI(model="gpt-5-mini")
# 定义消息列表
messages = [
    SystemMessage(content="Translate the following from English into Chinese"),
    HumanMessage(content="hi!"),
]
# 定义输出解析器
parser = StrOutputParser()
# 定义链
chain = model | parser
# 执行链
result = chain.invoke(messages)
print(result)

输出结果:

你好!
(7).完整代码
from langchain_openai import ChatOpenAI
from langchain_core.messages import HumanMessage, SystemMessage
from langchain_core.output_parsers import StrOutputParser

# 定义大模型
model = ChatOpenAI(model="gpt-5-mini")

# 定义消息列表
messages = [
    SystemMessage(content="Translate the following from English into Chinese"),
    HumanMessage(content="hi!"),
]

# 定义输出解析器
parser = StrOutputParser()

# 定义链
# 法一(推荐):
chain = model | parser
# 法二:
# chain = RunnableSequence(first=model,last= parser)
# 法三:
# chain = model.pipe(parser)

# 执行链
result = chain.invoke(messages)
print(result)

3.引出 LangChain 相关概念

(1).Runnable 接口

Runnable 接口是使用 LangChain Components(组件)的基础。

概念说明:

Components(组件):用来帮助当我们在构建应用程序时,提供了一系列的核心构建块,例如语言模型、输出解析器、检索器、编译的 LangGraph 图等。

Runnable 定义了一个标准接口,允许 Runnable 组件:

  • Invoked(调用): 单个输入转换为输出。
  • Batched(批处理): 多个输入被有效地转换为输出。
  • Streamed(流式传输): 输出在生成时进行流式传输。
  • Inspected(检查):可以访问有关Runnable的输入、输出和配置的原理图信息。

所有能力参考这里

**因此,在快速上手中,我们定义的语言模型(model)、输出解析器(StrOutputParser)都是Runnable 接口的实例!**他们都使用了 Invoked(调用)的能力,回顾一下:

# 语言模型(model)
model = ChatOpenAI(model="gpt-5-mini")
result = model.invoke(messages) 	# 语言模型是 Runnable 接口实例,允许invoke调用
    
# 输出解析器(StrOutputParser)
parser = StrOutputParser()
parser.invoke(result) 				# 输出解析器是 Runnable 接口实例,允许invoke调用
(2).LangChain Expression Language

LangChain Expression Language(LCEL):采用声明性方法,从现有 Runnable 对象构建新的Runnable 对象。我们定义好的一堆组件都是Runnabe实例,把它们串起来定义成链也是Runnabe实例.

通过 LCEL 构建出的新的 Runnable 对象,被称为RunnableSequence ,表示可运行序列。

RunnableSequence 就是一种链(参考步骤6)。通过调试步骤6 就能发现,chain 的类型就是 RunnableSequence 。如下所示:

image-20251115185556531

重要的是, RunnableSequence 也是 Runnable 接口的实例 ,它实现了完整的 Runnable 接口,因此它可以用与任何其他 Runnable 相同的姿势使用。

回顾一下:

chain = model | parser
chain.invoke(messages) # 链是 Runnable 接口实例,允许invoke调用
①.|

可以看到,LCEL 其实是一种编排解决方案,它使 LangChain 能够以优化的方式处理链的运行时执行。任何两个 Runnable 实例都可以“链”在一起成序列。上一个可运行对象的 .invoke() 调用的输出作为输入传递给下一个可运行对象。方法就是使用 | (管道/运算符):

chain = model | parser
②.RunnableSequence

它通过两个 Runnable 对象去创建一个RunnableSequence 。实际上 LangChain 重载了| 运算符,使用 | 运算符就相当于:

from langchain_core.runnables import RunnableSequence
chain = RunnableSequence(first=model, last=parser)
③.pipe()

除此之外,可以使用 .pipe 方法代替。这也相当于 | 运算符:

在 Unix/Linux 系统中, pipe() 系统调用和 | 管道操作符都用于实现进程间通信,这里同样也是迁移过来的用法。

chain = model.pipe(parser)
<think> 我们正在讨论LangChain的BaseTool.invoke()方法。BaseTool是LangChain中所有工具的基类,invoke()方法用于同步调用工具。 用法:通常,我们通过传入一个字典(包含工具所需的参数)来调用工具,工具会执行并返回结果。 基本语法:`tool.invoke(input: Union[str, Dict], config: Optional[RunnableConfig] = None) -> Any` 其中: - input:可以是字符串(如果工具只接受单个字符串参数)或字典(键为参数名,值为参数值)。 - config:可选配置,如回调函数等。 示例: ```python from langchain.tools import BaseTool class CalculatorTool(BaseTool): name = "calculator" description = "Used for performing basic arithmetic calculations" args_schema = ... # 定义参数模式 def _run(self, a: float, b: float, operator: str) -> float: if operator == '+': return a + b elif operator == '-': return a - b # 其他操作符 # 使用工具 tool = CalculatorTool() result = tool.invoke({"a": 5, "b": 3, "operator": "+"}) print(result) # 输出8.0 ``` 注意:如果工具定义时指定了单个字符串参数,则可以直接传入字符串,否则必须传入字典。 另外,BaseTool也实现了Runnable接口,因此也可以像其他Runnable一样使用invoke方法。 错误处理:如果输入参数不匹配,会抛出异常。 因此,invoke方法提供了同步调用工具执行任务的能力。 </think>### LangChain `BaseTool.invoke()` 方法详解 `BaseTool.invoke()` 是 LangChain 工具调用框架的核心方法,用于**同步执行工具功能**。以下是关键用法说明: #### 基本用法 ```python from langchain.tools import BaseTool # 定义自定义工具 class MyTool(BaseTool): name = "my_tool" description = "工具描述" def _run(self, arg1: str, arg2: int) -> str: """工具执行逻辑""" return f"结果: {arg1}-{arg2}" # 实例化工具 tool = MyTool() # 调用工具 result = tool.invoke( input={"arg1": "value", "arg2": 42}, # 参数必须与_run定义匹配 config={"callbacks": [...]} # 可选配置 ) print(result) # 输出: "结果: value-42" ``` #### 核心特性 1. **输入格式** - 必须为字典 `Dict[str, Any]` - 键名需与 `_run()` 方法参数名完全匹配 - 支持通过 `args_schema` 定义参数验证规则 2. **配置参数** ```python config = { "callbacks": [handler], # 回调处理器 "tags": ["debug"], # 执行标签 "metadata": {"key": "value"} # 元数据 } ``` 3. **错误处理** - 参数不匹配:抛出 `ValueError` - 执行异常:抛出工具自定义异常 - 可通过 `try-except` 捕获: ```python try: tool.invoke(bad_input) except (ValueError, ToolException) as e: print(f"错误: {e}") ``` 4. **返回值** - 直接返回 `_run()` 方法的执行结果 - 支持任意可序列化类型(str/dict/list等) #### 高级用法 **结合 Agent 使用** ```python from langchain.agents import AgentExecutor, create_tool_calling_agent agent = create_tool_calling_agent(llm, [tool], prompt) agent_executor = AgentExecutor(agent=agent, tools=[tool]) # 自动触发工具调用 result = agent_executor.invoke({"input": "使用工具查询..."}) ```
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值