Type something to search...
解锁 Langchain:构建强大工作流的 5 个关键 Runnables

解锁 Langchain:构建强大工作流的 5 个关键 Runnables

Runnables:LangChain 的构建基石

Runnable 是 LangChain 中的一个基础接口。

它是一个协议,用于标准化组件(例如 LLM、输出解析器、检索器或提示模板)的定义和执行方式。该接口确保了与各种组件的一致交互,从而促进了复杂工作流程和链的创建。

上一章:

[## LangChain in Chains #49: 批量处理

LangChain 中的批量处理

blog.devgenius.io](https://blog.devgenius.io/langchain-in-chains-49-batch-processing-a36a3cb27d63)

Runnable 本质上是一个抽象,代表一个工作单元。一个 Runnable 必须实现以下方法:

  • invoke:处理单个输入以产生输出。
  • batch:并行处理多个输入。
  • stream:在生成时流式传输输出。
  • ainvoke , abatch , astream:这些是相应 的异步方法。
  • astream_log:流式传输回中间步骤。
  • astream_events:流式传输事件。

我们使用 Runnables 创建组合。我们使用 LCEL 将它们组合起来形成复杂 的管道。

来源

每个 Runnable 都会公开输入和输出模式,从而清晰地了解预期的数据结构,并促进验证和调试。

让我们通过一个简单的例子并分析模式。

import os

os.environ["OPENAI_API_KEY"] = ""
from langchain_openai import ChatOpenAI
from langchain.output_parsers import PydanticOutputParser
from langchain.prompts import PromptTemplate
from pydantic import BaseModel, Field

首先,我们有一个 PromptTemplate

prompt_string = """
Write a movie review in any language for the movie {movie}

Format instructions:
{format_instructions}
"""

prompt_template = PromptTemplate(
    input_variables=["movie", "format_instructions"],
    template=prompt_string
)

通过调用 prompt_template.input_schema.model_json_schema(),我们获得预期输入的 JSON 模式表示:

prompt_template.input_schema.model_json_schema()

"""
{'properties': {'format_instructions': {'title': 'Format Instructions',
   'type': 'string'},
  'movie': {'title': 'Movie', 'type': 'string'}},
 'required': ['format_instructions', 'movie'],
 'title': 'PromptInput',
 'type': 'object'}
"""

此模式表明 format_instructionsmovie 都是必需的字符串属性。

通过调用 prompt_template.output_schema.model_json_schema(),我们检索预期输出的 JSON 模式表示。

    'type': {'const': 'function',
     'default': 'function',
     'title': 'Type',
     'type': 'string'},
    'name': {'title': 'Name', 'type': 'string'},
    'id': {'anyOf': [{'type': 'string'}, {'type': 'null'}],
     'default': None,
     'title': 'Id'},
    'example': {'default': False, 'title': 'Example', 'type': 'boolean'},
    'tool_calls': {'default': [],
     'items': {'$ref': '#/$defs/ToolCall'},
     'title': 'Tool Calls',
     'type': 'array'},
    'invalid_tool_calls': {'default': [],
     'items': {'$ref': '#/$defs/InvalidToolCall'},
     'title': 'Invalid Tool Calls',
     'type': 'array'},
    'usage_metadata': {'anyOf': [{'$ref': '#/$defs/UsageMetadata'},
      {'type': 'null'}],
     'default': None}},
   'required': ['content', 'name'],
   'title': 'FunctionMessage',
   'type': 'object'},
  'FunctionMessageChunk': {'additionalProperties': True,
   'description': 'Message chunk for passing the result of executing a tool back to a model.',
   'properties': {'content': {'anyOf': [{'type': 'string'},
      {'items': {'anyOf': [{'type': 'string'}, {'type': 'object'}]},
       'type': 'array'}],
     'title': 'Content'},
    'additional_kwargs': {'title': 'Additional Kwargs', 'type': 'object'},
    'response_metadata': {'title': 'Response Metadata', 'type': 'object'},
    'type': {'const': 'FunctionMessageChunk',
     'default': 'FunctionMessageChunk',
     'title': 'Type',
     'type': 'string'},
    'name': {'title': 'Name', 'type': 'string'},
    'id': {'anyOf': [{'type': 'string'}, {'type': 'null'}],
     'default': None,
     'title': 'Id'},
    'example': {'default': False, 'title': 'Example', 'type': 'boolean'},
    'tool_calls': {'default': [],
     'items': {'$ref': '#/$defs/ToolCall'},
     'title': 'Tool Calls',
     'type': 'array'},
    'invalid_tool_calls': {'default': [],
     'items': {'$ref': '#/$defs/InvalidToolCall'},
     'title': 'Invalid Tool Calls',
     'type': 'array'},
    'usage_metadata': {'anyOf': [{'$ref': '#/$defs/UsageMetadata'},
      {'type': 'null'}],
     'default': None},
    'tool_call_chunks': {'default': [],
     'items': {'$ref': '#/$defs/ToolCallChunk'},
     'title': 'Tool Call Chunks',
     'type': 'array'}},
   'required': ['content', 'name'],
   'title': 'FunctionMessageChunk',
   'type': 'object'},
  'HumanMessage': {'additionalProperties': True,
   'description': 'Message from a human.',
   'properties': {'content': {'anyOf': [{'type': 'string'},
      {'items': {'anyOf': [{'type': 'string'}, {'type': 'object'}]},
       'type': 'array'}],
     'title': 'Content'},
    'additional_kwargs': {'title': 'Additional Kwargs', 'type': 'object'},
    'response_metadata': {'title': 'Response Metadata', 'type': 'object'},
    'type': {'const': 'human',
     'default': 'human',
     'title': 'Type',
     'type': 'string'},
    'name': {'anyOf': [{'type': 'string'}, {'type': 'null'}],
     'default': None,
     'title': 'Name'},
    'id': {'anyOf': [{'type': 'string'}, {'type': 'null'}],
     'default': None,
     'title': 'Id'},
    'example': {'default': False, 'title': 'Example', 'type': 'boolean'},
    'tool_calls': {'default': [],
     'items': {'$ref': '#/$defs/ToolCall'},
     'title': 'Tool Calls',
     'type': 'array'},
    'invalid_tool_calls': {'default': [],
     'items': {'$ref': '#/$defs/InvalidToolCall'},
     'title': 'Invalid Tool Calls',
     'type': 'array'},
    'usage_metadata': {'anyOf': [{'$ref': '#/$defs/UsageMetadata'},
      {'type': 'null'}],
     'default': None}},
   'required': ['content'],
   'title': 'HumanMessage',
   'type': 'object'},
  'HumanMessageChunk': {'additionalProperties': True,
   'description': 'Message chunk from a human.',
   'properties': {'content': {'anyOf': [{'type': 'string'},
      {'items': {'anyOf': [{'type': 'string'}, {'type': 'object'}]},
       'type': 'array'}],
     'title': 'Content'},
    'additional_kwargs': {'title': 'Additional Kwargs', 'type': 'object'},
    'response_metadata': {'title': 'Response Metadata', 'type': 'object'},
    'type': {'const': 'HumanMessageChunk',
     'default': 'HumanMessageChunk',
     'title': 'Type',
     'type': 'string'},
    'name': {'anyOf': [{'type': 'string'}, {'type': 'null'}],
     'default': None,
     'title': 'Name'},
    'id': {'anyOf': [{'type': 'string'}, {'type': 'null'}],
     'default': None,
     'title': 'Id'},
    'example': {'default': False, 'title': 'Example', 'type': 'boolean'},
    'tool_calls': {'default': [],
     'items': {'$ref': '#/$defs/ToolCall'},
     'title': 'Tool Calls',
     'type': 'array'},
    'invalid_tool_calls': {'default': [],
     'items': {'$ref': '#/$defs/InvalidToolCall'},
     'title': 'Invalid Tool Calls',
     'type': 'array'},
    'usage_metadata': {'anyOf': [{'$ref': '#/$defs/UsageMetadata'},
      {'type': 'null'}],
     'default': None},
    'tool_call_chunks': {'default': [],
     'items': {'$ref': '#/$defs/ToolCallChunk'},
     'title': 'Tool Call Chunks',
     'type': 'array'}},
   'required': ['content'],
   'title': 'HumanMessageChunk',
   'type': 'object'},
  'InvalidToolCall': {'additionalProperties': True,
   'description': 'Represents a tool call that failed.',
   'properties': {'id': {'title': 'Id', 'type': 'string'},
    'type': {'const': 'invalid_tool_call',
     'default': 'invalid_tool_call',
     'title': 'Type',
     'type': 'string'},
    'code': {'title': 'Code', 'type': 'string'},
    'message': {'title': 'Message', 'type': 'string'},
    'tool_call_id': {'title': 'Tool Call Id', 'type': 'string'},
    'additional_kwargs': {'title': 'Additional Kwargs', 'type': 'object'},
    'response_metadata': {'title': 'Response Metadata', 'type': 'object'}},
   'required': ['id', 'code', 'message', 'tool_call_id'],
   'title': 'InvalidToolCall',
   'type': 'object'},
  'SystemMessage': {'additionalProperties': True,
   'description': 'Message from the system.',
   'properties': {'content': {'anyOf': [{'type': 'string'},
      {'items': {'anyOf': [{'type': 'string'}, {'type': 'object'}]},
       'type': 'array'}],
     'title': 'Content'},
    'additional_kwargs': {'title': 'Additional Kwargs', 'type': 'object'},
    'response_metadata': {'title': 'Response Metadata', 'type': 'object'},
    'type': {'const': 'system',
     'default': 'system',
     'title': 'Type',
     'type': 'string'},
    'name': {'anyOf': [{'type': 'string'}, {'type': '

```markdown
### langchain_core.messages

```python
from typing import Any, Dict, List, Optional, Union

from langchain_core.pydantic_v1 import BaseModel, Field, root_validator
from langchain_core.utils import (
    convert_to_json_compatible,
    get_type_display_name,
)

BaseMessage

class BaseMessage(BaseModel):
    """Base class for all messages."""

    content: Union[str, List[Union[str, Dict]]] = Field(
        ..., description="The contents of the message."
    )
    """Contents of the message."""
    additional_kwargs: Dict = Field(
        default_factory=dict,
        description="Additional information about the message.",
    )
    """Additional information about the message."""
    response_metadata: Dict = Field(
        default_factory=dict,
        description="Metadata about the response.",
    )
    """Metadata about the response."""
    type: str
    """Type of the message."""
    name: Optional[str] = Field(default=None, description="Optional name for the message.")
    """Optional name for the message."""
    id: Optional[str] = Field(default=None, description="Optional ID for the message.")
    """Optional ID for the message."""

    @root_validator(pre=True)
    def _validate_content(cls, values: Dict) -> Dict:
        content = values.get("content")
        if content is not None:
            values["content"] = convert_to_json_compatible(content)
        return values

    def dict(self, *args: Any, **kwargs: Any) -> Dict:
        """Return dictionary representation of message."""
        kwargs["exclude"] = kwargs.get("exclude", set()).union({"response_metadata"})
        return super().dict(*args, **kwargs)

    def __repr__(self) -> str:
        """Return string representation of message."""
        return (
            f"{self.__class__.__name__}(content='{self.content[:20]}'"
            f"{'...' if len(self.content) > 20 else ''}"
            f"{f', name={self.name}' if self.name else ''}"
            f")"
        )

    def __str__(self) -> str:
        """Return string representation of message."""
        return self.content

    def to_json(self) -> str:
        """Return JSON representation of message."""
        return self.json()

    @property
    def lc_namespace(self) -> List[str]:
        """Return the namespace of the module."""
        return ["langchain_core", "messages"]

    @property
    def lc_serializable(self) -> bool:
        """Return whether this class is serializable."""
        return True

BaseMessageChunk

class BaseMessageChunk(BaseMessage):
    """Base class for all message chunks."""

    @property
    def lc_serializable(self) -> bool:
        """Return whether this class is serializable."""
        return False

AIMessage

class AIMessage(BaseMessage):
    """Message from an AI."""

    type: str = "ai"
    """Type of the message."""
    name: Optional[str] = Field(default=None, description="Optional name for the message.")
    """Optional name for the message."""

    @classmethod
    def is_lc_serializable(cls) -> bool:
        """Return whether this class is serializable."""
        return True

    @property
    def lc_serializable(self) -> bool:
        """Return whether this class is serializable."""
        return True

AIMessageChunk

class AIMessageChunk(BaseMessageChunk):
    """AI Message chunk."""

    type: str = "AIMessageChunk"
    """Type of the message."""
    name: Optional[str] = Field(default=None, description="Optional name for the message.")
    """Optional name for the message."""

FunctionMessage

class FunctionMessage(BaseMessage):
    """Message from a function."""

    content: str = Field(..., description="The contents of the message.")
    """Contents of the message."""
    type: str = "function"
    """Type of the message."""
    name: str = Field(..., description="The name of the function.")
    """The name of the function."""
    id: Optional[str] = Field(default=None, description="Optional ID for the message.")
    """Optional ID for the message."""

    @classmethod
    def is_lc_serializable(cls) -> bool:
        """Return whether this class is serializable."""
        return True

    @property
    def lc_serializable(self) -> bool:
        """Return whether this class is serializable."""
        return True

FunctionMessageChunk

class FunctionMessageChunk(BaseMessageChunk):
    """Function Message chunk."""

    content: Union[str, List[Union[str, Dict]]] = Field(
        ..., description="The contents of the message."
    )
    """Contents of the message."""
    type: str = "FunctionMessageChunk"
    """Type of the message."""
    name: str = Field(..., description="The name of the function.")
    """The name of the function."""
    id: Optional[str] = Field(default=None, description="Optional ID for the message.")
    """Optional ID for the message."""

HumanMessage

class HumanMessage(BaseMessage):
    """Message from a human.

    HumanMessages are messages that are passed in from a human to the model.

    Example:

        .. code-block:: python

            from langchain_core.messages import HumanMessage, SystemMessage

            messages = [
                SystemMessage(
                    content="You are a helpful assistant! Your name is Bob."
                ),
                HumanMessage(
                    content="What is your name?"
                )
            ]

            # Instantiate a chat model and invoke it with the messages
            model = ...
            print(model.invoke(messages))
    """

    type: str = "human"
    """Type of the message."""
    name: Optional[str] = Field(default=None, description="Optional name for the message.")
    """Optional name for the message."""
    example: bool = Field(default=False, description="Whether this is an example message.")
    """Whether this is an example message."""

    @classmethod
    def is_lc_serializable(cls) -> bool:
        """Return whether this class is serializable."""
        return True

    @property
    def lc_serializable(self) -> bool:
        """Return whether this class is serializable."""
        return True

HumanMessageChunk

class HumanMessageChunk(BaseMessageChunk):
    """Human Message chunk."""

    type: str = "HumanMessageChunk"
    """Type of the message."""
    name: Optional[str] = Field(default=None, description="Optional name for the message.")
    """Optional name for the message."""
    example: bool = Field(default=False, description="Whether this is an example message.")
    """Whether this is an example message."""

InputTokenDetails

class InputTokenDetails(BaseModel):
    """Breakdown of input token counts.

    Does *not* need to sum to full input token count. Does *not* need to have all keys.

    Example:

        .. code-block:: python

            {
                "audio": 10,
                "cache_creation": 200,
                "cache_read": 100,
            }

    .. versionadded:: 0.3.9
    """

    audio: Optional[int] = None
    cache_creation: Optional[int] = None
    cache_read: Optional[int] = None

InvalidToolCall

class InvalidToolCall(BaseModel):
    """Allowance for errors made by LLM.

    Here we add an `error` key to surface errors made during generation
    (e.g., invalid JSON arguments.)
    """

    name: Optional[str] = Field(default=None)
    args: Optional[str] = Field(default=None)
    id: str
    error: str
    type: str = "invalid_tool_call"

OutputTokenDetails

class OutputTokenDetails(BaseModel):
    """Breakdown of output token counts.

    Does *not* need to sum to full output token count. Does *not* need to have all keys.

    Example:

        .. code-block:: python

            {


```markdown
### 消息类型

本文档介绍了 LangChain 中使用的不同消息类型。

```python
from typing import Any, Dict, List, Optional, Union

from langchain_core.pydantic_v1 import BaseModel, Field

BaseMessage

所有消息的基类。

class BaseMessage(BaseModel):
    """Base class for all messages."""

    content: Union[str, List[Any]] = Field(
        "", description="Contents of the message.  Can be a string or a list."
    )
    """Contents of the message.  Can be a string or a list."""
    additional_kwargs: Dict = Field(
        default_factory=dict,
        description="Additional information to include in the message.",
    )
    """Additional information to include in the message."""
    response_metadata: Dict = Field(
        default_factory=dict,
        description="Metadata about the response.",
    )
    """Metadata about the response."""
    type: str

    @property
    def lc_namespace(self) -> List[str]:
        """Return the namespace of the module."""
        return ["langchain_core", "messages"]

    @property
    def lc_serializable(self) -> bool:
        """Return whether this object is serializable."""
        return True

    def __add__(self, other: "BaseMessage") -> "BaseMessage":
        """Add two messages together.

        This is useful for merging chunks of messages.
        """
        raise NotImplementedError()

    def dict(self, *args: Any, **kwargs: Any) -> Dict:
        """Return dictionary representation of the message."""
        # We do not want to include the type in the dict
        # as it is already known.
        kwargs["exclude"] = kwargs.get("exclude", set()).union({"type"})
        return super().dict(*args, **kwargs)

    def json(self, *args: Any, **kwargs: Any) -> str:
        """Return JSON representation of the message."""
        # We do not want to include the type in the json
        # as it is already known.
        kwargs["exclude"] = kwargs.get("exclude", set()).union({"type"})
        return super().json(*args, **kwargs)

InputTokenDetails

class InputTokenDetails(BaseModel):
    """Input token details."""

    audio: Optional[int] = Field(default=None, description="Number of audio input tokens.")
    cache_creation: Optional[int] = Field(
        default=None, description="Number of cache creation input tokens."
    )
    cache_read: Optional[int] = Field(
        default=None, description="Number of cache read input tokens."
    )
    other: Optional[Dict[str, int]] = Field(
        default=None, description="Other input token details."
    )

OutputTokenDetails

class OutputTokenDetails(BaseModel):
    """Output token details."""

    audio: Optional[int] = Field(default=None, description="Number of audio output tokens.")
    reasoning: Optional[int] = Field(
        default=None, description="Number of reasoning output tokens."
    )
    other: Optional[Dict[str, int]] = Field(
        default=None, description="Other output token details."
    )

AIMessage

来自 AI 的消息。

class AIMessage(BaseMessage):
    """Message from an AI."""

    type: str = "ai"
    name: Optional[str] = Field(default=None, title="Name")
    id: Optional[str] = Field(default=None, title="Id")

AIMessageChunk

来自 AI 的消息块(例如,作为流的一部分)。

当合并 AIMessageChunks(例如,通过 AIMessageChunk.__add__)时,所有字符串属性都将被连接。

class AIMessageChunk(BaseMessage):
    """Chunk of a message from an AI (e.g., as part of a stream).

    When merging `AIMessageChunks` (e.g., via `AIMessageChunk.__add__`),
    all string attributes are concatenated.
    Chunks are only merged if their values of `index` are equal and not None.
    """

    type: str = "AIMessageChunk"
    name: Optional[str] = Field(default=None, title="Name")
    id: Optional[str] = Field(default=None, title="Id")
    tool_call_chunks: Optional[List["ToolCallChunk"]] = Field(
        default=None, title="Tool Call Chunks"
    )

    def __add__(self, other: "AIMessageChunk") -> "AIMessageChunk":
        """Add two messages together.

        This is useful for merging chunks of messages.
        """
        if not isinstance(other, AIMessageChunk):
            raise TypeError(f"Cannot add {type(other)} to AIMessageChunk")
        if self.tool_call_chunks is not None and other.tool_call_chunks is not None:
            if len(self.tool_call_chunks) != len(other.tool_call_chunks):
                raise ValueError(
                    "Cannot merge AIMessageChunks with different number of tool calls"
                )
            merged_tool_call_chunks: List[ToolCallChunk] = []
            for i in range(len(self.tool_call_chunks)):
                merged_tool_call_chunks.append(
                    self.tool_call_chunks[i] + other.tool_call_chunks[i]
                )
        elif self.tool_call_chunks is not None:
            merged_tool_call_chunks = self.tool_call_chunks
        elif other.tool_call_chunks is not None:
            merged_tool_call_chunks = other.tool_call_chunks
        else:
            merged_tool_call_chunks = None

        return AIMessageChunk(
            content=self.content + other.content,
            name=(self.name or "") + (other.name or ""),
            id=(self.id or "") + (other.id or ""),
            tool_call_chunks=merged_tool_call_chunks,
        )

BaseMessageChunk

消息块的基类。

class BaseMessageChunk(BaseModel):
    """Base class for message chunks."""

    content: Union[str, List[Any]] = Field(
        "", description="Contents of the message.  Can be a string or a list."
    )
    """Contents of the message.  Can be a string or a list."""
    additional_kwargs: Dict = Field(
        default_factory=dict,
        description="Additional information to include in the message.",
    )
    """Additional information to include in the message."""
    response_metadata: Dict = Field(
        default_factory=dict,
        description="Metadata about the response.",
    )
    """Metadata about the response."""
    type: str
    name: Optional[str] = Field(default=None, title="Name")
    id: Optional[str] = Field(default=None, title="Id")

    @property
    def lc_namespace(self) -> List[str]:
        """Return the namespace of the module."""
        return ["langchain_core", "messages"]

    @property
    def lc_serializable(self) -> bool:
        """Return whether this object is serializable."""
        return True

    def __add__(self, other: "BaseMessageChunk") -> "BaseMessageChunk":
        """Add two messages together.

        This is useful for merging chunks of messages.
        """
        raise NotImplementedError()

    def dict(self, *args: Any, **kwargs: Any) -> Dict:
        """Return dictionary representation of the message."""
        # We do not want to include the type in the dict
        # as it is already known.
        kwargs["exclude"] = kwargs.get("exclude", set()).union({"type"})
        return super().dict(*args, **kwargs)

    def json(self, *args: Any, **kwargs: Any) -> str:
        """Return JSON representation of the message."""
        # We do not want to include the type in the json
        # as it is already known.
        kwargs["exclude"] = kwargs.get("exclude", set()).union({"type"})
        return super().json(*args, **kwargs)

ChatMessage

来自聊天的通用消息。

class ChatMessage(BaseMessage):
    """A generic message from a chat."""

    role: str = Field(description="The role of the agent.")
    """The role of the agent."""
    type: str =
### PromptTemplateOutput

```json
"""
{
 'description': 'Output of a prompt template.',
 'oneOf': [{'$ref': '#/$defs/StringPromptValue'},
  {'$ref': '#/$defs/ChatPromptValueConcrete'}],
 '$defs': {
  'StringPromptValue': {
   'description': 'A single string prompt value.',
   'type': 'string',
   'title': 'StringPromptValue'},
  'ChatPromptValueConcrete': {
   'description': 'A chat prompt value.',
   'properties': {
    'messages': {
     'items': {'$ref': '#/$defs/ChatMessage'},
     'type': 'array',
     'description': 'The messages in the chat prompt.',
     'title': 'Messages'},
    'type': {'const': 'chat', 'description': 'The type of the prompt value.', 'title': 'Type'}},
   'required': ['messages', 'type'],
   'type': 'object',
   'title': 'ChatPromptValueConcrete'},
  'ChatMessage': {
   'description': 'A single chat message.',
   'oneOf': [{'$ref': '#/$defs/HumanChatMessage'},
    {'$ref': '#/$defs/AIChatMessage'},
    {'$ref': '#/$defs/SystemChatMessage'},
    {'$ref': '#/$defs/FunctionChatMessage'}],
   'title': 'ChatMessage'},
  'HumanChatMessage': {
   'description': 'A human chat message.',
   'properties': {
    'content': {'type': 'string', 'description': 'The content of the message.', 'title': 'Content'},
    'type': {'const': 'human', 'description': 'The type of the message.', 'title': 'Type'}},
   'required': ['content', 'type'],
   'type': 'object',
   'title': 'HumanChatMessage'},
  'AIChatMessage': {
   'description': 'An AI chat message.',
   'properties': {
    'content': {'type': ['string', 'null'], 'description': 'The content of the message.', 'title': 'Content'},
    'type': {'const': 'ai', 'description': 'The type of the message.', 'title': 'Type'},
    'additional_kwargs': {
     'type': 'object',
     'description': 'Additional information about the message.',
     'title': 'Additional Kwargs'}},
   'required': ['type'],
   'type': 'object',
   'title': 'AIChatMessage'},
  'SystemChatMessage': {
   'description': 'A system chat message.',
   'properties': {
    'content': {'type': 'string', 'description': 'The content of the message.', 'title': 'Content'},
    'type': {'const': 'system', 'description': 'The type of the message.', 'title': 'Type'}},
   'required': ['content', 'type'],
   'type': 'object',
   'title': 'SystemChatMessage'},
  'FunctionChatMessage': {
   'description': 'A function chat message.',
   'properties': {
    'content': {'type': ['string', 'null'], 'description': 'The content of the message.', 'title': 'Content'},
    'name': {'type': 'string', 'description': 'The name of the function.', 'title': 'Name'},
    'type': {'const': 'function', 'description': 'The type of the message.', 'title': 'Type'}},
   'required': ['name', 'type'],
   'type': 'object',
   'title': 'FunctionChatMessage'},
  'UsageMetadata': {
   'description': 'Metadata about the usage of the prompt template.',
   'properties': {},
   'type': 'object'}},
 'anyOf': [{'$ref': '#/$defs/StringPromptValue'},
  {'$ref': '#/$defs/ChatPromptValueConcrete'}],
 'title': 'PromptTemplateOutput'}
"""

消息类型和 LLM 创建

提供的模式非常详尽,详细说明了各种消息类型,例如 AIMessageHumanMessageChatMessage 等。这些定义概述了提示可能生成或与之交互的不同消息组件的结构和关系。

现在,让我们创建 LLM。

llm = ChatOpenAI(model="gpt-4o-mini")
llm.input_schema.model_json_schema()
    'type': {'const': 'function',
     'default': 'function',
     'title': 'Type',
     'type': 'string'},
    'name': {'title': 'Name', 'type': 'string'},
    'id': {'anyOf': [{'type': 'string'}, {'type': 'null'}],
     'default': None,
     'title': 'Id'},
    'example': {'default': False, 'title': 'Example', 'type': 'boolean'},
    'usage_metadata': {'anyOf': [{'$ref': '#/$defs/UsageMetadata'},
      {'type': 'null'}],
     'default': None}},
   'required': ['content', 'name'],
   'title': 'FunctionMessage',
   'type': 'object'},
  'FunctionMessageChunk': {'additionalProperties': True,
   'description': 'Message chunk for passing the result of executing a tool back to a model.',
   'properties': {'content': {'anyOf': [{'type': 'string'},
      {'items': {'anyOf': [{'type': 'string'}, {'type': 'object'}]},
       'type': 'array'}],
     'title': 'Content'},
    'additional_kwargs': {'title': 'Additional Kwargs', 'type': 'object'},
    'response_metadata': {'title': 'Response Metadata', 'type': 'object'},
    'type': {'const': 'FunctionMessageChunk',
     'default': 'FunctionMessageChunk',
     'title': 'Type',
     'type': 'string'},
    'name': {'title': 'Name', 'type': 'string'},
    'id': {'anyOf': [{'type': 'string'}, {'type': 'null'}],
     'default': None,
     'title': 'Id'},
    'example': {'default': False, 'title': 'Example', 'type': 'boolean'},
    'usage_metadata': {'anyOf': [{'$ref': '#/$defs/UsageMetadata'},
      {'type': 'null'}],
     'default': None}},
   'required': ['content', 'name'],
   'title': 'FunctionMessageChunk',
   'type': 'object'},
  'HumanMessage': {'additionalProperties': True,
   'description': 'Message from a human.',
   'properties': {'content': {'anyOf': [{'type': 'string'},
      {'items': {'anyOf': [{'type': 'string'}, {'type': 'object'}]},
       'type': 'array'}],
     'title': 'Content'},
    'additional_kwargs': {'title': 'Additional Kwargs', 'type': 'object'},
    'response_metadata': {'title': 'Response Metadata', 'type': 'object'},
    'type': {'const': 'human',
     'default': 'human',
     'title': 'Type',
     'type': 'string'},
    'name': {'anyOf': [{'type': 'string'}, {'type': 'null'}],
     'default': None,
     'title': 'Name'},
    'id': {'anyOf': [{'type': 'string'}, {'type': 'null'}],
     'default': None,
     'title': 'Id'},
    'example': {'default': False, 'title': 'Example', 'type': 'boolean'},
    'usage_metadata': {'anyOf': [{'$ref': '#/$defs/UsageMetadata'},
      {'type': 'null'}],
     'default': None}},
   'required': ['content'],
   'title': 'HumanMessage',
   'type': 'object'},
  'HumanMessageChunk': {'additionalProperties': True,
   'description': 'Message chunk from a human.',
   'properties': {'content': {'anyOf': [{'type': 'string'},
      {'items': {'anyOf': [{'type': 'string'}, {'type': 'object'}]},
       'type': 'array'}],
     'title': 'Content'},
    'additional_kwargs': {'title': 'Additional Kwargs', 'type': 'object'},
    'response_metadata': {'title': 'Response Metadata', 'type': 'object'},
    'type': {'const': 'HumanMessageChunk',
     'default': 'HumanMessageChunk',
     'title': 'Type',
     'type': 'string'},
    'name': {'anyOf': [{'type': 'string'}, {'type': 'null'}],
     'default': None,
     'title': 'Name'},
    'id': {'anyOf': [{'type': 'string'}, {'type': 'null'}],
     'default': None,
     'title': 'Id'},
    'example': {'default': False, 'title': 'Example', 'type': 'boolean'},
    'usage_metadata': {'anyOf': [{'$ref': '#/$defs/UsageMetadata'},
      {'type': 'null'}],
     'default': None}},
   'required': ['content'],
   'title': 'HumanMessageChunk',
   'type': 'object'},
  'InvalidToolCall': {'additionalProperties': True,
   'description': 'Represents an invalid tool call.',
   'properties': {'id': {'title': 'Id', 'type': 'string'},
    'name': {'title': 'Name', 'type': 'string'},
    'args': {'title': 'Args', 'type': 'string'},
    'message_log': {'items': {'$ref': '#/$defs/BaseMessage'},
     'title': 'Message Log',
     'type': 'array'},
    'invalid_message': {'$ref': '#/$defs/BaseMessage',
     'title': 'Invalid Message'}},
   'required': ['id', 'name', 'args', 'message_log', 'invalid_message'],
   'title': 'InvalidToolCall',
   'type': 'object'},
  'SystemMessage': {'additionalProperties': True,
   'description': 'Message from the system.',
   'properties': {'content': {'anyOf': [{'type': 'string'},
      {'items': {'anyOf': [{'type': 'string'}, {'type': 'object'}]},
       'type': 'array'}],
     'title': 'Content'},
    'additional_kwargs': {'title': 'Additional Kwargs', 'type': 'object'},
    'response_metadata': {'title': 'Response Metadata', 'type': 'object'},
    'type': {'const': 'system',
     'default': 'system',
     'title': 'Type',
     'type': 'string'},
    'name': {'anyOf': [{'type': 'string'}, {'type': 'null'}],
     'default': None,
     'title': 'Name'},
    'id': {'anyOf': [{'type': 'string'}, {'type': 'null'}],
     'default': None,
     'title': 'Id'},
    'example': {'default': False, 'title': 'Example', 'type': 'boolean'},
    'usage_metadata': {'anyOf': [{'$ref': '#/$defs/UsageMetadata'},
      {'type': 'null'}],
     'default': None}},
   'required': ['content'],
   'title': 'SystemMessage',
   'type': 'object'},
  'SystemMessageChunk': {'additionalProperties': True,
   'description': 'Message chunk from the system.',
   'properties': {'content': {'anyOf': [{'type': 'string'},
      {'items': {'anyOf': [{'type': 'string'}, {'type': 'object'}]},
       'type': 'array'}],
     'title': 'Content'},
    'additional_kwargs': {'title': 'Additional Kwargs', 'type': 'object'},
    'response_metadata': {'title': 'Response Metadata', 'type': 'object'},
    'type': {'const': 'SystemMessageChunk',
     'default': 'SystemMessageChunk',
     'title': 'Type',
     'type': 'string'},
    'name': {'anyOf': [{'type': 'string'}, {'type': 'null'}],
     'default': None,
     'title': 'Name'},
    'id': {'anyOf': [{'type': 'string'}, {'type': 'null'}],
     'default': None,
     'title': 'Id'},
    'example': {'default': False, 'title': 'Example', 'type': 'boolean'},
    'usage_metadata': {'anyOf': [{'$ref': '#/$defs/UsageMetadata'},
      {'type': 'null'}],
     'default': None}},
   'required': ['content'],
   'title': 'SystemMessageChunk',
   'type': 'object'},
  'ToolCall': {'additionalProperties': True,
   'description': 'Represents a tool call.',
   'properties': {'id': {'title': 'Id', 'type': 'string'},
    

```markdown
### langchain_core.messages

```python
from typing import Any, Dict, List, Optional, Union

from langchain_core.pydantic_v1 import BaseModel, Field

BaseMessage

class BaseMessage(BaseModel):
    """Base class for all messages."""

    content: Union[str, List[Union[str, Dict]]] = Field(
        ..., description="Contents of the message."
    )
    """Contents of the message."""
    additional_kwargs: Dict = Field(
        default_factory=dict,
        description="Additional information to pass to the model.",
    )
    """Additional information to pass to the model."""
    response_metadata: Dict = Field(
        default_factory=dict, description="Metadata about the response."
    )
    """Metadata about the response."""
    type: str
    """Type of the message."""
    name: Optional[str] = Field(default=None)
    """Name of the message sender."""
    id: Optional[str] = Field(default=None)
    """Unique ID of the message."""

    def __init__(self, **data: Any):
        """Initialize a message."""
        super().__init__(**data)

    @property
    def lc_namespace(self) -> List[str]:
        """Return the namespace of the module."""
        return ["langchain_core", "messages"]

    @property
    def lc_serializable(self) -> bool:
        """Return whether this object is serializable."""
        return True

AIMessage

class AIMessage(BaseMessage):
    """Message from an AI."""

    type: str = "ai"
    """Type of the message."""
    name: Optional[str] = Field(default=None)
    """Name of the message sender."""
    id: Optional[str] = Field(default=None)
    """Unique ID of the message."""
    def __init__(self, **data: Any):
        """Initialize a message."""
        super().__init__(**data)

AIMessageChunk

class AIMessageChunk(BaseMessage):
    """AI Message chunk."""

    type: str = "AIMessageChunk"
    """Type of the message."""
    name: Optional[str] = Field(default=None)
    """Name of the message sender."""
    id: Optional[str] = Field(default=None)
    """Unique ID of the message."""
    def __init__(self, **data: Any):
        """Initialize a message."""
        super().__init__(**data)

BaseMessageChunk

class BaseMessageChunk(BaseModel):
    """Base class for all message chunks."""

    content: Union[str, List[Union[str, Dict]]] = Field(
        ..., description="Contents of the message."
    )
    """Contents of the message."""
    additional_kwargs: Dict = Field(
        default_factory=dict,
        description="Additional information to pass to the model.",
    )
    """Additional information to pass to the model."""
    response_metadata: Dict = Field(
        default_factory=dict, description="Metadata about the response."
    )
    """Metadata about the response."""
    type: str
    """Type of the message."""
    name: Optional[str] = Field(default=None)
    """Name of the message sender."""
    id: Optional[str] = Field(default=None)
    """Unique ID of the message."""

    def __init__(self, **data: Any):
        """Initialize a message."""
        super().__init__(**data)

    @property
    def lc_namespace(self) -> List[str]:
        """Return the namespace of the module."""
        return ["langchain_core", "messages"]

    @property
    def lc_serializable(self) -> bool:
        """Return whether this object is serializable."""
        return True

ChatMessage

class ChatMessage(BaseMessage):
    """Message from any actor in a chat."""

    role: str = Field(..., description="The role of the agent.")
    """The role of the agent."""
    type: str = "chat"
    """Type of the message."""
    name: Optional[str] = Field(default=None)
    """Name of the message sender."""
    id: Optional[str] = Field(default=None)
    """Unique ID of the message."""

    def __init__(self, **data: Any):
        """Initialize a message."""
        super().__init__(**data)

ChatMessageChunk

class ChatMessageChunk(BaseMessageChunk):
    """Chat Message chunk."""

    role: str = Field(..., description="The role of the agent.")
    """The role of the agent."""
    type: str = "ChatMessageChunk"
    """Type of the message."""
    name: Optional[str] = Field(default=None)
    """Name of the message sender."""
    id: Optional[str] = Field(default=None)
    """Unique ID of the message."""

    def __init__(self, **data: Any):
        """Initialize a message."""
        super().__init__(**data)

FunctionMessage

class FunctionMessage(BaseMessage):
    """Message from a function call."""

    name: str = Field(..., description="The name of the function.")
    """The name of the function."""
    type: str = "function"
    """Type of the message."""
    id: Optional[str] = Field(default=None)
    """Unique ID of the message."""

    def __init__(self, **data: Any):
        """Initialize a message."""
        super().__init__(**data)

FunctionMessageChunk

class FunctionMessageChunk(BaseMessageChunk):
    """Function Message chunk."""

    name: str = Field(..., description="The name of the function.")
    """The name of the function."""
    type: str = "FunctionMessageChunk"
    """Type of the message."""
    id: Optional[str] = Field(default=None)
    """Unique ID of the message."""

    def __init__(self, **data: Any):
        """Initialize a message."""
        super().__init__(**data)

HumanMessage

class HumanMessage(BaseMessage):
    """Message from a human.

    HumanMessages are messages that are passed in from a human to the model.

    Example:

        .. code-block:: python

            from langchain_core.messages import HumanMessage, SystemMessage

            messages = [
                SystemMessage(
                    content="You are a helpful assistant! Your name is Bob."
                ),
                HumanMessage(
                    content="What is your name?"
                )
            ]

            # Instantiate a chat model and invoke it with the messages
            model = ...
            print(model.invoke(messages))
    """

    type: str = "human"
    """Type of the message."""
    name: Optional[str] = Field(default=None)
    """Name of the message sender."""
    id: Optional[str] = Field(default=None)
    """Unique ID of the message."""
    example: bool = Field(default=False)
    """Whether the message is an example."""

    def __init__(self, **data: Any):
        """Initialize a message."""
        super().__init__(**data)

HumanMessageChunk

class HumanMessageChunk(BaseMessageChunk):
    """Human Message chunk."""

    type: str = "HumanMessageChunk"
    """Type of the message."""
    name: Optional[str] = Field(default=None)
    """Name of the message sender."""
    id: Optional[str] = Field(default=None)
    """Unique ID of the message."""
    example: bool = Field(default=False)
    """Whether the message is an example."""

    def __init__(self, **data: Any):
        """Initialize a message."""
        super().__init__(**data)

InputTokenDetails

class InputTokenDetails(BaseModel):
    """Breakdown of input token counts.

    Does *not* need to sum to full input token count. Does *not* need to have all keys.

    Example:

        .. code-block:: python

            {
                "audio": 10,
                "cache_creation": 200,
                "cache_read": 100,
            }

    .. versionadded:: 0.3.9
    """

    audio: Optional[int] = None
    cache_creation: Optional[int] = None
    cache_read:

```markdown
### 消息类型

```json
{
  "$defs": {
    "InputTokenDetails": {
      "description": "Details about the input tokens.",
      "additionalProperties": {
        "type": "integer"
      },
      "title": "InputTokenDetails",
      "type": "object"
    },
    "OutputTokenDetails": {
      "description": "Details about the output tokens.",
      "additionalProperties": {
        "type": "integer"
      },
      "title": "OutputTokenDetails",
      "type": "object"
    }
  },
  "AIMessage": {
    "description": "Message from an AI.",
    "properties": {
      "content": {
        "anyOf": [
          {
            "type": "string"
          },
          {
            "items": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "object"
                }
              ]
            },
            "type": "array"
          }
        ],
        "title": "Content"
      },
      "additional_kwargs": {
        "title": "Additional Kwargs",
        "type": "object"
      },
      "response_metadata": {
        "title": "Response Metadata",
        "type": "object"
      },
      "type": {
        "const": "ai",
        "default": "ai",
        "title": "Type",
        "type": "string"
      },
      "name": {
        "anyOf": [
          {
            "type": "string"
          },
          {
            "type": "null"
          }
        ],
        "default": null,
        "title": "Name"
      },
      "id": {
        "anyOf": [
          {
            "type": "string"
          },
          {
            "type": "null"
          }
        ],
        "default": null,
        "title": "Id"
      },
      "tool_calls": {
        "items": {
          "$ref": "#/$defs/ToolCall"
        },
        "title": "Tool Calls",
        "type": "array"
      },
      "usage": {
        "allOf": [
          {
            "$ref": "#/$defs/UsageMetadata"
          },
          {
            "description": "Usage metadata for a message, such as token counts.",
            "title": "Usage Metadata",
            "type": "object"
          }
        ],
        "title": "Usage"
      }
    },
    "required": [
      "content"
    ],
    "title": "AIMessage",
    "type": "object"
  },
  "AIMessageChunk": {
    "description": "Chunk of an AI message (e.g., as part of a stream).",
    "properties": {
      "content": {
        "anyOf": [
          {
            "type": "string"
          },
          {
            "items": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "object"
                }
              ]
            },
            "type": "array"
          }
        ],
        "title": "Content"
      },
      "additional_kwargs": {
        "title": "Additional Kwargs",
        "type": "object"
      },
      "response_metadata": {
        "title": "Response Metadata",
        "type": "object"
      },
      "type": {
        "const": "AIMessageChunk",
        "default": "AIMessageChunk",
        "title": "Type",
        "type": "string"
      },
      "name": {
        "anyOf": [
          {
            "type": "string"
          },
          {
            "type": "null"
          }
        ],
        "default": null,
        "title": "Name"
      },
      "id": {
        "anyOf": [
          {
            "type": "string"
          },
          {
            "type": "null"
          }
        ],
        "default": null,
        "title": "Id"
      },
      "tool_call_chunks": {
        "items": {
          "$ref": "#/$defs/ToolCallChunk"
        },
        "title": "Tool Call Chunks",
        "type": "array"
      },
      "usage": {
        "allOf": [
          {
            "$ref": "#/$defs/UsageMetadata"
          },
          {
            "description": "Usage metadata for a message, such as token counts.",
            "title": "Usage Metadata",
            "type": "object"
          }
        ],
        "title": "Usage"
      }
    },
    "required": [
      "content"
    ],
    "title": "AIMessageChunk",
    "type": "object"
  },
  "BaseMessage": {
    "description": "Base class for all messages.",
    "properties": {
      "content": {
        "anyOf": [
          {
            "type": "string"
          },
          {
            "items": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "object"
                }
              ]
            },
            "type": "array"
          }
        ],
        "title": "Content"
      },
      "additional_kwargs": {
        "title": "Additional Kwargs",
        "type": "object"
      },
      "response_metadata": {
        "title": "Response Metadata",
        "type": "object"
      },
      "type": {
        "title": "Type",
        "type": "string"
      },
      "name": {
        "anyOf": [
          {
            "type": "string"
          },
          {
            "type": "null"
          }
        ],
        "default": null,
        "title": "Name"
      },
      "id": {
        "anyOf": [
          {
            "type": "string"
          },
          {
            "type": "null"
          }
        ],
        "default": null,
        "title": "Id"
      }
    },
    "required": [
      "content"
    ],
    "title": "BaseMessage",
    "type": "object"
  },
  "ChatMessage": {
    "description": "Message from a chat.",
    "properties": {
      "content": {
        "anyOf": [
          {
            "type": "string"
          },
          {
            "items": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "object"
                }
              ]
            },
            "type": "array"
          }
        ],
        "title": "Content"
      },
      "additional_kwargs": {
        "title": "Additional Kwargs",
        "type": "object"
      },
      "response_metadata": {
        "title": "Response Metadata",
        "type": "object"
      },
      "type": {
        "const": "chat",
        "default": "chat",
        "title": "Type",
        "type": "string"
      },
      "role": {
        "title": "Role",
        "type": "string"
      },
      "name": {
        "anyOf": [
          {
            "type": "string"
          },
          {
            "type": "null"
          }
        ],
        "default": null,
        "title": "Name"
      },
      "id": {
        "anyOf": [
          {
            "type": "string"
          },
          {
            "type": "null"
          }
        ],
        "default": null,
        "title": "Id"
      }
    },
    "required": [
      "content",
      "role"
    ],
    "title": "ChatMessage",
    "type": "object"
  },
  "ChatMessageChunk": {
    "description": "Chunk of a chat message (

ChatOpenAIInput Schema

{
 'description': 'ChatOpenAI的输入',
 'additionalProperties': False,
 'properties': {
  'model_name': {
   'title': 'Model Name',
   'type': 'string',
   'description': '要使用的模型名称。'},
  'temperature': {
   'default': 0.0,
   'description': '使用什么采样温度。较高的值意味着模型将承担更多风险。对于更具创造性的应用,尝试0.9,对于有明确答案的应用,尝试0(argmax采样)。',
   'title': 'Temperature',
   'type': 'number'},
  'top_p': {
   'default': 1.0,
   'description': '一种替代温度采样的方案,称为核采样,其中模型考虑具有top_p概率质量的标记的结果。因此,0.1意味着只考虑包含前10%概率质量的标记。',
   'title': 'Top P',
   'type': 'number'},
  'presence_penalty': {
   'default': 0.0,
   'description': '介于-2.02.0之间的数字。正值会根据新标记是否已出现在文本中来惩罚新标记,从而增加模型谈论新主题的可能性。',
   'title': 'Presence Penalty',
   'type': 'number'},
  'frequency_penalty': {
   'default': 0.0,
   'description': '介于-2.02.0之间的数字。正值会根据新标记在文本中已有的频率来惩罚新标记,从而降低模型逐字重复同一行的可能性。',
   'title': 'Frequency Penalty',
   'type': 'number'},
  'n': {
   'default': 1,
   'description': '为每个提示生成多少个补全。',
   'title': 'N',
   'type': 'integer'},
  'max_tokens': {
   'description': '在补全中生成的最大标记数。您的提示的标记计数加上max_tokens不能超过模型的上下文长度。大多数模型的上下文长度为2048个标记(最新的模型除外,它们支持4096个)。',
   'title': 'Max Tokens',
   'type': 'integer'},
  'model_kwargs': {
   'description': '保存任何对`model_name`有效的模型参数。',
   'title': 'Model Kwargs',
   'type': 'object'},
  'stop': {
   'anyOf': [{'type': 'string'}, {'items': {'type': 'string'}, 'type': 'array'}],
   'description': 'API将停止生成更多标记的最多4个序列。',
   'title': 'Stop'},
  'streaming': {
   'default': False,
   'description': '是否流式传输结果。',
   'title': 'Streaming',
   'type': 'boolean'},
  'callbacks': {
   'anyOf': [{
    'items': {'$ref': '#/$defs/BaseCallbackHandler'},
    'type': 'array'},
    {'$ref': '#/$defs/BaseCallbackHandler'}],
   'description': '用于此链的回调。',
   'title': 'Callbacks'},
  'tags': {
   'items': {'type': 'string'},
   'description': '用于此链的标签。',
   'title': 'Tags',
   'type': 'array'},
  'metadata': {
   'description': '用于此链的元数据。',
   'title': 'Metadata',
   'type': 'object'},
  'verbose': {
   'default': False,
   'description': '是否打印详细输出。',
   'title': 'Verbose',
   'type': 'boolean'},
  'return_only_outputs': {
   'default': False,
   'description': '是否仅返回输出或完整响应。',
   'title': 'Return Only Outputs',
   'type': 'boolean'},
  'handle_tokenization_error': {
   'default': False,
   'description': '是否处理标记化错误。',
   'title': 'Handle Tokenization Error',
   'type': 'boolean'},
  'input_variables': {
   'default': ['input'],
   'description': '要使用的输入变量。',
   'items': {'type': 'string'},
   'title': 'Input Variables',
   'type': 'array'},
  'prompt': {
   'anyOf': [{'$ref': '#/$defs/BasePromptTemplate'},
    {'type': 'string'},
    {'items': {'oneOf': [{'$ref': '#/$defs/AIMessage'},
       {'$ref': '#/$defs/HumanMessage'},
       {'$ref': '#/$defs/ChatMessage'},
       {'$ref': '#/$defs/SystemMessage'},
       {'$ref': '#/$defs/FunctionMessage'},
       {'$ref': '#/$defs/ToolMessage'},
       {'$ref': '#/$defs/AIMessageChunk'},
       {'$ref': '#/$defs/HumanMessageChunk'},
       {'$ref': '#/$defs/ChatMessageChunk'},
       {'$ref': '#/$defs/SystemMessageChunk'},
       {'$ref': '#/$defs/FunctionMessageChunk'},
       {'$ref': '#/$defs/ToolMessageChunk'}]},
     'type': 'array'}],
   'title': 'Prompt'},
  'messages': {
   'description': '用于聊天提示的消息列表。',
   'title': 'Messages',
   'anyOf': [{'type': 'string'},
    {'$ref': '#/$defs/StringPromptValue'},
    {'$ref': '#/$defs/ChatPromptValueConcrete'},
    {'items': {'oneOf': [{'$ref': '#/$defs/AIMessage'},
       {'$ref': '#/$defs/HumanMessage'},
       {'$ref': '#/$defs/ChatMessage'},
       {'$ref': '#/$defs/SystemMessage'},
       {'$ref': '#/$defs/FunctionMessage'},
       {'$ref': '#/$defs/ToolMessage'},
       {'$ref': '#/$defs/AIMessageChunk'},
       {'$ref': '#/$defs/HumanMessageChunk'},
       {'$ref': '#/$defs/ChatMessageChunk'},
       {'$ref': '#/$defs/SystemMessageChunk'},
       {'$ref': '#/$defs/FunctionMessageChunk'},
       {'$ref': '#/$defs/ToolMessageChunk'}]},
     'type': 'array'}],
   'title': 'Messages'},
  'extra_kwargs': {
   'description': '已弃用。请改用model_kwargs。',
   'title': 'Extra Kwargs',
   'type': 'object'},
  'api_key': {
   'description': 'OpenAI API密钥。',
   'title': 'Api Key',
   'type': 'string'},
  'openai_api_key': {
   'description': 'OpenAI API密钥。',
   'title': 'Openai Api Key',
   'type': 'string'},
  'openai_api_base': {
   'description': 'OpenAI API的基本URL。',
   'title': 'Openai Api Base',
   'type': 'string'},
  'openai_api_type': {
   'description': 'OpenAI API的类型。',
   'title': 'Openai Api Type',
   'type': 'string'},
  'openai_api_version': {
   'description': 'OpenAI API的API版本。',
   'title': 'Openai Api Version',
   'type': 'string'},
  'organization': {
   'description': 'OpenAI组织ID。',
   'title': 'Organization',
   'type': 'string'},
  'allowed_special': {
   'default': ['<|file_separator|>'],
   'description': '允许的特殊标记。',
   'items': {'type': 'string'},
   'title': 'Allowed Special',
   'type': 'array'},
  'client': {
   'description': '要使用的OpenAI客户端。',
   'title': 'Client',
   'anyOf': [{'$ref': '#/$defs/OpenAI'}, {'type': 'null'}]},
  'cache': {
   'description': '用于此链的缓存。',
   'title': 'Cache',
   'anyOf': [{'$ref': '#/$defs/BaseCache'}, {'type': 'null'}]},
  'request_timeout': {
   'description': 'OpenAI API请求的超时时间。',
   'title': 'Request Timeout',
   'type': ['integer', 'null']},
  }
}
### llm.output_schema.model_json_schema()

此函数返回一个 JSON 模式,描述了 LLM(大型语言模型)的输出结构。这对于验证 LLM 的输出是否符合预期格式非常有用。

#### 函数签名

```python
llm.output_schema.model_json_schema()

返回值

一个 JSON 模式(Python 字典),描述了 LLM 的输出结构。

示例

from langchain_core.pydantic_v1 import BaseModel, Field
from langchain_core.prompts import ChatPromptTemplate, MessagesPlaceholder
from langchain_core.runnables import chain
from langchain_openai import ChatOpenAI

## 定义一个 Pydantic 模型来描述输出
class Person(BaseModel):
    name: str = Field(description="The person's name")
    age: int = Field(description="The person's age")
    fav_food: str = Field(description="The person's favorite food")

## 创建一个 LLM 实例
llm = ChatOpenAI(model="gpt-3.5-turbo-0613", temperature=0)

## 创建一个提示模板
prompt = ChatPromptTemplate.from_messages(
    [
        ("system", "You are a helpful assistant that extracts information."),
        ("user", "Extract the following information: {information}"),
    ]
)

## 创建一个 Runnable 序列
chain = (
    prompt
    | llm.with_structured_output(Person)
)

## 获取 JSON 模式
json_schema = Person.model_json_schema()
print(json_schema)

## 使用 JSON 模式来获取 LLM 的输出
output = chain.invoke({"information": "My name is John, I am 30 years old and I like pizza."})
print(output)

详细说明

llm.output_schema.model_json_schema() 函数主要用于定义 LLM 输出的结构,并将其作为提示的一部分传递给 LLM。这有助于确保 LLM 的输出符合预期的格式,从而更容易地进行后续处理。

该函数通常与 with_structured_output() 方法结合使用,用于指定 LLM 输出的结构。with_structured_output() 方法接受一个 Pydantic 模型作为参数,该模型定义了输出的字段和数据类型。model_json_schema() 方法用于生成该 Pydantic 模型的 JSON 模式,然后将其传递给 LLM,从而指导 LLM 生成符合该 JSON 模式的输出。

通过使用 llm.output_schema.model_json_schema(),可以有效地控制 LLM 的输出格式,提高输出的可预测性和可处理性。

}, ‘id’: {‘anyOf’: [{‘type’: ‘string’}, {‘type’: ‘null’}], ‘default’: None, ‘title’: ‘Id’}}, ‘required’: [‘content’, ‘name’], ‘title’: ‘FunctionMessageChunk’, ‘type’: ‘object’}, ‘HumanMessage’: {‘additionalProperties’: True, ‘description’: ‘Message from a human.’, ‘properties’: {‘content’: {‘anyOf’: [{‘type’: ‘string’}, {‘items’: {‘anyOf’: [{‘type’: ‘string’}, {‘type’: ‘object’}]}, ‘type’: ‘array’}], ‘title’: ‘Content’}, ‘additional_kwargs’: {‘title’: ‘Additional Kwargs’, ‘type’: ‘object’}, ‘response_metadata’: {‘title’: ‘Response Metadata’, ‘type’: ‘object’}, ‘type’: {‘const’: ‘human’, ‘default’: ‘human’, ‘title’: ‘Type’, ‘type’: ‘string’}, ‘name’: {‘anyOf’: [{‘type’: ‘string’}, {‘type’: ‘null’}], ‘default’: None, ‘title’: ‘Name’}, ‘id’: {‘anyOf’: [{‘type’: ‘string’}, {‘type’: ‘null’}], ‘default’: None, ‘title’: ‘Id’}, ‘example’: {‘default’: False, ‘title’: ‘Example’, ‘type’: ‘boolean’}}, ‘required’: [‘content’], ‘title’: ‘HumanMessage’, ‘type’: ‘object’}, ‘HumanMessageChunk’: {‘additionalProperties’: True, ‘description’: ‘Human message chunk.’, ‘properties’: {‘content’: {‘anyOf’: [{‘type’: ‘string’}, {‘items’: {‘anyOf’: [{‘type’: ‘string’}, {‘type’: ‘object’}]}, ‘type’: ‘array’}], ‘title’: ‘Content’}, ‘additional_kwargs’: {‘title’: ‘Additional Kwargs’, ‘type’: ‘object’}, ‘response_metadata’: {‘title’: ‘Response Metadata’, ‘type’: ‘object’}, ‘type’: {‘const’: ‘HumanMessageChunk’, ‘default’: ‘HumanMessageChunk’, ‘title’: ‘Type’, ‘type’: ‘string’}, ‘name’: {‘anyOf’: [{‘type’: ‘string’}, {‘type’: ‘null’}], ‘default’: None, ‘title’: ‘Name’}, ‘id’: {‘anyOf’: [{‘type’: ‘string’}, {‘type’: ‘null’}], ‘default’: None, ‘title’: ‘Id’}, ‘example’: {‘default’: False, ‘title’: ‘Example’, ‘type’: ‘boolean’}}, ‘required’: [‘content’], ‘title’: ‘HumanMessageChunk’, ‘type’: ‘object’}, ‘InvalidToolCall’: {‘additionalProperties’: True, ‘description’: ‘Represents an invalid tool call.’, ‘properties’: {‘id’: {‘title’: ‘Id’, ‘type’: ‘string’}, ‘name’: {‘title’: ‘Name’, ‘type’: ‘string’}, ‘type’: {‘const’: ‘invalid_tool_call’, ‘default’: ‘invalid_tool_call’, ‘title’: ‘Type’, ‘type’: ‘string’}, ‘invalid_tool_call_error’: {‘title’: ‘Invalid Tool Call Error’, ‘type’: ‘string’}}, ‘required’: [‘id’, ‘name’, ‘invalid_tool_call_error’], ‘title’: ‘InvalidToolCall’, ‘type’: ‘object’}, ‘InvalidToolCallChunk’: {‘additionalProperties’: True, ‘description’: ‘Represents an invalid tool call chunk.’, ‘properties’: {‘id’: {‘title’: ‘Id’, ‘type’: ‘string’}, ‘name’: {‘title’: ‘Name’, ‘type’: ‘string’}, ‘type’: {‘const’: ‘InvalidToolCallChunk’, ‘default’: ‘InvalidToolCallChunk’, ‘title’: ‘Type’, ‘type’: ‘string’}, ‘invalid_tool_call_error’: {‘title’: ‘Invalid Tool Call Error’, ‘type’: ‘string’}}, ‘required’: [‘id’, ‘name’, ‘invalid_tool_call_error’], ‘title’: ‘InvalidToolCallChunk’, ‘type’: ‘object’}, ‘SystemMessage’: {‘additionalProperties’: True, ‘description’: ‘Message from the system.’, ‘properties’: {‘content’: {‘anyOf’: [{‘type’: ‘string’}, {‘items’: {‘anyOf’: [{‘type’: ‘string’}, {‘type’: ‘object’}]}, ‘type’: ‘array’}], ‘title’: ‘Content’}, ‘additional_kwargs’: {‘title’: ‘Additional Kwargs’, ‘type’: ‘object’}, ‘response_metadata’: {‘title’: ‘Response Metadata’, ‘type’: ‘object’}, ‘type’: {‘const’: ‘system’, ‘default’: ‘system’, ‘title’: ‘Type’, ‘type’: ‘string’}, ‘name’: {‘anyOf’: [{‘type’: ‘string’}, {‘type’: ‘null’}], ‘default’: None, ‘title’: ‘Name’}, ‘id’: {‘anyOf’: [{‘type’: ‘string’}, {‘type’: ‘null’}], ‘default’: None, ‘title’: ‘Id’}, ‘example’: {‘default’: False, ‘title’: ‘Example’, ‘type’: ‘boolean’}}, ‘required’: [‘content’], ‘title’: ‘SystemMessage’, ‘type’: ‘object’}, ‘SystemMessageChunk’: {‘additionalProperties’: True, ‘description’: ‘System message chunk.’, ‘properties’: {‘content’: {‘anyOf’: [{‘type’: ‘string’}, {‘items’: {‘anyOf’: [{‘type’: ‘string’}, {‘type’: ‘object’}]}, ‘type’: ‘array’}], ‘title’: ‘Content’}, ‘additional_kwargs’: {‘title’: ‘Additional Kwargs’, ‘type’: ‘object’}, ‘response_metadata’: {‘title’: ‘Response Metadata’, ‘type’: ‘object’}, ‘type’: {‘const’: ‘SystemMessageChunk’, ‘default’: ‘SystemMessageChunk’, ‘title’: ‘Type’, ‘type’: ‘string’}, ‘name’: {‘anyOf’: [{‘type’: ‘string’}, {‘type’: ‘null’}], ‘default’: None, ‘title’: ‘Name’}, ‘id’: {‘anyOf’: [{‘type’: ‘string’}, {‘type’: ‘null’}], ‘default’: None, ‘title’: ‘Id’}, ‘example’: {‘default’: False, ‘title’: ‘Example’, ‘type’: ‘boolean’}}, ‘required’: [‘content’], ‘title’: ‘SystemMessageChunk’, ‘type’: ‘object’}, ‘ToolCall’: {‘additionalProperties’: True, ‘description’: ‘Represents a tool call.’, ‘properties’: {‘id’: {‘title’: ‘Id’, ‘type’: ‘string’}, ‘type’: {‘const’: ‘function’, ‘default’: ‘function’, ‘title’: ‘Type’, ‘type’: ‘string’}, ‘function’: {‘title’: ‘Function’, ‘type’: ‘object’, ‘properties’: {‘name’: {‘title’: ‘Name’, ‘type’: ‘string’}, ‘arguments’: {‘title’: ‘Arguments’, ‘type’: ‘string’}}, ‘required’: [‘name’, ‘arguments’]}}, ‘required’: [‘id’, ‘function’], ‘title’: ‘ToolCall’, ‘type’: ‘object’}, ‘ToolCallChunk’: {‘additionalProperties’: True, ‘description’: ‘Represents a tool call chunk.’, ‘properties’: {‘id’: {‘title’: ‘Id’, ‘type’: ‘string’}, ‘type’: {‘const’: ‘ToolCallChunk’, ‘default’: ‘ToolCallChunk’, ‘title’: ‘Type’, ‘type’: ‘string’}, ‘function’: {‘title’: ‘Function’, ‘type’: ‘object’, ‘properties’: {‘name’: {‘title’: ‘Name’, ‘type’: ‘string’}, ‘arguments’: {‘title’: ‘Arguments’, ‘type’: ‘string’}}, ‘required’: [‘name’, ‘arguments’]}}, ‘required’: [‘id’, ‘function’], ‘title’: ‘ToolCallChunk’, ‘type’: ‘object’}, ‘ToolMessage’: {‘additionalProperties’: True, ‘description’: ‘Message for passing the result of executing a tool back to a model.’, ‘properties’: {‘content’: {‘anyOf’: [{‘type’: ‘string’}, {‘items’: {‘anyOf’: [{‘type’: ‘string’}, {‘type’: ‘object’}]}, ‘type’: ‘array’}], ‘title’: ‘Content’}, ‘additional_kwargs’: {‘title’: ‘Additional Kw

消息类型

以下是 LangChain 中使用的各种消息类型的定义。

AIMessage

from langchain_core.messages import AIMessage

## Define an AI message
message = AIMessage(content="你好!")
print(message)

AIMessageChunk

from langchain_core.messages import AIMessageChunk

## Define an AI message chunk
message = AIMessageChunk(content="你好!")
print(message)

BaseMessage

from langchain_core.messages import BaseMessage

## Define a base message
message = BaseMessage(content="你好!", type="base")
print(message)

FunctionMessage

from langchain_core.messages import FunctionMessage

## Define a function message
message = FunctionMessage(content="你好!", name="my_function")
print(message)

FunctionMessageChunk

from langchain_core.messages import FunctionMessageChunk

## Define a function message chunk
message = FunctionMessageChunk(content="你好!", name="my_function")
print(message)

HumanMessage

from langchain_core.messages import HumanMessage

## Define a human message
message = HumanMessage(content="你好!")
print(message)

HumanMessageChunk

from langchain_core.messages import HumanMessageChunk

## Define a human message chunk
message = HumanMessageChunk(content="你好!")
print(message)

InputTokenDetails

from langchain_core.messages import InputTokenDetails

## Define input token details
message = InputTokenDetails(audio=10, cache_creation=200, cache_read=100)
print(message)

InvalidToolCall

from langchain_core.messages import InvalidToolCall

## Define an invalid tool call
message = InvalidToolCall(name="my_tool", args="{}", id="123", error="Invalid JSON")
print(message)

OutputTokenDetails

from langchain_core.messages import OutputTokenDetails

## Define output token details
message = OutputTokenDetails(reasoning=200)
print(message)

SystemMessage

from langchain_core.messages import SystemMessage

## Define a system message
message = SystemMessage(content="你是一个有用的助手!")
print(message)
from langchain_core.messages import HumanMessage, SystemMessage

messages = [
    SystemMessage(
        content="You are a helpful assistant! Your name is Bob."
    ),
    HumanMessage(
        content="What is your name?"
    )
]

## Instantiate a chat model and invoke it with the messages
model = ...
print(model.invoke(messages))

SystemMessageChunk

from langchain_core.messages import SystemMessageChunk

## Define a system message chunk
message = SystemMessageChunk(content="你是一个有用的助手!")
print(message)

ToolCall

from langchain_core.messages import ToolCall

## Define a tool call
message = ToolCall(name="my_tool", args={"a": 1}, id="123")
print(message)

ToolCallChunk

from langchain_core.messages import ToolCallChunk

## Define a tool call chunk
message = ToolCallChunk(name="my_tool", args={"a": 1}, id="123")
print(message)
### ChatOpenAIOutput

```json
{
 'description': 'ChatOpenAI 调用的输出。',
 'definitions': {
  'InputTokenDetails': {
   'additionalProperties': {'type': 'integer'},
   'description': '关于输入 token 的详细信息。',
   'title': 'InputTokenDetails',
   'type': 'object'
  },
  'OutputTokenDetails': {
   'additionalProperties': {'type': 'integer'},
   'description': '关于输出 token 的详细信息。',
   'title': 'OutputTokenDetails',
   'type': 'object'
  },
  'AIMessage': {
   'additionalProperties': True,
   'description': '来自 AI 的消息。',
   'properties': {
    'content': {'anyOf': [{'type': 'string'}, {'type': 'null'}],
     'title': 'Content'},
    'additional_kwargs': {'title': 'Additional Kwargs', 'type': 'object'},
    'response_metadata': {'title': 'Response Metadata', 'type': 'object'},
    'type': {'const': 'ai', 'default': 'ai', 'title': 'Type', 'type': 'string'},
    'name': {'anyOf': [{'type': 'string'}, {'type': 'null'}],
     'default': None,
     'title': 'Name'},
    'id': {'anyOf': [{'type': 'string'}, {'type': 'null'}],
     'default': None,
     'title': 'Id'},
    'tool_calls': {
     'items': {'$ref': '#/$defs/ToolCall'},
     'title': 'Tool Calls',
     'type': 'array'
    },
    'function_call': {'$ref': '#/$defs/FunctionCall', 'title': 'Function Call'}
   },
   'required': ['content'],
   'title': 'AIMessage',
   'type': 'object'},
  'AIMessageChunk': {
   'additionalProperties': True,
   'description': 'AI 消息的块。',
   'properties': {
    'content': {'anyOf': [{'type': 'string'}, {'type': 'null'}],
     'title': 'Content'},
    'additional_kwargs': {'title': 'Additional Kwargs', 'type': 'object'},
    'response_metadata': {'title': 'Response Metadata', 'type': 'object'},
    'type': {'const': 'AIMessageChunk',
     'default': 'AIMessageChunk',
     'title': 'Type',
     'type': 'string'},
    'name': {'anyOf': [{'type': 'string'}, {'type': 'null'}],
     'default': None,
     'title': 'Name'},
    'id': {'anyOf': [{'type': 'string'}, {'type': 'null'}],
     'default': None,
     'title': 'Id'},
    'tool_call_chunks': {
     'items': {'$ref': '#/$defs/ToolCallChunk'},
     'title': 'Tool Call Chunks',
     'type': 'array'
    },
    'function_call': {'$ref': '#/$defs/FunctionCall', 'title': 'Function Call'}
   },
   'required': ['content'],
   'title': 'AIMessageChunk',
   'type': 'object'},
  'ChatMessage': {
   'additionalProperties': True,
   'description': '来自任何参与者的消息。',
   'properties': {
    'content': {'anyOf': [{'type': 'string'}, {'type': 'null'}],
     'title': 'Content'},
    'additional_kwargs': {'title': 'Additional Kwargs', 'type': 'object'},
    'response_metadata': {'title': 'Response Metadata', 'type': 'object'},
    'type': {'const': 'chat', 'default': 'chat', 'title': 'Type', 'type': 'string'},
    'name': {'anyOf': [{'type': 'string'}, {'type': 'null'}],
     'title': 'Name'},
    'id': {'anyOf': [{'type': 'string'}, {'type': 'null'}],
     'default': None,
     'title': 'Id'}
   },
   'required': ['content', 'name'],
   'title': 'ChatMessage',
   'type': 'object'},
  'ChatMessageChunk': {
   'additionalProperties': True,
   'description': '聊天消息的块。',
   'properties': {
    'content': {'anyOf': [{'type': 'string'}, {'type': 'null'}],
     'title': 'Content'},
    'additional_kwargs': {'title': 'Additional Kwargs', 'type': 'object'},
    'response_metadata': {'title': 'Response Metadata', 'type': 'object'},
    'type': {'const': 'ChatMessageChunk',
     'default': 'ChatMessageChunk',
     'title': 'Type',
     'type': 'string'},
    'name': {'anyOf': [{'type': 'string'}, {'type': 'null'}],
     'title': 'Name'},
    'id': {'anyOf': [{'type': 'string'}, {'type': 'null'}],
     'default': None,
     'title': 'Id'}
   },
   'required': ['content', 'name'],
   'title': 'ChatMessageChunk',
   'type': 'object'},
  'FunctionCall': {
   'description': '函数调用。',
   'properties': {'name': {'type': 'string', 'title': 'Name'},
    'arguments': {'type': 'string', 'title': 'Arguments'}},
   'required': ['name', 'arguments'],
   'title': 'FunctionCall',
   'type': 'object'},
  'FunctionMessage': {
   'additionalProperties': True,
   'description': '用于将函数输出传回模型的消息。',
   'properties': {
    'content': {'anyOf': [{'type': 'string'}, {'type': 'null'}],
     'title': 'Content'},
    'additional_kwargs': {'title': 'Additional Kwargs', 'type': 'object'},
    'response_metadata': {'title': 'Response Metadata', 'type': 'object'},
    'type': {'const': 'function',
     'default': 'function',
     'title': 'Type',
     'type': 'string'},
    'name': {'type': 'string', 'title': 'Name'},
    'id': {'anyOf': [{'type': 'string'}, {'type': 'null'}],
     'default': None,
     'title': 'Id'}
   },
   'required': ['content', 'name'],
   'title': 'FunctionMessage',
   'type': 'object'},
  'FunctionMessageChunk': {
   'additionalProperties': True,
   'description': '函数消息的块。',
   'properties': {
    'content': {'anyOf': [{'type': 'string'}, {'type': 'null'}],
     'title': 'Content'},
    'additional_kwargs': {'title': 'Additional Kwargs', 'type': 'object'},
    'response_metadata': {'title': 'Response Metadata', 'type': 'object'},
    'type': {'const': 'FunctionMessageChunk',
     'default': 'FunctionMessageChunk',
     'title': 'Type',
     'type': 'string'},
    'name': {'type': 'string', 'title': 'Name'},
    'id': {'anyOf': [{'type': 'string'}, {'type': 'null'}],
     'default': None,
     'title': 'Id'}
   },
   'required': ['content', 'name'],
   'title': 'FunctionMessageChunk',
   'type': 'object'},
  'HumanMessage': {
   'additionalProperties': True,
   'description': '来自人类的消息。',
   'properties': {
    'content': {'anyOf': [{'type': 'string'}, {'type': 'null'}],
     'title': 'Content'},
    'additional_kwargs': {'title': 'Additional Kwargs', 'type': 'object'},
    'response_metadata': {'title': 'Response Metadata', 'type': 'object'},
    'type': {'const': 'human',
     'default': 'human',
     'title': 'Type',
     'type': 'string'},
    'name': {'anyOf': [{'type': 'string'}, {'type': 'null'}],
     'default': None,
     'title': 'Name'},
    'id': {'anyOf': [{'type': 'string'}, {'type': 'null'}],
     'default': None,
     'title': 'Id'}
   },
   'required': ['content'],

class MovieReview(BaseModel): movie_title: str = Field(description=“电影的标题”) review: str = Field(description=“电影的评论”) language: str = Field(description=“评论的语言”)

parser = PydanticOutputParser(pydantic_object=MovieReview) format_instructions = parser.get_format_instructions()

parser.input_schema.model_json_schema()


```markdown
### 消息类型

```json
{'$defs': {'AIMessage': {'additionalProperties': True,
   'description': '来自 AI 的消息。\n\nAIMessage 作为对提示的响应从聊天模型返回。\n\n此消息表示模型的输出,由模型返回的原始输出以及 LangChain 框架添加的标准化字段(例如,工具调用、使用元数据)组成。',
   'properties': {'content': {'anyOf': [{'type': 'string'},
      {'items': {'anyOf': [{'type': 'string'}, {'type': 'object'}]},
       'type': 'array'}],
     'title': 'Content'},
    'additional_kwargs': {'title': 'Additional Kwargs', 'type': 'object'},
    'response_metadata': {'title': 'Response Metadata', 'type': 'object'},
    'type': {'const': 'ai',
     'default': 'ai',
     'title': 'Type',
     'type': 'string'},
    'name': {'anyOf': [{'type': 'string'}, {'type': 'null'}],
     'default': None,
     'title': 'Name'},
    'id': {'anyOf': [{'type': 'string'}, {'type': 'null'}],
     'default': None,
     'title': 'Id'},
    'example': {'default': False, 'title': 'Example', 'type': 'boolean'},
    'tool_calls': {'default': [],
     'items': {'$ref': '#/$defs/ToolCall'},
     'title': 'Tool Calls',
     'type': 'array'},
    'invalid_tool_calls': {'default': [],
     'items': {'$ref': '#/$defs/InvalidToolCall'},
     'title': 'Invalid Tool Calls',
     'type': 'array'},
    'usage_metadata': {'anyOf': [{'$ref': '#/$defs/UsageMetadata'},
      {'type': 'null'}],
     'default': None}},
   'required': ['content'],
   'title': 'AIMessage',
   'type': 'object'},
  'AIMessageChunk': {'additionalProperties': True,
   'description': '来自 AI 的消息块。',
   'properties': {'content': {'anyOf': [{'type': 'string'},
      {'items': {'anyOf': [{'type': 'string'}, {'type': 'object'}]},
       'type': 'array'}],
     'title': 'Content'},
    'additional_kwargs': {'title': 'Additional Kwargs', 'type': 'object'},
    'response_metadata': {'title': 'Response Metadata', 'type': 'object'},
    'type': {'const': 'AIMessageChunk',
     'default': 'AIMessageChunk',
     'title': 'Type',
     'type': 'string'},
    'name': {'anyOf': [{'type': 'string'}, {'type': 'null'}],
     'default': None,
     'title': 'Name'},
    'id': {'anyOf': [{'type': 'string'}, {'type': 'null'}],
     'default': None,
     'title': 'Id'},
    'example': {'default': False, 'title': 'Example', 'type': 'boolean'},
    'tool_calls': {'default': [],
     'items': {'$ref': '#/$defs/ToolCall'},
     'title': 'Tool Calls',
     'type': 'array'},
    'invalid_tool_calls': {'default': [],
     'items': {'$ref': '#/$defs/InvalidToolCall'},
     'title': 'Invalid Tool Calls',
     'type': 'array'},
    'usage_metadata': {'anyOf': [{'$ref': '#/$defs/UsageMetadata'},
      {'type': 'null'}],
     'default': None},
    'tool_call_chunks': {'default': [],
     'items': {'$ref': '#/$defs/ToolCallChunk'},
     'title': 'Tool Call Chunks',
     'type': 'array'}},
   'required': ['content'],
   'title': 'AIMessageChunk',
   'type': 'object'},
  'ChatMessage': {'additionalProperties': True,
   'description': '可以分配任意说话者(即角色)的消息。',
   'properties': {'content': {'anyOf': [{'type': 'string'},
      {'items': {'anyOf': [{'type': 'string'}, {'type': 'object'}]},
       'type': 'array'}],
     'title': 'Content'},
    'additional_kwargs': {'title': 'Additional Kwargs', 'type': 'object'},
    'response_metadata': {'title': 'Response Metadata', 'type': 'object'},
    'type': {'const': 'chat',
     'default': 'chat',
     'title': 'Type',
     'type': 'string'},
    'name': {'anyOf': [{'type': 'string'}, {'type': 'null'}],
     'default': None,
     'title': 'Name'},
    'id': {'anyOf': [{'type': 'string'}, {'type': 'null'}],
     'default': None,
     'title': 'Id'},
    'role': {'title': 'Role', 'type': 'string'}},
   'required': ['content', 'role'],
   'title': 'ChatMessage',
   'type': 'object'},
  'ChatMessageChunk': {'additionalProperties': True,
   'description': '聊天消息块。',
   'properties': {'content': {'anyOf': [{'type': 'string'},
      {'items': {'anyOf': [{'type': 'string'}, {'type': 'object'}]},
       'type': 'array'}],
     'title': 'Content'},
    'additional_kwargs': {'title': 'Additional Kwargs', 'type': 'object'},
    'response_metadata': {'title': 'Response Metadata', 'type': 'object'},
    'type': {'const': 'ChatMessageChunk',
     'default': 'ChatMessageChunk',
     'title': 'Type',
     'type': 'string'},
    'name': {'anyOf': [{'type': 'string'}, {'type': 'null'}],
     'default': None,
     'title': 'Name'},
    'id': {'anyOf': [{'type': 'string'}, {'type': 'null'}],
     'default': None,
     'title': 'Id'},
    'role': {'title': 'Role', 'type': 'string'}},
   'required': ['content', 'role'],
   'title': 'ChatMessageChunk',
   'type': 'object'},
  'FunctionMessage': {'additionalProperties': True,
   'description': '用于将执行工具的结果传递回模型的消息。\n\nFunctionMessage 是 ToolMessage 模式的旧版本,并且\n不包含 tool_call_id 字段。\n\ntool_call_id 字段用于将工具调用请求与\n工具调用响应关联起来。这在聊天模型能够\n并行请求多个工具调用的情况下很有用。',
   'properties': {'content': {'anyOf': [{'type': 'string'},
      {'items': {'anyOf': [{'type': 'string'}, {'type': 'object'}]},
       'type': 'array'}],
     'title': 'Content'},
    'additional_kwargs': {'title': 'Additional Kwargs', 'type': 'object'},
    'response_metadata': {'title': 'Response Metadata', 'type': 'object'},
    'type': {'const': 'function',
     'default': 'function',
     'title': 'Type',
     'type': 'string'},
    'name': {'title': 'Name', 'type': 'string'},
    'id': {'anyOf': [{'type': 'string'}, {'type': 'null'}],
     'default': None,
     'title': 'Id'}},
   'required': ['content', 'name'],
   'title': 'FunctionMessage',
   'type': 'object'},
  'FunctionMessageChunk': {'additionalProperties': True,
   'description': '函数消息块。',
   'properties': {'content': {'anyOf': [{'type': 'string'},
      {'items': {'anyOf': [{'type': 'string'}, {'type': 'object'}]},
       'type': 'array'}],
     'title': 'Content'},
    'additional_kwargs': {'title': 'Additional Kwargs', 'type': 'object'},
    'response_metadata': {'title': 'Response Metadata', 'type': 'object'},
    'type': {'const': 'FunctionMessageChunk',
     'default': 'FunctionMessageChunk',
     'title': 'Type',
     'type': 'string'},
    'name': {'title':

### 消息类型

LangChain 提供了多种消息类型,用于与大型语言模型 (LLM) 进行交互。这些消息类型定义了不同类型的输入和输出,以及它们各自的属性。

以下是 LangChain 中定义的消息类型的详细信息:

#### HumanMessage

`HumanMessage` 代表来自人类用户的消息。

```python
from langchain_core.messages import HumanMessage, SystemMessage

messages = [
    SystemMessage(
        content="You are a helpful assistant! Your name is Bob."
    ),
    HumanMessage(
        content="What is your name?"
    )
]

## Instantiate a chat model and invoke it with the messages
model = ...
print(model.invoke(messages))

属性:

  • content: 消息的内容。可以是字符串或字符串列表。
  • additional_kwargs: 额外的关键字参数。
  • response_metadata: 响应元数据。
  • type: 消息类型,固定为 “human”。
  • name: 消息的发送者名称。
  • id: 消息的 ID。
  • example: 一个布尔值,指示该消息是否为示例。

HumanMessageChunk

HumanMessageChunkHumanMessage 的一个分块版本。

属性:

  • content: 消息的内容。可以是字符串或字符串列表。
  • additional_kwargs: 额外的关键字参数。
  • response_metadata: 响应元数据。
  • type: 消息类型,固定为 “HumanMessageChunk”。
  • name: 消息的发送者名称。
  • id: 消息的 ID。
  • example: 一个布尔值,指示该消息是否为示例。

SystemMessage

SystemMessage 用于指示 AI 行为。通常作为消息序列的第一个消息传递。

from langchain_core.messages import HumanMessage, SystemMessage

messages = [
    SystemMessage(
        content="You are a helpful assistant! Your name is Bob."
    ),
    HumanMessage(
        content="What is your name?"
    )
]

## Define a chat model and invoke it with the messages
print(model.invoke(messages))

属性:

  • content: 消息的内容。可以是字符串或字符串列表。
  • additional_kwargs: 额外的关键字参数。
  • response_metadata: 响应元数据。
  • type: 消息类型,固定为 “system”。
  • name: 消息的发送者名称。
  • id: 消息的 ID。

SystemMessageChunk

SystemMessageChunkSystemMessage 的一个分块版本。

属性:

  • content: 消息的内容。可以是字符串或字符串列表。
  • additional_kwargs: 额外的关键字参数。
  • response_metadata: 响应元数据。
  • type: 消息类型,固定为 “SystemMessageChunk”。
  • name: 消息的发送者名称。
  • id: 消息的 ID。

ToolCall

ToolCall 代表调用工具的请求。

示例:

{
    "name": "foo",
    "args": {"a": 1},
    "id": "123"
}

这代表请求调用名为 “foo” 的工具,参数为 {"a": 1},标识符为 “123”。

属性:

  • name: 工具的名称。
  • args: 工具的参数。
  • id: 工具调用的 ID。
  • type: 消息类型,固定为 “tool_call”。

ToolCallChunk

ToolCallChunk 是工具调用的一个分块 (例如,作为流的一部分)。

属性:

  • name: 工具的名称。
  • args: 工具的参数。
  • id: 工具调用的 ID。
  • type: 消息类型,固定为 “ToolCallChunk”。

InvalidToolCall

InvalidToolCall 用于处理 LLM 产生的错误。

这里,我们在生成过程中添加一个 error 键来显示错误 (例如,无效的 JSON 参数)。

属性:

  • name: 工具的名称。
  • args: 工具的参数。
  • id: 工具调用的 ID。
  • error: 错误信息。
  • type: 消息类型,固定为 “invalid_tool_call”。

InputTokenDetails

输入令牌计数的细分。

不需要 累加到完整的输入令牌计数。 不需要 包含所有键。

示例:

{
    "audio": 10,
    "cache_creation": 200,
    "cache_read": 100,
}

属性:

  • audio: 音频令牌的数量。
  • cache_creation: 缓存创建的令牌数量。
  • cache_read: 缓存读取的令牌数量。

OutputTokenDetails

输出令牌计数的细分。

不需要 累加到完整的输出令牌计数。 不需要 包含所有键。

示例:

{
    "audio": 10,
    "reasoning": 200,
}

属性:

  • audio: 音频令牌的数量。
  • reasoning: 推理令牌的数量。

```python
{
 'description': 'Output parser for the chat model.',
 'definitions': {
  'InputTokenDetails': {'additionalProperties': {'type': 'integer'},
   'description': 'Details about the input tokens used.',
   'title': 'InputTokenDetails',
   'type': 'object'},
  'OutputTokenDetails': {'additionalProperties': {'type': 'integer'},
   'description': 'Details about the output tokens used.',
   'title': 'OutputTokenDetails',
   'type': 'object'},
  'AIMessage': {'additionalProperties': True,
   'description': 'Message from an AI.',
   'properties': {'content': {'anyOf': [{'type': 'string'},
      {'items': {'anyOf': [{'type': 'string'}, {'type': 'object'}]},
       'type': 'array'}],
     'title': 'Content'},
    'additional_kwargs': {'title': 'Additional Kwargs', 'type': 'object'},
    'response_metadata': {'title': 'Response Metadata', 'type': 'object'},
    'type': {'const': 'ai', 'default': 'ai', 'title': 'Type', 'type': 'string'},
    'name': {'anyOf': [{'type': 'string'}, {'type': 'null'}],
     'default': None,
     'title': 'Name'},
    'id': {'anyOf': [{'type': 'string'}, {'type': 'null'}],
     'default': None,
     'title': 'Id'},
    'tool_call_chunks': {'items': {'$ref': '#/$defs/ToolCallChunk'},
     'title': 'Tool Call Chunks',
     'type': 'array'},
    'usage': {'$ref': '#/$defs/UsageMetadata', 'title': 'Usage'}},
   'required': ['content'],
   'title': 'AIMessage',
   'type': 'object'},
  'AIMessageChunk': {'additionalProperties': True,
   'description': 'Message from an AI, in chunks.',
   'properties': {'content': {'anyOf': [{'type': 'string'},
      {'items': {'anyOf': [{'type': 'string'}, {'type': 'object'}]},
       'type': 'array'}],
     'title': 'Content'},
    'additional_kwargs': {'title': 'Additional Kwargs', 'type': 'object'},
    'response_metadata': {'title': 'Response Metadata', 'type': 'object'},
    'type': {'const': 'AIMessageChunk',
     'default': 'AIMessageChunk',
     'title': 'Type',
     'type': 'string'},
    'name': {'anyOf': [{'type': 'string'}, {'type': 'null'}],
     'default': None,
     'title': 'Name'},
    'id': {'anyOf': [{'type': 'string'}, {'type': 'null'}],
     'default': None,
     'title': 'Id'},
    'tool_call_chunks': {'items': {'$ref': '#/$defs/ToolCallChunk'},
     'title': 'Tool Call Chunks',
     'type': 'array'},
    'usage': {'$ref': '#/$defs/UsageMetadata', 'title': 'Usage'}},
   'required': ['content'],
   'title': 'AIMessageChunk',
   'type': 'object'},
  'ChatMessage': {'additionalProperties': True,
   'description': 'Message from any actor.',
   'properties': {'content': {'anyOf': [{'type': 'string'},
      {'items': {'anyOf': [{'type': 'string'}, {'type': 'object'}]},
       'type': 'array'}],
     'title': 'Content'},
    'additional_kwargs': {'title': 'Additional Kwargs', 'type': 'object'},
    'response_metadata': {'title': 'Response Metadata', 'type': 'object'},
    'type': {'const': 'chat', 'default': 'chat', 'title': 'Type', 'type': 'string'},
    'role': {'title': 'Role', 'type': 'string'},
    'name': {'anyOf': [{'type': 'string'}, {'type': 'null'}],
     'default': None,
     'title': 'Name'},
    'id': {'anyOf': [{'type': 'string'}, {'type': 'null'}],
     'default': None,
     'title': 'Id'},
    'usage': {'$ref': '#/$defs/UsageMetadata', 'title': 'Usage'}},
   'required': ['content', 'role'],
   'title': 'ChatMessage',
   'type': 'object'},
  'ChatMessageChunk': {'additionalProperties': True,
   'description': 'Message from any actor, in chunks.',
   'properties': {'content': {'anyOf': [{'type': 'string'},
      {'items': {'anyOf': [{'type': 'string'}, {'type': 'object'}]},
       'type': 'array'}],
     'title': 'Content'},
    'additional_kwargs': {'title': 'Additional Kwargs', 'type': 'object'},
    'response_metadata': {'title': 'Response Metadata', 'type': 'object'},
    'type': {'const': 'ChatMessageChunk',
     'default': 'ChatMessageChunk',
     'title': 'Type',
     'type': 'string'},
    'role': {'title': 'Role', 'type': 'string'},
    'name': {'anyOf': [{'type': 'string'}, {'type': 'null'}],
     'default': None,
     'title': 'Name'},
    'id': {'anyOf': [{'type': 'string'}, {'type': 'null'}],
     'default': None,
     'title': 'Id'},
    'usage': {'$ref': '#/$defs/UsageMetadata', 'title': 'Usage'}},
   'required': ['content', 'role'],
   'title': 'ChatMessageChunk',
   'type': 'object'},
  'FunctionMessage': {'additionalProperties': True,
   'description': 'Message for passing the result of a function back to a model.',
   'properties': {'content': {'anyOf': [{'type': 'string'},
      {'items': {'anyOf': [{'type': 'string'}, {'type': 'object'}]},
       'type': 'array'}],
     'title': 'Content'},
    'additional_kwargs': {'title': 'Additional Kwargs', 'type': 'object'},
    'response_metadata': {'title': 'Response Metadata', 'type': 'object'},
    'type': {'const': 'function',
     'default': 'function',
     'title': 'Type',
     'type': 'string'},
    'name': {'title': 'Name', 'type': 'string'},
    'id': {'anyOf': [{'type': 'string'}, {'type': 'null'}],
     'default': None,
     'title': 'Id'},
    'usage': {'$ref': '#/$defs/UsageMetadata', 'title': 'Usage'}},
   'required': ['content', 'name'],
   'title': 'FunctionMessage',
   'type': 'object'},
  'FunctionMessageChunk': {'additionalProperties': True,
   'description': 'Message for passing the result of a function back to a model, in chunks.',
   'properties': {'content': {'anyOf': [{'type': 'string'},
      {'items': {'anyOf': [{'type': 'string'}, {'type': 'object'}]},
       'type': 'array'}],
     'title': 'Content'},
    'additional_kwargs': {'title': 'Additional Kwargs', 'type': 'object'},
    'response_metadata': {'title': 'Response Metadata', 'type': 'object'},
    'type': {'const': 'FunctionMessageChunk',
     'default': 'FunctionMessageChunk',
     'title': 'Type',
     'type': 'string'},
    'name': {'title': 'Name', 'type': 'string'},
    'id': {'anyOf': [{'type': 'string'}, {'type': 'null'}],
     'default': None,
     'title': 'Id'},
    'usage': {'$ref': '#/$defs/UsageMetadata', 'title': 'Usage'}},
   'required': ['content', 'name'],
   'title': 'FunctionMessageChunk',
   'type': 'object'},
  'HumanMessage': {'additionalProperties': True,
   'description': 'Message from a human.',
   'properties': {'content': {'anyOf': [{'type': 'string'},
      {'items': {'anyOf': [{'type': 'string'}, {'type': 'object'}]},
       'type': 'array'}],
     'title': 'Content'},
    'additional_kwargs': {'title': 'Additional Kwargs', 'type':

### Runnables

Runnables 是 Langchain 中的一个核心概念,它提供了一个统一的接口来调用 LLMs、chains 和 agents。它们提供了一种灵活且可组合的方式来构建复杂的应用程序。

#### 基本用法

Runnables 的基本用法包括创建和调用它们。

```python
from langchain_core.prompts import ChatPromptTemplate
from langchain_core.models import ChatOpenAI
from langchain_core.output_parsers import StrOutputParser

prompt = ChatPromptTemplate.from_template("Tell me a short joke about {topic}")
model = ChatOpenAI()
output_parser = StrOutputParser()

chain = prompt | model | output_parser

在这里,我们创建了一个 chain,它:

  1. 将一个主题作为输入,并使用 prompt template 格式化它。
  2. 将格式化的 prompt 传递给语言模型。
  3. 将模型的输出解析为字符串。

然后,我们可以使用一个输入主题来调用该 chain:

response = chain.invoke({"topic": "ice cream"})
print(response)

输入和输出 Schema

Runnables 支持输入和输出 schema,它们定义了预期的输入和输出格式。这允许更好的类型检查和错误处理。

from langchain_core.pydantic_v1 import BaseModel, Field

class MovieReview(BaseModel):
    movie_title: str = Field(description="The title of the movie")
    review: str = Field(description="The review of the movie")
    language: str = Field(description="The language of the review")

我们可以使用这些 schema 来定义 Runnables 的输入和输出格式。

from langchain_core.prompts import ChatPromptTemplate, MessagesPlaceholder
from langchain_core.models import ChatOpenAI
from langchain_core.output_parsers import JsonOutputParser

prompt_template = ChatPromptTemplate.from_messages(
    [
        ("system", "You are a helpful assistant that translates {input_language} to {output_language}."),
        ("human", "{input}"),
        MessagesPlaceholder(variable_name="history"),
    ]
)

model = ChatOpenAI()

parser = JsonOutputParser(pydantic_schema=MovieReview)

然后,我们可以访问 Runnables 的输入和输出 schema。

prompt_template.input_schema.model_json_schema()

"""
{'properties': {'input_language': {'title': 'Input Language', 'type': 'string'},
  'output_language': {'title': 'Output Language', 'type': 'string'},
  'input': {'title': 'Input', 'type': 'string'},
  'history': {'items': {'$ref': '#/definitions/BaseMessage'},
   'title': 'History',
   'type': 'array'}},
 'required': ['input_language', 'output_language', 'input'],
 'title': 'PromptInput',
 'type': 'object',
 'definitions': {'BaseMessage': {'properties': {'type': {'title': 'Type',
      'type': 'string'},
     'content': {'title': 'Content', 'type': 'string'}},
    'required': ['type', 'content'],
    'title': 'BaseMessage',
    'type': 'object'}}}
"""

model.input_schema.model_json_schema()

"""
{'properties': {'messages': {'items': {'$ref': '#/definitions/BaseMessage'},
   'title': 'Messages',
   'type': 'array'},
  'functions': {'items': {'$ref': '#/definitions/FunctionSchema'},
   'title': 'Functions',
   'type': 'array'},
  'function_call': {'anyOf': [{'type': 'string'},
    {'type': 'object',
     'properties': {'name': {'title': 'Name', 'type': 'string'}},
     'required': ['name']}],
   'title': 'Function Call'}},
 'required': ['messages'],
 'title': 'ChatInput',
 'type': 'object',
 'definitions': {'BaseMessage': {'properties': {'type': {'title': 'Type',
      'type': 'string'},
     'content': {'title': 'Content', 'type': 'string'}},
    'required': ['type', 'content'],
    'title': 'BaseMessage',
    'type': 'object'},
  'FunctionSchema': {'properties': {'name': {'title': 'Name', 'type': 'string'},
     'description': {'title': 'Description', 'type': 'string'},
     'parameters': {'title': 'Parameters', 'type': 'object'}},
    'required': ['name', 'parameters'],
    'title': 'FunctionSchema',
    'type': 'object'}}}
"""

parser.output_schema.model_json_schema()

"""
{'properties': {'movie_title': {'description': 'The title of the movie',
   'title': 'Movie Title',
   'type': 'string'},
  'review': {'description': 'The review of the movie',
   'title': 'Review',
   'type': 'string'},
  'language': {'description': 'The language of the review',
   'title': 'Language',
   'type': 'string'}},
 'required': ['movie_title', 'review', 'language'],
 'title': 'MovieReview',
 'type': 'object'}
"""

最后,我们可以构建我们的 chain。我们使用 | 管道运算符来链接每个组件。

chain = prompt_template | model | parser
chain.input_schema.model_json_schema()

"""
{'properties': {'format_instructions': {'title': 'Format Instructions',
   'type': 'string'},
  'movie': {'title': 'Movie', 'type': 'string'}},
 'required': ['format_instructions', 'movie'],
 'title': 'PromptInput',
 'type': 'object'}
"""

chain.output_schema.model_json_schema()

"""
{'properties': {'movie_title': {'description': 'The title of the movie',
   'title': 'Movie Title',
   'type': 'string'},
  'review': {'description': 'The review of the movie',
   'title': 'Review',
   'type': 'string'},
  'language': {'description': 'The language of the review',
   'title': 'Language',
   'type': 'string'}},
 'required': ['movie_title', 'review', 'language'],
 'title': 'MovieReview',
 'type': 'object'}
"""

我们使用 Runnable 的 invoke 方法并获取响应。

使用提示调用链

result = runnable.invoke('hello')
print(result)
### Output: {'llm1': 'completion', 'llm2': 'completion', 'total_chars': 20}

fake_llm 函数模拟一个 LLM。我们使用 | 运算符将字典链接到 RunnablePassthrough.assign()

RunnablePassthrough.assign() 是一种方法,它接受关键字参数,其中每个键是要添加的新字段,其值是一个函数,该函数根据输入计算该字段的值。

在这种情况下,它向输出添加一个新键 'total_chars'。该值由一个 lambda 函数计算,该函数:

  • 接受 inputs(一个包含 'llm1''llm2' 的输出的字典)。
  • 连接来自 inputs['llm1']inputs['llm2'] 的字符串。
  • 使用 len() 计算连接字符串的长度。
result = runnable.invoke('hello')
  • 使用输入 'hello' 调用 invoke 方法。
  • 此输入传递给 'llm1''llm2' 函数(它们都是 fake_llm)。
  • 每个 fake_llm 函数返回 'completion'
  • 输出被收集到一个字典中:{'llm1': 'completion', 'llm2': 'completion'}
  • 在获得初始输出后,RunnablePassthrough.assign() 添加 'total_chars' 键。

让我们创建一个 RAG 示例。

from langchain_core.prompts import ChatPromptTemplate
from langchain_community.vectorstores import FAISS
from langchain_core.output_parsers import StrOutputParser
from langchain_core.runnables import RunnablePassthrough
from langchain_openai import OpenAIEmbeddings, ChatOpenAI

template = """仅根据以下上下文回答问题:
{context}

问题:{question}
"""
prompt = ChatPromptTemplate.from_template(template)

llm = ChatOpenAI(model="gpt-4o-mini")

vectorstore = FAISS.from_texts(
    ["harrison worked at kensho"], embedding=OpenAIEmbeddings()
)
retriever = vectorstore.as_retriever()

retrieval_chain = (
    {
        "context": retriever.with_config(run_name="Docs"),
        "question": RunnablePassthrough(),
    }
    | prompt
    | llm.with_config(run_name="my_llm")
    | StrOutputParser()
)

response = retrieval_chain.invoke("Where did harrison work?")

print(response)

"""
'Harrison worked at Kensho.'
"""

让我们仔细看看链部分,在这里我们组合了 Runnables。

retrieval_chain = (
    {
        "context": retriever.with_config(run_name="Docs"),
        "question": RunnablePassthrough(),
    }
    | prompt
    | llm.with_config(run_name="my_llm")
    | StrOutputParser()
)

response = retrieval_chain.invoke("Where did harrison work?")

此链旨在通过检索相关上下文并生成适当的答案来处理用户的问题。

首先,可运行的是带有上下文和问题的字典。

{
    "context": retriever.with_config(run_name="Docs"),
    "question": RunnablePassthrough(),
}

这是一个字典,它为链构建了初始输入结构。它是一个 RunnableParallel 结构,这意味着它并行处理其键(上下文和问题),并生成一个包含这些键的字典输出。

  • context:此键与 retriever 对象关联,该对象配置了 "Docs"run_nameretriever 负责根据输入问题获取相关文档或上下文。
  • question:此键使用 RunnablePassthrough(),它只是将输入(用户的问题)不变地传递到下一步。
用户问题
      |
      v
+-----------------+
|  Retriever      |  --> 从向量存储中检索上下文
+-----------------+
      |
      v
+-----------------+
|  RunnablePassthrough |  --> 不变地传递问题
+-----------------+
      |
      v
+-----------------+
|  提示模板 |  --> 将上下文和问题格式化为提示
+-----------------+
      |
      v
+-----------------+
|  LLM (GPT-4)    |  --> 根据提示生成响应
+-----------------+
      |
      v
+-----------------+
|  StrOutputParser |  --> 将 LLM 的输出解析为字符串
+-----------------+
      |
      v
最终答案:"Harrison worked at Kensho."

另一个例子:

from operator import itemgetter

template = """仅根据以下上下文回答问题:
{context}

问题:{question}

像一个 {character_style} 角色一样回答。
"""

prompt = ChatPromptTemplate.from_template(template)

chain = (
    {
        "context": itemgetter("question") | retriever,
        "question": itemgetter("question"),
        "character_style": itemgetter("character_style"),
    }
    | prompt
    | llm
    | StrOutputParser()
)

response = chain.invoke({"question": "Where did harrison work?", "character_style": "funny"})

print(response)

"""
好吧,好吧,好吧!如果这不是我们的朋友哈里森,数据方面的大师!我的朋友,他正在 Kensho 炫耀他的东西!没错!Kensho!听起来很花哨,不是吗?我敢打赌,他正在那里处理数字,像计算器商店里的巫师一样创造奇迹!✨🧙‍♂️
"""

首先,我们有一个输入字典。此字典中的每个键都对应于我们的提示模板所需的字段。

{
    "context": itemgetter("question") | retriever,
    "question": itemgetter("question"),
    "character_style": itemgetter("character_style"),
}

itemgetter 是 Python operator 模块中的一个实用程序,它创建一个可调用对象,用于从集合(如字典)中提取特定项目。在这种情况下,itemgetter("question") 返回一个函数,该函数在给定一个字典时,检索与键 "question" 关联的值。

因此,首先,我们从输入字典中提取用户的问题,然后,| 运算符将提取的问题传递到 retriever 中。

retriever 在向量存储中搜索与问题相关的文档。

检索到的文档被分配到输出字典中的 context 键。

RunnableSequence

RunnableSequence 允许我们将多个 runnables 链接在一起,其中一个 runnable 的输出用作下一个的输入。

它可以通过使用 RunnableSequence 或(更常见的是)使用管道 | 运算符来创建。

实际上,这就是我们在本博客的演示中所做的事情。

RunnableParallel

RunnableParallel 是一个组合原语,它允许我们并发地执行多个 runnable,为每个 runnable 提供相同的输入,并返回它们输出的映射。当有几个可以同时执行的独立任务时,这特别有用,从而提高了效率并减少了总处理时间。

from langchain_core.runnables import RunnableParallel, RunnablePassthrough

runnable = RunnableParallel(
    passed=RunnablePassthrough(),
    extra=RunnablePassthrough.assign(muliplied=lambda x: x["num"] * 2),
    modified=lambda x: x["num"] + 1
)

runnable.invoke({"num": 1})

"""
{'passed': {'num': 1}, 'extra': {'num': 1, 'muliplied': 2}, 'modified': 2}
"""

我们创建了三个并行分支:

  • passed:使用 RunnablePassthrough 简单地原样传递输入。
  • extra:使用 RunnablePassthrough.assign() 向输入添加一个新字段 multiplied
  • modified:使用 lambda 函数仅转换 num 值。

输入被并发地馈送到 RunnableParallel 中的每个组件(passedextra 和 `modified)。

RunnableParallel 收集所有组件的输出并将它们组装成一个字典:

  • 'passed'{"num": 1}
  • 'extra'{"num": 1, "multiplied": 2}
  • 'modified'2
{
    'passed': {'num': 1},
    'extra': {'num': 1, 'multiplied': 2},
    'modified': 2
}

上面使用 character_style 的 RAG 示例实际上是一个 RunnableParallel

{
    "context": itemgetter("question") | retriever,
    "question": itemgetter("question"),
    "character_style": itemgetter("character_style"),
}

另一个例子:

joke_chain = ChatPromptTemplate.from_template("tell me a joke about {topic}") | llm

poem_chain = (
    ChatPromptTemplate.from_template("write a 2-line poem about {topic}") | llm
)

map_chain = RunnableParallel(joke=joke_chain, poem=poem_chain)

map_chain.invoke({"topic": "marriage"})

RunnableLambda

RunnableLambda 是一种实用程序,它允许我们将一个 Python 函数(或任何可调用对象)封装到一个 runnable 组件中。

from langchain_core.runnables import RunnableLambda

### Step 1: Define a custom function
def add_greeting(input_text):
    return f"Hello, {input_text}!"

### Step 2: Wrap the function in RunnableLambda
greet_runnable = RunnableLambda(add_greeting)

### Step 3: Use the RunnableLambda in a pipeline
result = greet_runnable.invoke("world")
print(result)  # Output: "Hello, world!"
from langchain_core.runnables import RunnableLambda, RunnablePassthrough

### Step 1: Define custom functions
def add_greeting(input_text):
    return f"Hello, {input_text}!"

def to_uppercase(input_text):
    return input_text.upper()

### Step 2: Wrap the functions in RunnableLambda
greet_runnable = RunnableLambda(add_greeting)
uppercase_runnable = RunnableLambda(to_uppercase)

### Step 3: Create a pipeline
pipeline = (
    RunnablePassthrough()  # Passes input through unchanged
    | greet_runnable       # Adds a greeting
    | uppercase_runnable  # Converts to uppercase
)

### Step 4: Invoke the pipeline
result = pipeline.invoke("world")
print(result)  # Output: "HELLO, WORLD!"
Input: "world"
      |
      v
+-----------------+
|  RunnablePassthrough |  --> Output: "world"
+-----------------+
      |
      v
+-----------------+
|  greet_runnable |  --> Output: "Hello, world!"
+-----------------+
      |
      v
+-----------------+
|  uppercase_runnable |  --> Output: "HELLO, WORLD!"
+-----------------+
      |
      v
Final Output: "HELLO, WORLD!"

封装在 RunnableLambda 中的函数只能接受一个参数。如果需要多个参数,请使用字典。

RunnableConfig

简单来说,它是 runnable 的配置。它可以包括元数据,如标签或回调(在调用 LLM 链时使用)。

在此示例中,我们定义了一个函数 parse_or_fix,它尝试解析 JSON 字符串。如果解析失败,它会利用一个重试机制,该机制涉及一个 LLM 来更正 JSON 格式。

import json
from langchain_core.prompts import ChatPromptTemplate
from langchain.schema.output_parser import StrOutputParser
from langchain.schema.runnable import RunnableConfig
from langchain.callbacks import get_openai_callback

def parse_or_fix(text: str, config: RunnableConfig):
    fixing_chain = (
        ChatPromptTemplate.from_template(
            "Fix the following text:\n\n```text\n{input}\n```\nError: {error}"
            " Don't narrate, just respond with the fixed data."
        )
        | ChatOpenAI()
        | StrOutputParser()
    )
    for _ in range(3):
        try:
            return json.loads(text)
        except Exception as e:
            text = fixing_chain.invoke({"input": text, "error": e}, config)
    return "Failed to parse"

with get_openai_callback() as cb:
    output = RunnableLambda(parse_or_fix).invoke(
        "{foo: bar}", {"tags": ["my-tag"], "callbacks": [cb]}
    )
    print(output)
    print(cb)

"""
{'foo': 'bar'}
Tokens Used: 63
 Prompt Tokens: 56
  Prompt Tokens Cached: 0
 Completion Tokens: 7
  Reasoning Tokens: 0
Successful Requests: 1
Total Cost (USD): $3.85e-0
"""

该函数最多尝试解析 JSON 字符串三次。如果解析失败,则调用 fixing_chain 来更正文本。然后,更正后的文本将在下一次迭代中使用。

fixing_chain 是一个 RunnableSequence(通过 | 运算符)。

get_openai_callback() 创建一个上下文管理器,该管理器通过回调对象 cb 跟踪 OpenAI API 使用情况(令牌、成本、请求)。

RunnableLambda(parse_or_fix).invokeparse_or_fix 函数封装在 RunnableLambda 中,并使用格式错误的 JSON 字符串和包含标签和回调的配置来调用它。

RunnableBranch

RunnableBranch 允许我们在工作流程中定义多个“分支”。 每个分支都与一个特定条件相关联。

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"
branch.invoke(None) # "goodbye"

另一个例子:此链将用户的问题分类为预定义的类别之一:TechnologyHealthOther

classification_chain = (
    PromptTemplate.from_template(
        """将以下问题分类为以下类别之一:`Technology`、`Health` 或 `Other`。

问题:{question}

类别:"""
    )
    | ChatOpenAI()
    | StrOutputParser()
)

technology_chain 回答与技术相关的问题。

technology_chain = (
    PromptTemplate.from_template(
        """你是一位技术专家。 始终以“作为技术大师,我可以告诉你”开头你的回答。 回答以下问题:

问题:{question}
        答案:"""
    )
    | ChatOpenAI()
)

health_chain 回答与健康相关的问题。

health_chain = (
    PromptTemplate.from_template(
        """你是一位健康专家。 始终以“作为健康专家,我建议”开头你的回答。 回答以下问题:

问题:{question}
        答案:"""
    )
    | ChatOpenAI()
)

general_chain 处理不属于指定类别的问题。

general_chain = (
    PromptTemplate.from_template(
        """我很乐意帮助你解决问题:

问题:{question}
        答案:"""
    )
    | ChatOpenAI()
)

RunnableBranch 根据分类结果将输入定向到适当的链。

branch = RunnableBranch(
    (lambda x: "technology" in x["category"].lower(), technology_chain),
    (lambda x: "health" in x["category"].lower(), health_chain),
    general_chain,  # 如果没有满足的条件,则为默认链
)

此管道首先对问题进行分类,然后将其路由到相应的响应链。

full_chain = {"category": classification_chain,
              "question": lambda x: x["question"]} | branch
response = full_chain.invoke({"question": "What are the latest advancements in artificial intelligence?"})
print(response)

"""
content="As a tech guru, I can tell you that the latest advancements in artificial intelligence include the development of more advanced deep learning algorithms, the integration of AI into various industries such as healthcare and finance, the emergence of autonomous systems, and the progress in natural language processing and computer vision technologies. Additionally, researchers are also focusing on enhancing AI's ability to understand and interpret human emotions, which opens up new possibilities for AI applications in mental health and social interactions." additional_kwargs={'refusal': None} response_metadata={'token_usage': {'completion_tokens': 91, 'prompt_tokens': 51, 'total_tokens': 142, '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-3.5-turbo-0125', 'system_fingerprint': None, 'finish_reason': 'stop', 'logprobs': None} id='run-24ab7153-c697-41c0-a5c0-c1a03cf5522a-0' usage_metadata={'input_tokens': 51, 'output_tokens': 91, 'total_tokens': 142, 'input_token_details': {'audio': 0, 'cache_read': 0}, 'output_token_details': {'audio': 0, 'reasoning': 0}}
"""

自定义 Runnable

我们可以通过实现 Runnable 类来创建自定义的 runnable。 让我们创建一个 Runnable,它在失败时多次重试任务,并可以选择延迟。

import time
import random
from langchain_core.runnables import Runnable
from langchain_core.runnables.utils import Input, Output
from typing import Any, Optional

class TaskRetrier(Runnable):
    """一个 Runnable,它在失败时多次重试任务,并可以选择延迟。"""

    def __init__(self, task: Runnable[Input, Output], max_attempts: int, delay_seconds: float = 0.0):
        """
        初始化 TaskRetrier。

        参数:
            task: 要执行具有重试逻辑的 Runnable。
            max_attempts: 尝试任务的最大次数。
            delay_seconds: 重试之间的延迟(以秒为单位)(默认值:0.0)。
        """
        self.task = task
        self.max_attempts = max_attempts
        self.delay_seconds = delay_seconds

    def invoke(self, input_data: Input, config: Optional[Any] = None) -> Output:
        """
        执行具有重试逻辑的任务。

        参数:
            input_data: 传递给任务的输入。
            config: 任务的可选配置(例如,回调)。

        返回:
            如果成功,则返回任务的输出。

        引发:
            Exception: 如果所有尝试都失败,则引发遇到的最后一个异常。
        """
        attempt_count = 0

        while attempt_count < self.max_attempts:
            try:
                return self.task.invoke(input_data, config)
            except Exception as error:
                attempt_count += 1
                print(f"重试 {attempt_count}/{self.max_attempts} 失败:{error}")
                if attempt_count >= self.max_attempts:
                    raise error
                if self.delay_seconds > 0:
                    time.sleep(self.delay_seconds)
def occasionally_fails(text: str) -> str:
    """
    一个将输入文本大写的函数,但有一半的时间会随机失败。

    参数:
        text: 要处理的输入字符串。

    返回:
        如果成功,则返回文本的大写版本。

    引发:
        ValueError: 随机引发以模拟失败。
    """
    if random.random() < 0.5:
        raise ValueError("模拟处理错误")
    return text.upper()

### 创建一个启用重试的 Runnable
retry_handler = TaskRetrier(
    task=RunnableLambda(occasionally_fails),
    max_attempts=3,
    delay_seconds=1.0,
)

### 测试重试逻辑
try:
    result = retry_handler.invoke("hello")
    print(f"成功:{result}")
except Exception as final_error:
    print(f"所有重试已用尽:{final_error}")

"""
Retry 1/3 failed: Simulated processing error
Success: HELLO
"""

我们可以使用 Runnablewith_retry 方法实现相同的逻辑!

import time
import random
from langchain_core.runnables import RunnableLambda

### 定义一个模拟偶尔失败的函数
def unreliable_function(input_value: str) -> str:
    if random.random() < 0.5:
        raise ValueError("发生随机故障")
    return input_value.upper()

### 将该函数包装在 RunnableLambda 中
runnable = RunnableLambda(unreliable_function)

为可运行对象添加重试逻辑

runnable_with_retries = runnable.with_retry(
    retry_if_exception_type=(ValueError,),  # Retry only on ValueError
    wait_exponential_jitter=True,           # Add jitter to the exponential backoff
    stop_after_attempt=3                    # Retry up to 3 times
)

### Invoke the runnable with retries
try:
    result = runnable_with_retries.invoke("hello")
    print(f"Success: {result}")
except Exception as e:
    print(f"Operation failed after retries: {e}")

总结

LangChain 中的可运行对象是模块化的、可执行的构建块,允许您通过链式、分支或并行运行任务来创建动态的 AI 工作流程。它们对于创建灵活、可重用的管道至关重要,这些管道通过自定义逻辑、LLM 或检索器等工具处理数据。

从本质上讲,可运行对象标准化了输入到输出的流程,使其易于适应各种场景——想想聊天机器人、数据解析或错误处理。在任何需要对复杂任务进行可组合、逐步控制的地方使用它们。

最重要的是,请记住这一点:可运行对象是您构建智能、自适应系统的乐高积木——掌握它们,您将解锁无限的可能性。

了解更多

[## LangChain in Chains #45: Web Scraping with LLMs

Integrating LLMs into Web Scraping Workflows Using LangChain

blog.devgenius.io](https://blog.devgenius.io/langchain-in-chains-45-web-scraping-with-llms-8c4192bde030)

[## Mastering CrewAI: Chapter 1 — Your First Intelligent Workflow

The Basics of Agents and Tasks

ai.plainenglish.io](https://ai.plainenglish.io/mastering-crewai-chapter-1-your-first-intelligent-workflow-06b58aed1b3d)

[## Inside AutoGen: Chapter 1 –Introducing AgentChat

An Overview of AgentChat’s Features

pub.aimind.so](https://pub.aimind.so/inside-autogen-chapter-1-introducing-agentchat-1ffbe4489bfe)

[## MobileNet and Depthwise Separable Convolutions: Faster, Smaller, Smarter

MobileNet Explained: The Secret to Efficient Deep Learning on Mobile Devices

medium.com](https://readmedium.com/mobilenet-and-depthwise-separable-convolutions-faster-smaller-smarter-798f5a3920d3)

来源

https://python.langchain.com/v0.1/docs/expression_language/interface/

https://python.langchain.com/docs/concepts/runnables/

https://python.langchain.com/v0.1/docs/expression_language/primitives/passthrough/

https://python.langchain.com/api_reference/core/runnables/langchain_core.runnables.base.RunnableSequence.html

https://www.youtube.com/watch?v=moJRxxEddzU

https://python.langchain.com/api_reference/core/runnables/langchain_core.runnables.base.RunnableParallel.html

来自 AI Mind 的消息

Related Posts

结合chatgpt-o3-mini与perplexity Deep Research的3步提示:提升论文写作质量的终极指南

结合chatgpt-o3-mini与perplexity Deep Research的3步提示:提升论文写作质量的终极指南

AI 研究报告和论文写作 合并两个系统指令以获得两个模型的最佳效果 Perplexity AI 的 Deep Research 工具提供专家级的研究报告,而 OpenAI 的 ChatGPT-o3-mini-high 擅长推理。我发现你可以将它们结合起来生成令人难以置信的论文,这些论文比任何一个模型单独撰写的都要好。你只需要将这个一次性提示复制到 **

阅读更多
让 Excel 过时的 10 种 Ai 工具:实现数据分析自动化,节省手工作业时间

让 Excel 过时的 10 种 Ai 工具:实现数据分析自动化,节省手工作业时间

Non members click here作为一名软件开发人员,多年来的一个发现总是让我感到惊讶,那就是人们还在 Excel

阅读更多
使用 ChatGPT 搜索网络功能的 10 种创意方法

使用 ChatGPT 搜索网络功能的 10 种创意方法

例如,提示和输出 你知道可以使用 ChatGPT 的“搜索网络”功能来完成许多任务,而不仅仅是基本的网络搜索吗? 对于那些不知道的人,ChatGPT 新的“搜索网络”功能提供实时信息。 截至撰写此帖时,该功能仅对使用 ChatGPT 4o 和 4o-mini 的付费会员开放。 ![](https://images.weserv.nl/?url=https://cdn-im

阅读更多
掌握Ai代理:解密Google革命性白皮书的10个关键问题解答

掌握Ai代理:解密Google革命性白皮书的10个关键问题解答

10 个常见问题解答 本文是我推出的一个名为“10 个常见问题解答”的新系列的一部分。在本系列中,我旨在通过回答关于该主题的十个最常见问题来分解复杂的概念。我的目标是使用简单的语言和相关的类比,使这些想法易于理解。 图片来自 [Solen Feyissa](https://unsplash.com/@solenfeyissa?utm_source=medium&utm_medi

阅读更多
在人工智能和技术领域保持领先地位的 10 项必学技能 📚

在人工智能和技术领域保持领先地位的 10 项必学技能 📚

在人工智能和科技这样一个动态的行业中,保持领先意味着不断提升你的技能。无论你是希望深入了解人工智能模型性能、掌握数据分析,还是希望通过人工智能转变传统领域如法律,这些课程都是你成功的捷径。以下是一个精心策划的高价值课程列表,可以助力你的职业发展,并让你始终处于创新的前沿。 1. 生成性人工智能简介课程: [生成性人工智能简介](https://genai.works

阅读更多
揭开真相!深度探悉DeepSeek AI的十大误区,您被误导了吗?

揭开真相!深度探悉DeepSeek AI的十大误区,您被误导了吗?

在AI军备竞赛中分辨事实与虚构 DeepSeek AI真的是它所宣传的游戏规则改变者,还是仅仅聪明的营销和战略炒作?👀 虽然一些人将其视为AI效率的革命性飞跃,但另一些人则认为它的成功建立在借用(甚至窃取的)创新和可疑的做法之上。传言称,DeepSeek的首席执行官在疫情期间像囤积卫生纸一样囤积Nvidia芯片——这只是冰山一角。 从其声称的550万美元培训预算到使用Open

阅读更多
Type something to search...