欢迎光临
我们一直在努力

LangChain入门:从 Runnable 协议到完整生态

LangChain入门:从 Runnable 协议到完整生态

标签: LangChain, 源码分析, Python, 架构设计, LLM

深入分析 LangChain 核心源码,从 Runnable 协议开始,逐步解析语言模型、工具系统、提示词模板、回调系统、记忆系统和检索器的内部实现机制

LangChain 核心源码导读


概述

本文档深入分析 LangChain 的核心源码,帮助初学者理解框架的内部实现机制。我们将从最基础的 Runnable 接口开始,逐步深入到各个核心模块。

源码结构导航

libs/
├── core/langchain_core/ # 核心抽象层
│ ├── runnables/ # ★ 核心:Runnable 协议
│ ├── language_models/ # 语言模型抽象
│ ├── messages/ # 消息类型
│ ├── tools/ # 工具抽象
│ ├── prompts/ # 提示词模板
│ ├── retrievers/ # 检索器抽象
│ ├── embeddings/ # 嵌入抽象
│ └── callbacks/ # 回调系统

├── langchain/langchain/ # 主实现
│ ├── chains/ # 链实现
│ ├── agents/ # 代理实现
│ ├── tools/ # 工具实现
│ ├── memory/ # 记忆管理
│ └── document_loaders/ # 文档加载器

└── community/ # 社区集成
└── langchain_community/
├── chat_models/ # 聊天模型
├── embeddings/ # 嵌入模型
├── vectorstores/ # 向量存储
└── tools/ # 社区工具

1. Runnable 协议 – 核心抽象

1.1 基础接口定义

文件: libs/core/langchain_core/runnables/base.py

from abc import ABC, abstractmethod
from typing import Generic, TypeVar, Optional, Any

# 定义输入和输出的类型变量
Input = TypeVar("Input")
Output = TypeVar("Output")

class Runnable(Generic[Input, Output], ABC):
"""
LangChain 的核心抽象接口

所有组件都实现这个接口,提供统一的执行方式:
– invoke: 同步执行
– batch: 批量执行
– stream: 流式输出
"""

# ========== 核心同步方法 ==========

@abstractmethod
def invoke(
self,
input: Input,
config: Optional["RunnableConfig"] = None,
**kwargs: Any,
) > Output:
"""同步执行:将输入转换为输出"""
raise NotImplementedError()

def batch(
self,
inputs: list[Input],
config: Optional["RunnableConfig"] = None,
**kwargs: Any,
) > list[Output]:
"""
批量执行:处理多个输入

默认实现:使用线程池并行调用 invoke
子类可以重写以优化批量处理
"""
# 获取配置中的并发限制
config = config or {}
max_concurrency = kwargs.get("max_concurrency")

# 使用线程池并行执行
from concurrent.futures import ThreadPoolExecutor

with ThreadPoolExecutor() as executor:
futures = [
executor.submit(self.invoke, inp, config)
for inp in inputs
]
return [f.result() for f in futures]

def stream(
self,
input: Input,
config: Optional["RunnableConfig"] = None,
**kwargs: Any,
) > Iterator[Output]:
"""
流式输出:逐步产生结果

默认实现:调用 invoke 并产生单个结果
子类应该重写以支持真正的流式输出
"""
yield self.invoke(input, config, **kwargs)

# ========== 核心异步方法 ==========

async def ainvoke(
self,
input: Input,
config: Optional["RunnableConfig"] = None,
**kwargs: Any,
) > Output:
"""
异步执行

默认实现:在线程池中运行 invoke
子类应该重写以提供原生异步实现
"""
from asyncio import get_event_loop
return await get_event_loop().run_in_executor(
None, functools.partial(self.invoke, input, config, **kwargs)
)

async def abatch(
self,
inputs: list[Input],
config: Optional["RunnableConfig"] = None,
**kwargs: Any,
) > list[Output]:
"""异步批量执行"""
import asyncio

# 并行执行所有异步调用
coros = [self.ainvoke(inp, config, **kwargs) for inp in inputs]
return await asyncio.gather(*coros)

async def astream(
self,
input: Input,
config: Optional["RunnableConfig"] = None,
**kwargs: Any,
) > AsyncIterator[Output]:
"""异步流式输出"""
result = await self.ainvoke(input, config, **kwargs)
yield result

# ========== 组合操作 ==========

def __or__(
self,
other: "Runnable[Any, Output]",
) > "RunnableSequence[Input, Any]":
"""
实现 | 操作符:创建顺序链

这是 LCEL (LangChain Expression Language) 的核心
"""
from langchain_core.runnables.base import RunnableSequence
return RunnableSequence([self, other])

def __ror__(
self,
other: "Runnable[Input, Any]",
) > "RunnableSequence[Input, Output]":
"""反向 | 操作符"""
from langchain_core.runnables.base import RunnableSequence
return RunnableSequence([other, self])

1.2 RunnableSequence – 顺序链

文件: libs/core/langchain_core/runnables/base.py

class RunnableSequence(RunnableSerializable[Input, Output]):
"""
顺序执行的链:LCEL | 操作符的核心实现

当使用 | 操作符时,实际创建的就是 RunnableSequence
"""

steps: Sequence[Runnable[Any, Any]]
"""要按顺序执行的 Runnable 列表"""

def invoke(
self,
input: Input,
config: Optional[RunnableConfig] = None,
**kwargs: Any,
) > Output:
"""
顺序执行所有步骤

执行流程:
1. 将输入传递给第一个步骤
2. 每个步骤的输出成为下一个步骤的输入
3. 返回最后一个步骤的输出
"""
value: Any = input

# 依次执行每个步骤
for i, step in enumerate(self.steps):
try:
# 将当前值传递给步骤
value = step.invoke(value, config, **kwargs)
except Exception as e:
# 添加上下文信息以便调试
raise RuntimeError(
f"Error in step {i} ({step.get_name()}): {str(e)}"
) from e

return value

async def ainvoke(
self,
input: Input,
config: Optional[RunnableConfig] = None,
**kwargs: Any,
) > Output:
"""异步版本"""
value: Any = input

for i, step in enumerate(self.steps):
try:
value = await step.ainvoke(value, config, **kwargs)
except Exception as e:
raise RuntimeError(
f"Error in async step {i} ({step.get_name()}): {str(e)}"
) from e

return value

def stream(
self,
input: Input,
config: Optional[RunnableConfig] = None,
**kwargs: Any,
) > Iterator[Output]:
"""
流式执行

关键点:最后一个步骤可以流式输出时,
整个链就可以流式输出
"""
value: Any = input

# 前面的步骤正常执行
for i, step in enumerate(self.steps[:1]):
value = step.invoke(value, config, **kwargs)

# 最后一个步骤流式输出
for chunk in self.steps[1].stream(value, config, **kwargs):
yield chunk

使用示例:

# 这段代码创建了一个 RunnableSequence
chain = prompt | llm | parser

# 等价于:
chain = RunnableSequence([prompt, llm, parser])

# 执行时的数据流:
# input -> prompt.format() -> llm.invoke() -> parser.parse() -> output

1.3 RunnableParallel – 并行执行

文件: libs/core/langchain_core/runnables/base.py

class RunnableParallel(RunnableSerializable[Input, dict[str, Any]]):
"""
并行执行多个 Runnable

可以使用字典字面量语法创建:
chain = {
"summary": summary_chain,
"analysis": analysis_chain,
}
"""

steps: Mapping[str, Runnable[Any, Any]]
"""要并行执行的 Runnable 映射"""

def invoke(
self,
input: Input,
config: Optional[RunnableConfig] = None,
**kwargs: Any,
) > dict[str, Any]:
"""
并行执行所有步骤

执行流程:
1. 将相同输入传递给所有步骤
2. 并行执行所有步骤
3. 将结果合并到字典中返回
"""
import asyncio

# 创建异步任务
async def _parallel_invoke():
results = {}
tasks = []

# 为每个步骤创建异步任务
for key, step in self.steps.items():
async def invoke_step(k=key, s=step):
result = await s.ainvoke(input, config, **kwargs)
return k, result

tasks.append(invoke_step())

# 等待所有任务完成
completed = await asyncio.gather(*tasks)
return {k: v for k, v in completed}

# 在同步上下文中运行异步代码
return asyncio.run(_parallel_invoke())

1.4 RunnableLambda – 函数适配器

文件: libs/core/langchain_core/runnables/base.py

class RunnableLambda(Runnable[Input, Output]):
"""
将普通函数转换为 Runnable

这使得任何函数都可以在 LCEL 链中使用
"""

func: Union[
Callable[[Input], Output], # 同步函数
Callable[[Input], Awaitable[Output]], # 异步函数
]
"""要包装的函数"""

def invoke(
self,
input: Input,
config: Optional[RunnableConfig] = None,
**kwargs: Any,
) > Output:
"""调用包装的函数"""
return self.func(input)

async def ainvoke(
self,
input: Input,
config: Optional[RunnableConfig] = None,
**kwargs: Any,
) > Output:
"""异步调用包装的函数"""
result = self.func(input)

# 如果结果是可等待对象,等待它
if inspect.isawaitable(result):
return await result

return result

使用示例:

# 将普通函数转换为 Runnable
def extract_title(text: str) > str:
"""提取文本的第一行作为标题"""
return text.split('\\n')[0]

# 现在可以在链中使用
chain = (
RunnableLambda(extract_title)
| another_runnable
)

1.5 RunnablePassthrough – 透传

文件: libs/core/langchain_core/runnables/passthrough.py

class RunnablePassthrough(RunnableSerializable[Other, Other]):
"""
透传输入:将输入原样传递,不进行任何修改

常用于 RunnableParallel 中,需要同时传递输入和使用处理后的结果
"""

def invoke(
self,
input: Other,
config: Optional[RunnableConfig] = None,
) > Other:
"""直接返回输入"""
return input

使用示例:

from langchain_core.runnables import RunnablePassthrough

# 在并行链中同时保留原始输入
chain = {
"original": RunnablePassthrough(), # 保留原始输入
"processed": some_processor, # 处理后的结果
"count": lambda x: len(x), # 计数
}

2. 语言模型抽象

2.1 BaseLanguageModel

文件: libs/core/langchain_core/language_models/base.py

class BaseLanguageModel(
RunnableSerializable[LanguageModelInput, LanguageModelOutputVar], ABC
):
"""
所有语言模型的抽象基类

提供了生成文本的核心接口,所有具体的 LLM 实现都继承此类
"""

# 配置字段
cache: Union[BaseCache, bool, None] = Field(default=None, exclude=True)
"""响应缓存"""

verbose: bool = Field(default_factory=_get_verbosity, exclude=True)
"""是否打印输出"""

callbacks: Callbacks = Field(default=None, exclude=True)
"""回调处理器"""

tags: Optional[list[str]] = Field(default=None, exclude=True)
"""用于追踪的标签"""

metadata: Optional[dict[str, Any]] = Field(default=None, exclude=True)
"""元数据"""

@abstractmethod
def generate_prompt(
self,
prompts: list[PromptValue],
stop: list[str] | None = None,
**kwargs: Any,
) > LLMResult:
"""
从提示生成文本

这是核心抽象方法,子类必须实现
"""
raise NotImplementedError()

def invoke(
self,
input: LanguageModelInput,
config: Optional[RunnableConfig] = None,
**kwargs: Any,
) > LanguageModelOutputVar:
"""
Runnable 接口的实现

将输入转换为 PromptValue,然后调用 generate_prompt
"""
# 转换输入为 PromptValue
if isinstance(input, str):
prompt_value = StringPromptValue(text=input)
elif isinstance(input, PromptValue):
prompt_value = input
else:
# 消息列表
prompt_value = ChatPromptValue(messages=input)

# 调用 generate_prompt
llm_result = self.generate_prompt(
[prompt_value],
**kwargs
)

# 提取结果
return llm_result.generations[0][0].text

2.2 ChatModel – 聊天模型

文件: libs/core/langchain_core/language_models/chat_models.py

class BaseChatModel(BaseLanguageModel[BaseMessage], ABC):
"""
聊天模型的抽象基类

处理消息列表而不是纯文本
"""

@abstractmethod
def _generate(
self,
messages: list[BaseMessage],
stop: list[str] | None = None,
run_manager: CallbackManagerForLLMRun | None = None,
**kwargs: Any,
) > ChatResult:
"""
生成聊天响应

子类必须实现此方法
"""
raise NotImplementedError()

def bind_tools(
self,
tools: Sequence[BaseTool | StructuredTool],
**kwargs: Any,
) > "RunnableBinding":
"""
绑定工具到模型

这使得模型可以调用工具
"""
# 将工具转换为模型特定的格式
formatted_tools = [self._format_tool(tool) for tool in tools]

# 创建绑定
return RunnableBinding(
bound=self,
kwargs={**kwargs, "tools": formatted_tools}
)

3. 工具系统

3.1 BaseTool

文件: libs/core/langchain_core/tools/base.py

class BaseTool(RunnableSerializable[Union[str, dict], Any], ABC):
"""
工具的抽象基类

工具是可以被 LLM 调用的函数,用于执行特定任务
"""

# 工具元数据
name: str
"""工具名称,在提示词中使用"""

description: str
"""工具描述,告诉 LLM 何时使用此工具"""

args_schema: Type[BaseModel] = Field(default=...)
"""参数的 Pydantic 模式,用于验证和文档"""

# ========== 核心方法 ==========

@abstractmethod
def _run(
self,
*args: Any,
**kwargs: Any,
) > Any:
"""
同步执行工具

子类必须实现此方法
"""
raise NotImplementedError()

async def _arun(
self,
*args: Any,
**kwargs: Any,
) > Any:
"""
异步执行工具

默认实现调用 _run
子类可以重写以提供原生异步实现
"""
return await asyncio.get_event_loop().run_in_executor(
None, functools.partial(self._run, *args, **kwargs)
)

# ========== Runnable 接口实现 ==========

def invoke(
self,
input: Union[str, dict],
config: Optional[RunnableConfig] = None,
**kwargs: Any,
) > Any:
"""
Runnable 接口实现

解析输入并执行工具
"""
# 解析输入
if isinstance(input, str):
parsed_input = {"query": input}
elif isinstance(input, dict):
parsed_input = input
else:
parsed_input = self.args_schema.model_validate(input)

# 执行工具
return self._run(**parsed_input.model_dump())

# ========== 工具特定方法 ==========

def to_tool_call(
self,
arguments: dict[str, Any],
) > ToolCall:
"""创建工具调用记录"""
return ToolCall(
name=self.name,
args=arguments,
id=str(uuid.uuid4()),
)

3.2 StructuredTool – 结构化工具

文件: libs/core/langchain_core/tools/structured.py

class StructuredTool(BaseTool):
"""
带有结构化输入/输出的工具

允许为工具的输入和输出定义严格的模式
"""

args_schema: Type[BaseModel] = Field(default=...)
"""输入模式"""

response_format: "Type[BaseModel]" = Field(default=None)
"""输出模式(可选)"""

func: Callable[..., Any]
"""要包装的函数"""

def _run(
self,
*args: Any,
**kwargs: Any,
) > Any:
"""调用包装的函数"""
return self.func(*args, **kwargs)

@classmethod
def from_function(
cls,
func: Callable,
name: str,
description: str,
args_schema: Optional[Type[BaseModel]] = None,
) > "StructuredTool":
"""
从函数创建工具

这是创建自定义工具的便捷方法
"""
# 如果没有提供模式,从函数签名推断
if args_schema is None:
args_schema = cls._infer_schema(func)

return cls(
name=name,
description=description,
args_schema=args_schema,
func=func,
)

创建自定义工具示例:

from langchain_core.tools import StructuredTool
from pydantic import BaseModel

class SearchInput(BaseModel):
"""搜索输入模式"""
query: str
limit: int = 10

def search_func(query: str, limit: int = 10) > str:
"""执行搜索"""
return f"Searching for: {query}"

# 创建工具
search_tool = StructuredTool.from_function(
func=search_func,
name="search",
description="搜索互联网",
args_schema=SearchInput,
)

4. 提示词模板

4.1 BasePromptTemplate

文件: libs/core/langchain_core/prompts/base.py

class BasePromptTemplate(Serializable, ABC):
"""
提示词模板的抽象基类

定义了模板的接口和基本行为
"""

template: str
"""模板字符串"""

input_variables: list[str]
"""模板中使用的变量名"""

template_format: str = "f-string"
"""模板格式:f-string, jinja2, mustache"""

@abstractmethod
def format(self, **kwargs: Any) > str:
"""
格式化模板

使用提供的值替换模板中的变量
"""
raise NotImplementedError()

def invoke(
self,
input: dict[str, Any],
config: Optional[RunnableConfig] = None,
) > PromptValue:
"""Runnable 接口实现"""
return self.format_prompt(**input)

def __or__(
self,
other: Runnable[Any, Other],
) > RunnableSequence[dict[str, Any], Other]:
"""支持 | 操作符"""
return RunnableSequence([self, other])

4.2 ChatPromptTemplate

文件: libs/core/langchain_core/prompts/chat.py

class ChatPromptTemplate(BasePromptTemplate):
"""
聊天提示词模板

由多个消息模板组成
"""

messages: Sequence[MessageLikeRepresentation]
"""消息模板列表"""

@classmethod
def from_template(
cls,
template: str,
**kwargs: Any,
) > "ChatPromptTemplate":
"""
从字符串创建聊天模板

这是创建聊天提示词的便捷方法
"""
return cls(
messages=[
("human", template) # 人类消息
],
**kwargs
)

@classmethod
def from_messages(
cls,
messages: Sequence[MessageLikeRepresentation],
) > "ChatPromptTemplate":
"""
从消息列表创建模板

消息可以是:
– 元组:(角色, 内容)
– MessageTemplate:消息模板对象
– BaseMessage:实际消息
"""
return cls(messages=list(messages))

def format_messages(
self,
**kwargs: Any,
) > list[BaseMessage]:
"""格式化为消息列表"""
formatted_messages = []

for message in self.messages:
if isinstance(message, tuple):
role, content = message
# 格式化内容
formatted_content = content.format(**kwargs)

# 创建对应的消息类型
if role == "system":
formatted_messages.append(SystemMessage(content=formatted_content))
elif role == "human":
formatted_messages.append(HumanMessage(content=formatted_content))
elif role == "ai":
formatted_messages.append(AIMessage(content=formatted_content))
else:
formatted_messages.append(message)

return formatted_messages

5. 回调系统

5.1 BaseCallbackHandler

文件: libs/core/langchain_core/callbacks/base.py

class BaseCallbackHandler(ABC):
"""
回调处理器的抽象基类

定义了可以监听的各种事件
"""

# ========== LLM 事件 ==========

def on_llm_start(
self,
prompts: list[str],
**kwargs: Any,
) > Any:
"""LLM 开始生成"""
pass

def on_llm_end(
self,
response: LLMResult,
**kwargs: Any,
) > Any:
"""LLM 结束生成"""
pass

def on_llm_error(
self,
error: Exception,
**kwargs: Any,
) > Any:
"""LLM 发生错误"""
pass

# ========== 链事件 ==========

def on_chain_start(
self,
serialized: dict,
inputs: dict,
**kwargs: Any,
) > Any:
"""链开始执行"""
pass

def on_chain_end(
self,
outputs: dict,
**kwargs: Any,
) > Any:
"""链结束执行"""
pass

def on_chain_error(
self,
error: Exception,
**kwargs: Any,
) > Any:
"""链发生错误"""
pass

# ========== 工具事件 ==========

def on_tool_start(
self,
serialized: dict,
input_str: str,
**kwargs: Any,
) > Any:
"""工具开始执行"""
pass

def on_tool_end(
self,
output: str,
**kwargs: Any,
) > Any:
"""工具结束执行"""
pass

def on_tool_error(
self,
error: Exception,
**kwargs: Any,
) > Any:
"""工具发生错误"""
pass

5.2 CallbackManager

文件: libs/core/langchain_core/callbacks/manager.py

class CallbackManager:
"""
管理多个回调处理器

当事件发生时,通知所有注册的处理器
"""

handlers: list[BaseCallbackHandler]

def __init__(self, handlers: list[BaseCallbackHandler]):
self.handlers = handlers

def on_llm_start(
self,
prompts: list[str],
**kwargs: Any,
) > None:
"""通知所有处理器:LLM 开始"""
for handler in self.handlers:
try:
handler.on_llm_start(prompts, **kwargs)
except Exception as e:
logger.warning(f"Error in callback handler: {e}")

def on_llm_end(
self,
response: LLMResult,
**kwargs: Any,
) > None:
"""通知所有处理器:LLM 结束"""
for handler in self.handlers:
try:
handler.on_llm_end(response, **kwargs)
except Exception as e:
logger.warning(f"Error in callback handler: {e}")

6. 记忆系统

6.1 BaseMemory

文件: libs/langchain/langchain/memory/base.py

class BaseMemory(Serializable, ABC):
"""
记忆的抽象基类

定义了在对话中保存和检索状态的接口
"""

@property
@abstractmethod
def memory_variables(self) > list[str]:
"""
此记忆组件管理的变量名

例如:["history", "summary"]
"""
pass

@abstractmethod
def load_memory_variables(
self,
inputs: dict[str, Any],
) > dict[str, Any]:
"""
加载记忆变量

返回的字典会被添加到提示词中
"""
pass

@abstractmethod
def save_context(
self,
inputs: dict[str, Any],
outputs: dict[str, Any],
) > None:
"""
保存当前对话上下文到记忆

inputs: 用户的输入
outputs: 模型的输出
"""
pass

def clear(self) > None:
"""清除所有记忆"""
pass

6.2 ConversationBufferMemory

文件: libs/langchain/langchain/memory/buffer.py

class ConversationBufferMemory(BaseMemory):
"""
缓冲对话历史的记忆组件

保存所有对话消息
"""

chat_memory: BaseChatMessageHistory = Field(default_factory=ChatMessageHistory)
"""消息历史存储"""

return_messages: bool = False
"""是否返回消息对象而非字符串"""

@property
def memory_variables(self) > list[str]:
return ["history"]

def load_memory_variables(
self,
inputs: dict[str, Any],
) > dict[str, Any]:
"""加载对话历史"""
if self.return_messages:
return {"history": self.chat_memory.messages}
else:
# 转换为字符串
return {
"history": get_buffer_string(
self.chat_memory.messages,
human_prefix="Human",
ai_prefix="AI",
)
}

def save_context(
self,
inputs: dict[str, Any],
outputs: dict[str, Any],
) > None:
"""保存对话"""
# 保存用户输入
input_str = inputs.get("input", "")
self.chat_memory.add_message(HumanMessage(content=input_str))

# 保存模型输出
output_str = outputs.get("output", "")
self.chat_memory.add_message(AIMessage(content=output_str))

7. 检索器

7.1 BaseRetriever

文件: libs/core/langchain_core/retrievers.py

class BaseRetriever(Runnable[langchain_core.utils.input.Input, list[Document]], ABC):
"""
检索器的抽象基类

检索器用于根据查询找到相关文档
"""

@abstractmethod
def _get_relevant_documents(
self,
query: str,
run_manager: CallbackManagerForChainRun,
) > list[Document]:
"""
获取相关文档

子类必须实现此方法
"""
raise NotImplementedError()

def invoke(
self,
input: str,
config: Optional[RunnableConfig] = None,
) > list[Document]:
"""Runnable 接口实现"""
# 创建运行管理器
run_manager = get_callback_manager_for_config(config)

# 调用子类实现
return self._get_relevant_documents(input, run_manager)

async def ainvoke(
self,
input: str,
config: Optional[RunnableConfig] = None,
) > list[Document]:
"""异步版本"""
run_manager = await get_async_callback_manager_for_config(config)
return await self._aget_relevant_documents(input, run_manager)

7.2 VectorStoreRetriever

文件: libs/langchain/langchain/vectorstores/base.py

class VectorStoreRetriever(BaseRetriever):
"""
基于向量存储的检索器

使用向量相似度搜索查找相关文档
"""

vectorstore: VectorStore
"""底层的向量存储"""

search_type: str = "similarity"
"""搜索类型:similarity, mmr, similarity_score_threshold"""

search_kwargs: dict[str, Any] = Field(default_factory=dict)
"""搜索参数,如 k(返回数量)"""

def _get_relevant_documents(
self,
query: str,
run_manager: CallbackManagerForChainRun,
) > list[Document]:
"""执行向量搜索"""
if self.search_type == "similarity":
# 标准相似度搜索
docs = self.vectorstore.similarity_search(
query,
**self.search_kwargs
)
elif self.search_type == "mmr":
# 最大边际相关性(MMR)搜索
docs = self.vectorstore.max_marginal_relevance_search(
query,
**self.search_kwargs
)
else:
raise ValueError(f"Unknown search type: {self.search_type}")

return docs

8. 数据流追踪

8.1 使用 LangSmith 追踪

LangChain 与 LangSmith 深度集成,可以追踪所有执行:

import os
os.environ["LANGCHAIN_TRACING_V2"] = "true"
os.environ["LANGCHAIN_API_KEY"] = "your-api-key"

# 所有链执行都会被自动追踪
result = chain.invoke({"input": "hello"})

8.2 本地调试

from langchain_core.globals import set_debug
from langchain_core.tracers import ConsoleCallbackHandler

# 启用调试模式
set_debug(True)

# 或使用控制台回调
chain.invoke(
{"input": "hello"},
config={"callbacks": [ConsoleCallbackHandler()]}
)

9. 总结

LangChain 的核心设计理念:

  • 统一抽象: Runnable 协议为所有组件提供统一接口
  • 可组合性: LCEL 使组件可以轻松组合
  • 异步优先: 核心接口支持异步操作
  • 可扩展性: 通过继承和装饰器扩展功能
  • 可观测性: 内置回调和追踪系统
  • 通过理解这些核心源码,你可以:

    • 更好地使用 LangChain
    • 创建自定义组件
    • 调试和优化你的应用
    • 贡献到 LangChain 项目

    赞(0)
    未经允许不得转载:171主机测评 » LangChain入门:从 Runnable 协议到完整生态
    分享到: 更多 (0)

    评论 抢沙发

    • 昵称 (必填)
    • 邮箱 (必填)
    • 网址