当前位置: 首页 > news >正文

langchain runnable

LangChain 文档详细解析

LangChain 是一个用于构建与语言模型(如GPT-4)交互的框架。本文档介绍了LangChain v0.1版本中的Runnable接口及其相关功能。

目录
  1. Runnable接口
  2. 输入和输出模式
  3. 使用示例
  4. 异步方法
  5. 事件流
  6. 并行处理

1. Runnable接口

为了简化自定义链(chain)的创建,LangChain实现了一个名为“Runnable”的协议。许多LangChain组件,如聊天模型、LLMs(大型语言模型)、输出解析器、检索器、提示模板等,都实现了Runnable协议。Runnable协议定义了一组标准方法,使得调用和定义自定义链变得更加容易。

标准接口方法包括:

  • stream: 流式返回响应的片段。
  • invoke: 在输入上调用链。
  • batch: 在输入列表上调用链。

这些方法还有对应的异步版本,适用于并发处理:

  • astream: 异步流式返回响应的片段。
  • ainvoke: 异步调用链。
  • abatch: 异步在输入列表上调用链。
  • astream_log: 除了最终响应,还流式返回中间步骤。
  • astream_events: (测试版)在链中发生事件时流式传输事件(在langchain-core 0.1.14中引入)。

组件的输入和输出类型因组件而异:

组件输入类型输出类型
Prompt字典PromptValue
ChatModel单字符串、聊天消息列表或PromptValueChatMessage
LLM单字符串、聊天消息列表或PromptValueString
OutputParserLLM或ChatModel的输出取决于解析器
Retriever单字符串文档列表
Tool单字符串或字典,取决于工具取决于工具

所有Runnable组件都公开输入和输出的schema,便于检查输入和输出:

  • input_schema: 由Runnable结构自动生成的输入Pydantic模型。
  • output_schema: 由Runnable结构自动生成的输出Pydantic模型。

2. 输入和输出模式

输入模式 描述了Runnable接受的输入结构,而 输出模式 描述了Runnable生成的输出结构。通过调用.schema()方法,可以获取输入或输出的JSONSchema表示。

示例:

# 获取链的输入模式(链的第一个部分是prompt)
chain.input_schema.schema()

输出示例:

{"title": "PromptInput","type": "object","properties": {"topic": {"title": "Topic","type": "string"}}
}

类似地,可以获取具体组件的输入模式,如prompt和model:

prompt.input_schema.schema()
model.input_schema.schema()

输出模式 类似,描述了链的最终输出:

chain.output_schema.schema()

输出示例:

{"title": "ChatOpenAIOutput","anyOf": [{"$ref": "#/definitions/AIMessage"},{"$ref": "#/definitions/HumanMessage"},...],"definitions": {"AIMessage": { ... },"HumanMessage": { ... },...}
}

3. 使用示例

为了说明Runnable接口的方法,我们创建一个简单的PromptTemplateChatModel链。

安装必要的包:

%pip install --upgrade --quiet langchain-core langchain-community langchain-openai

代码示例:

from langchain_core.prompts import ChatPromptTemplate
from langchain_openai import ChatOpenAImodel = ChatOpenAI()
prompt = ChatPromptTemplate.from_template("tell me a joke about {topic}")
chain = prompt | model

这里,我们创建了一个提示模板,要求模型根据主题(topic)讲一个笑话,并将提示与模型连接成一个链(chain)。

调用方法示例:

  • Stream(流式调用):

    for s in chain.stream({"topic": "bears"}):print(s.content, end="", flush=True)
    

    输出:

    Sure, here's a bear-themed joke for you:Why don't bears wear shoes?Because they already have bear feet!
    
  • Invoke(调用):

    chain.invoke({"topic": "bears"})
    

    输出:

    AIMessage(content="Why don't bears wear shoes? \n\nBecause they have bear feet!")
    
  • Batch(批量调用):

    chain.batch([{"topic": "bears"}, {"topic": "cats"}])
    

    输出:

    [AIMessage(content="Sure, here's a bear joke for you:\n\nWhy don't bears wear shoes?\n\nBecause they already have bear feet!"),AIMessage(content="Why don't cats play poker in the wild?\n\nToo many cheetahs!")
    ]
    

4. 异步方法

LangChain还支持异步调用,适用于需要并发处理的场景。以下是异步方法的示例:

  • 异步流式调用:

    async for s in chain.astream({"topic": "bears"}):print(s.content, end="", flush=True)
    

    输出与同步流式调用类似,但以异步方式处理。

  • 异步调用:

    await chain.ainvoke({"topic": "bears"})
    

    输出:

    AIMessage(content="Why don't bears ever wear shoes?\n\nBecause they already have bear feet!")
    
  • 异步批量调用:

    await chain.abatch([{"topic": "bears"}])
    

    输出:

    [AIMessage(content="Why don't bears wear shoes?\n\nBecause they have bear feet!")
    ]
    
  • 异步流式事件(测试版):

    async for event in retrieval_chain.astream_events("where did harrison work?", version="v1", include_names=["Docs", "my_llm"]
    ):# 处理事件
    

    输出示例展示了事件的触发过程和相应的数据变化。


5. 事件流

事件流 提供了一种机制,可以在链执行过程中捕捉和处理各种事件。这对于调试、监控和展示进度非常有用。

事件参考表:

事件名称相关组件数据内容
on_chat_model_startChatModel输入消息的内容
on_chat_model_streamChatModelAI消息片段
on_chat_model_endChatModel最终生成的消息
on_llm_startLLM输入内容
on_llm_streamLLM生成的内容片段
on_llm_endLLM最终生成的内容
on_chain_startChain链的开始执行
on_chain_streamChain链执行过程中的流式数据
on_chain_endChain链执行完成后的输出
on_tool_startTool工具开始执行的输入数据
on_tool_streamTool工具执行过程中的流式数据
on_tool_endTool工具执行完成后的输出
on_retriever_startRetriever检索器开始执行的查询
on_retriever_chunkRetriever检索器返回的文档片段
on_retriever_endRetriever检索器执行完成后的文档列表
on_prompt_startPromptTemplate提示模板开始执行的输入数据
on_prompt_endPromptTemplate提示模板执行完成后的消息

示例代码解析:

async for event in retrieval_chain.astream_events("where did harrison work?", version="v1", include_names=["Docs", "my_llm"]
):kind = event["event"]if kind == "on_chat_model_stream":print(event["data"]["chunk"].content, end="|")elif kind in {"on_chat_model_start"}:print()print("Streaming LLM:")elif kind in {"on_chat_model_end"}:print()print("Done streaming LLM.")elif kind == "on_retriever_end":print("--")print("Retrieved the following documents:")print(event["data"]["output"]["documents"])elif kind == "on_tool_end":print(f"Ended tool: {event['name']}")else:pass

输出示例:

--
Retrieved the following documents:
[Document(page_content='harrison worked at kensho')]Streaming LLM:
|H|arrison| worked| at| Kens|ho|.||
Done streaming LLM.

6. 并行处理

并行处理 允许同时执行多个Runnable,提升处理效率。LangChain通过RunnableParallel实现并行执行。

示例代码:

from langchain_core.runnables import RunnableParallelchain1 = ChatPromptTemplate.from_template("tell me a joke about {topic}") | model
chain2 = (ChatPromptTemplate.from_template("write a short (2 line) poem about {topic}")| model
)
combined = RunnableParallel(joke=chain1, poem=chain2)

调用示例:

combined.invoke({"topic": "bears"})

输出示例:

{'joke': AIMessage(content="Sure, here's a bear-related joke for you:\n\nWhy did the bear bring a ladder to the bar?\n\nBecause he heard the drinks were on the house!"),'poem': AIMessage(content="In wilderness they roam,\nMajestic strength, nature's throne.")
}

并行与批量处理结合:

combined.batch([{"topic": "bears"}, {"topic": "cats"}])

输出示例:

[{'joke': AIMessage(content="Sure, here's a bear joke for you:\n\nWhy don't bears wear shoes?\n\nBecause they have bear feet!"),'poem': AIMessage(content="Majestic bears roam,\nNature's strength, beauty shown.")},{'joke': AIMessage(content="Why don't cats play poker in the wild?\n\nToo many cheetahs!"),'poem': AIMessage(content="Whiskers dance, eyes aglow,\nCats embrace the night's gentle flow.")}
]

invoke()方法

invoke() 方法详解

在LangChain的Runnable接口中,invoke()方法是一个核心功能,用于在给定的输入上同步调用链(Chain)并获取结果。它简化了与链交互的过程,使开发者能够轻松地利用预定义或自定义的链来处理输入并生成输出。

1. 什么是 invoke() 方法?

invoke() 方法是Runnable协议的一部分,旨在同步地执行链上的操作。它接受一个输入,传递给链中的第一个组件(例如Prompt模板),然后依次通过链中的各个组件处理,最终返回链的输出。

2. invoke() 方法的基本用法
示例场景

假设我们有一个简单的链,由一个提示模板和一个聊天模型组成。我们希望根据给定的主题(topic)生成一个笑话。

步骤详解
  1. 安装必要的包

    首先,确保安装了LangChain及其相关组件:

    pip install --upgrade langchain-core langchain-community langchain-openai
    
  2. 导入必要的模块并初始化组件

    from langchain_core.prompts import ChatPromptTemplate
    from langchain_openai import ChatOpenAI# 初始化聊天模型
    model = ChatOpenAI()# 创建一个提示模板,要求模型根据主题讲笑话
    prompt = ChatPromptTemplate.from_template("tell me a joke about {topic}")# 将提示模板和模型连接成一个链
    chain = prompt | model
    
  3. 使用 invoke() 方法调用链

    # 定义输入
    input_data = {"topic": "bears"}# 调用 `invoke()` 方法
    result = chain.invoke(input_data)# 输出结果
    print(result)
    

    输出示例:

    AIMessage(content="Why don't bears wear shoes? \n\nBecause they have bear feet!")
    
3. invoke() 方法的参数
  • inputs: 一个字典,包含链所需的所有输入参数。键通常对应于提示模板中的占位符。

  • config(可选): 一个字典,用于配置调用的行为。例如,可以设置run_nametags等,用于追踪和管理不同的运行。

    result = chain.invoke(input_data, config={"run_name": "joke_run"})
    
4. invoke() 方法的返回值

invoke() 方法的返回值类型取决于链的最后一个组件。例如:

  • 如果链的最后一个组件是ChatModel,返回值可能是ChatMessage对象。
  • 如果链的最后一个组件是LLM,返回值可能是一个字符串。

示例:

result = chain.invoke({"topic": "cats"})
print(result)

可能的输出:

AIMessage(content="Why don't cats play poker in the wild?\n\nToo many cheetahs!")
5. invoke() 方法的应用场景
  • 单次请求:当需要根据单一输入生成输出时,invoke()方法非常适用。
  • 集成到应用程序中:可以将invoke()方法集成到Web应用、命令行工具或其他软件中,以实现动态内容生成。
6. invoke() 方法与其他方法的对比
  • stream()
    • invoke() 是同步的,适用于需要一次性获取完整输出的场景。
    • stream() 是流式的,适用于需要逐步处理输出(如实时显示生成内容)的场景。
  • batch()
    • invoke() 处理单个输入。
    • batch() 允许同时处理多个输入,提高处理效率。
  • 异步方法 (ainvoke())
    • ainvoke()invoke() 的异步版本,适用于需要并发处理的场景。
7. 实际案例
案例1:生成笑话
from langchain_core.prompts import ChatPromptTemplate
from langchain_openai import ChatOpenAI# 初始化模型和提示模板
model = ChatOpenAI()
prompt = ChatPromptTemplate.from_template("tell me a joke about {topic}")
chain = prompt | model# 调用 `invoke()` 方法
input_data = {"topic": "dogs"}
joke = chain.invoke(input_data)# 打印结果
print(joke.content)

输出:

Why don't dogs make good dancers?Because they have two left feet!
案例2:生成诗歌

假设我们有一个链,用于根据主题生成简短的诗歌:

from langchain_core.prompts import ChatPromptTemplate
from langchain_openai import ChatOpenAI# 初始化模型和提示模板
model = ChatOpenAI()
prompt = ChatPromptTemplate.from_template("write a short (2 line) poem about {topic}")
chain = prompt | model# 调用 `invoke()` 方法
input_data = {"topic": "sunset"}
poem = chain.invoke(input_data)# 打印结果
print(poem.content)

输出:

Sunset paints the sky in gold,
Day's embrace, a story told.
8. 进阶用法
配置 invoke() 方法

可以通过config参数传递额外的配置信息,以定制链的行为。例如,指定运行名称和标签:

input_data = {"topic": "technology"}
config = {"run_name": "tech_joke_run", "tags": ["joke", "technology"]}result = chain.invoke(input_data, config=config)
print(result.content)
错误处理

在使用invoke()方法时,可能会遇到各种错误(如输入格式错误、模型响应错误等)。建议使用异常处理机制来捕获和处理这些错误。

try:result = chain.invoke({"topic": "invalid_topic"})print(result.content)
except Exception as e:print(f"An error occurred: {e}")
9. 性能考虑

invoke() 方法是同步的,适用于处理较短或不频繁的请求。如果需要处理大量请求或需要更高的响应速度,建议考虑使用异步方法(如 ainvoke())或批量处理(batch())来优化性能。

示例:批量调用
inputs = [{"topic": "bears"}, {"topic": "cats"}, {"topic": "technology"}]
results = chain.batch(inputs)for res in results:print(res.content)

输出:

Why don't bears wear shoes?Because they have bear feet!Why don't cats play poker in the wild?Too many cheetahs!Why did the computer go to the doctor?Because it had a virus!
10. 总结

invoke() 方法是LangChain中一个强大且简洁的同步调用接口,适用于各种需要与链交互的场景。通过invoke(),开发者可以轻松地将输入传递给链,并获取生成的输出,无需关心链内部的具体实现细节。这使得构建复杂的自然语言处理应用变得更加高效和直观。

希望通过以上详细讲解,您能够更好地理解和使用LangChain中的invoke()方法,构建出强大而灵活的语言模型应用!

BaseChatModel


目录
  1. 类简介
  2. 核心方法
    • invoke()
    • ainvoke()
    • stream()
    • astream()
    • astream_events()
    • batch()
    • abatch()
    • batch_as_completed()
    • abatch_as_completed()
  3. 声明方法
    • bind_tools()
    • with_structured_output()
    • with_retry()
    • with_fallbacks()
    • configurable_fields()
    • configurable_alternatives()
    • with_types()
  4. 创建自定义聊天模型
  5. 属性和参数
    • cache
    • callback_manager
    • callbacks
    • custom_get_token_ids
    • disable_streaming
    • metadata
    • rate_limiter
    • tags
    • verbose
  6. 辅助方法
    • get_num_tokens()
    • get_num_tokens_from_messages()
    • get_token_ids()
  7. 示例代码
    • 绑定监听器
    • 重试机制
    • 结构化输出
    • 并行批量处理
  8. 总结

1. 类简介

BaseChatModel 是 LangChain 中所有聊天模型的基类。它定义了一系列方法,这些方法用于与底层模型交互,包括同步和异步调用、流式处理、批量处理等。通过继承 BaseChatModel,开发者可以创建自定义的聊天模型,扩展其功能以满足特定需求。


2. 核心方法

2.1 invoke() 方法

描述: invoke()BaseChatModel 中的一个核心同步方法,用于将单个输入传递给聊天模型,并返回生成的响应。

签名:

invoke(input: LanguageModelInput, config: RunnableConfig | None = None, *, stop: list[str] | None = None, **kwargs: Any) → BaseMessage

参数:

  • input (LanguageModelInput): 要传递给模型的输入,可以是字符串、消息列表或 PromptValue 对象。
  • config (RunnableConfig | None): 可选的配置参数,用于定制调用行为。
  • stop (list[str] | None): 可选的停止词列表,当生成的文本包含这些词时,模型将停止生成。
  • **kwargs (Any): 其他可选的关键字参数。

返回值:

  • BaseMessage: 模型生成的单个响应消息。

示例:

from langchain_core.prompts import ChatPromptTemplate
from langchain_openai import ChatOpenAI# 初始化聊天模型和提示模板
model = ChatOpenAI()
prompt = ChatPromptTemplate.from_template("tell me a joke about {topic}")
chain = prompt | model# 调用 invoke 方法
input_data = {"topic": "bears"}
result = chain.invoke(input_data)print(result.content)
# 输出示例: "Why don't bears wear shoes? \n\nBecause they have bear feet!"
2.2 ainvoke() 方法

描述: ainvoke()invoke() 的异步版本,用于在异步环境中调用聊天模型。

签名:

async ainvoke(input: LanguageModelInput, config: RunnableConfig | None = None, *, stop: list[str] | None = None, **kwargs: Any) → BaseMessage

参数和返回值:invoke() 方法相同,但返回的是一个异步的 BaseMessage 对象。

示例:

import asyncioasync def get_joke():result = await chain.ainvoke({"topic": "cats"})print(result.content)asyncio.run(get_joke())
# 输出示例: "Why don't cats play poker in the wild?\n\nToo many cheetahs!"
2.3 stream() 方法

描述: stream() 方法用于同步地流式获取模型的输出,适用于需要逐步处理输出的场景。

签名:

stream(input: LanguageModelInput, config: RunnableConfig | None = None, *, stop: list[str] | None = None, **kwargs: Any) → Iterator[BaseMessageChunk]

返回值:

  • Iterator[BaseMessageChunk]: 一个迭代器,逐步返回模型生成的输出片段。

示例:

for chunk in chain.stream({"topic": "bears"}):print(chunk.content, end="", flush=True)
# 输出示例:
# Sure, here's a bear-themed joke for you:
#
# Why don't bears wear shoes?
#
# Because they already have bear feet!
2.4 astream() 方法

描述: astream()stream() 的异步版本,用于在异步环境中流式获取模型的输出。

签名:

async astream(input: LanguageModelInput, config: RunnableConfig | None = None, *, stop: list[str] | None = None, **kwargs: Any) → AsyncIterator[BaseMessageChunk]

返回值:

  • AsyncIterator[BaseMessageChunk]: 一个异步迭代器,逐步返回模型生成的输出片段。

示例:

async def stream_joke():async for chunk in chain.astream({"topic": "bears"}):print(chunk.content, end="", flush=True)asyncio.run(stream_joke())
# 输出示例与同步流式调用相同
2.5 astream_events() 方法

描述: astream_events() 方法用于生成事件流,提供关于模型执行进度的实时信息,包括中间结果。

签名:

async astream_events(input: Any, config: RunnableConfig | None = None, *, version: Literal['v1', 'v2'], include_names: Sequence[str] | None = None, include_types: Sequence[str] | None = None, include_tags: Sequence[str] | None = None, exclude_names: Sequence[str] | None = None, exclude_types: Sequence[str] | None = None, exclude_tags: Sequence[str] | None = None, **kwargs: Any) → AsyncIterator[StandardStreamEvent | CustomStreamEvent]

返回值:

  • AsyncIterator[StandardStreamEvent | CustomStreamEvent]: 一个异步迭代器,逐步返回标准或自定义的事件。

示例:

async for event in chain.astream_events("tell me a joke about bears", version="v2"):print(event)
# 输出示例:
# {
#     "event": "on_chat_model_start",
#     "name": "ChatOpenAI",
#     "run_id": "some-unique-id",
#     "data": {"messages": [["SystemMessage", "HumanMessage"]]},
#     ...
# }
2.6 batch() 方法

描述: batch() 方法用于同步地批量处理多个输入,提高处理效率。

签名:

batch(inputs: list[Input], config: RunnableConfig | list[RunnableConfig] | None = None, *, return_exceptions: bool = False, **kwargs: Any | None)list[Output]

返回值:

  • list[Output]: 模型生成的多个输出消息列表。

示例:

inputs = [{"topic": "bears"}, {"topic": "cats"}]
results = chain.batch(inputs)
for res in results:print(res.content)
# 输出示例:
# "Why don't bears wear shoes? \n\nBecause they have bear feet!"
# "Why don't cats play poker in the wild?\n\nToo many cheetahs!"
2.7 abatch() 方法

描述: abatch()batch() 的异步版本,用于在异步环境中批量处理多个输入。

签名:

async abatch(inputs: list[Input], config: RunnableConfig | list[RunnableConfig] | None = None, *, return_exceptions: bool = False, **kwargs: Any | None)list[Output]

返回值:

  • list[Output]: 模型生成的多个输出消息列表。

示例:

async def batch_jokes():inputs = [{"topic": "bears"}, {"topic": "cats"}]results = await chain.abatch(inputs)for res in results:print(res.content)asyncio.run(batch_jokes())
# 输出示例:
# "Why don't bears wear shoes?\n\nBecause they have bear feet!"
# "Why don't cats play poker in the wild?\n\nToo many cheetahs!"
2.8 batch_as_completed() 方法

描述: batch_as_completed() 方法用于同步地并行处理多个输入,并在每个输入处理完成后立即返回结果。

签名:

batch_as_completed(inputs: Sequence[Input], config: RunnableConfig | Sequence[RunnableConfig] | None = None, *, return_exceptions: bool = False, **kwargs: Any | None) → Iterator[tuple[int, Output | Exception]]

返回值:

  • Iterator[tuple[int, Output | Exception]]: 一个迭代器,逐步返回每个输入的索引和对应的输出或异常。

示例:

inputs = [{"topic": "bears"}, {"topic": "cats"}, {"topic": "technology"}]
for idx, result in chain.batch_as_completed(inputs):if isinstance(result, Exception):print(f"Input {idx} raised an exception: {result}")else:print(f"Input {idx} result: {result.content}")
# 输出示例:
# Input 0 result: "Why don't bears wear shoes?\n\nBecause they have bear feet!"
# Input 1 result: "Why don't cats play poker in the wild?\n\nToo many cheetahs!"
# Input 2 result: "Why did the computer go to the doctor?\n\nBecause it had a virus!"
2.9 abatch_as_completed() 方法

描述: abatch_as_completed()batch_as_completed() 的异步版本,用于在异步环境中并行处理多个输入,并在每个输入处理完成后立即返回结果。

签名:

async abatch_as_completed(inputs: Sequence[Input], config: RunnableConfig | Sequence[RunnableConfig] | None = None, *, return_exceptions: bool = False, **kwargs: Any | None) → AsyncIterator[tuple[int, Output | Exception]]

返回值:

  • AsyncIterator[tuple[int, Output | Exception]]: 一个异步迭代器,逐步返回每个输入的索引和对应的输出或异常。

示例:

async def batch_as_completed_jokes():inputs = [{"topic": "bears"}, {"topic": "cats"}, {"topic": "technology"}]async for idx, result in chain.abatch_as_completed(inputs):if isinstance(result, Exception):print(f"Input {idx} raised an exception: {result}")else:print(f"Input {idx} result: {result.content}")asyncio.run(batch_as_completed_jokes())
# 输出示例:
# Input 0 result: "Why don't bears wear shoes?\n\nBecause they have bear feet!"
# Input 1 result: "Why don't cats play poker in the wild?\n\nToo many cheetahs!"
# Input 2 result: "Why did the computer go to the doctor?\n\nBecause it had a virus!"

3. 声明方法

除了核心的同步和异步调用方法,BaseChatModel 还提供了一些声明方法,用于创建其他可运行对象(Runnable),扩展模型的功能。

3.1 bind_tools() 方法

描述: 创建一个可以调用工具(tools)的聊天模型。

签名:

bind_tools(tools: Sequence[Dict[str, Any] | type | Callable | BaseTool], **kwargs: Any) → Runnable[LanguageModelInput, BaseMessage]

参数:

  • tools (Sequence[Union[Dict[str, Any], type, Callable, BaseTool]]): 要绑定到模型的工具序列。
  • **kwargs (Any): 其他可选的关键字参数。

返回值:

  • Runnable[LanguageModelInput, BaseMessage]: 一个新的 Runnable 对象,可以调用指定的工具。

示例:

from langchain_core.runnables import RunnableLambda
from langchain_core.callbacks.manager import adispatch_custom_event
from langchain_core.tools import BaseTool@tool
def some_tool(x: int, y: str) -> dict:'''Some_tool.'''return {"x": x, "y": y}llm = ChatOpenAI(model_name="gpt-4")
structured_llm = llm.bind_tools(tools=[some_tool])result = structured_llm.invoke({"x": 1, "y": "2"})
print(result.content)
# 输出示例: '{"x": 1, "y": "2"}'
3.2 with_structured_output() 方法

描述: 创建一个包装器,使用指定的 schema 结构化模型输出。

签名:

with_structured_output(schema: Dict | type, *, include_raw: bool = False, **kwargs: Any) → Runnable[LanguageModelInput, Dict | BaseModel]

参数:

  • schema (Union[Dict, type]): 输出的 schema,可以是 JSON Schema、Pydantic 类等。
  • include_raw (bool): 是否包含原始模型响应。
  • **kwargs (Any): 其他可选的关键字参数。

返回值:

  • Runnable[LanguageModelInput, Union[Dict, BaseModel]]: 一个新的 Runnable 对象,输出将按照指定的 schema 进行结构化。

示例:

from pydantic import BaseModelclass AnswerWithJustification(BaseModel):'''An answer to the user question along with justification for the answer.'''answer: strjustification: strllm = ChatOpenAI(model_name="gpt-4", temperature=0)
structured_llm = llm.with_structured_output(AnswerWithJustification)result = structured_llm.invoke("What weighs more, a pound of bricks or a pound of feathers?")
print(result)
# 输出示例:
# AnswerWithJustification(
#     answer='They weigh the same.',
#     justification='Both a pound of bricks and a pound of feathers weigh one pound. The weight is the same, but the volume or density of the objects may differ.'
# )
3.3 with_retry() 方法

描述: 创建一个包装器,在调用模型时遇到异常时进行重试。

签名:

with_retry(*, retry_if_exception_type: tuple[type[BaseException], ...] = (Exception,), wait_exponential_jitter: bool = True, stop_after_attempt: int = 3) → Runnable[Input, Output]

参数:

  • retry_if_exception_type (tuple[type[BaseException], ...]): 要重试的异常类型。
  • wait_exponential_jitter (bool): 是否在重试之间添加抖动。
  • stop_after_attempt (int): 最大重试次数。

返回值:

  • Runnable[Input, Output]: 一个新的 Runnable 对象,具有重试机制。

示例:

from langchain_core.runnables import RunnableLambdacount = 0def _lambda(x: int) -> None:global countcount += 1if x == 1:raise ValueError("x is 1")else:passrunnable = RunnableLambda(_lambda)
try:runnable.with_retry(stop_after_attempt=2,retry_if_exception_type=(ValueError,),).invoke(1)
except ValueError:passassert count == 2
3.4 with_fallbacks() 方法

描述: 为 Runnable 添加回退机制,当原始 Runnable 调用失败时,依次尝试回退的 Runnable。

签名:

with_fallbacks(fallbacks: Sequence[Runnable[Input, Output]], *, exceptions_to_handle: tuple[type[BaseException], ...] = (Exception,), exception_key: Optional[str] = None) → RunnableWithFallbacksT[Input, Output]

参数:

  • fallbacks (Sequence[Runnable[Input, Output]]): 回退的 Runnable 序列。
  • exceptions_to_handle (tuple[type[BaseException], ...]): 要处理的异常类型。
  • exception_key (Optional[str]): 如果指定字符串,则将处理的异常作为输入的一部分传递给回退的 Runnable。

返回值:

  • RunnableWithFallbacksT[Input, Output]: 一个新的 Runnable 对象,具备回退机制。

示例:

from langchain_core.runnables import RunnableGeneratordef _generate_immediate_error(input: Iterator) -> Iterator[str]:raise ValueError()yield ""def _generate(input: Iterator) -> Iterator[str]:yield from "foo bar"runnable = RunnableGenerator(_generate_immediate_error).with_fallbacks([RunnableGenerator(_generate)]
)
print(''.join(runnable.stream({})))  # 输出: foo bar
3.5 configurable_fields() 方法

描述: 配置 Runnable 的特定字段,以便在运行时通过 RunnableConfig 进行配置。

签名:

configurable_fields(**kwargs: ConfigurableField | ConfigurableFieldSingleOption | ConfigurableFieldMultiOption) → RunnableSerializable

参数:

  • **kwargs (ConfigurableField | ConfigurableFieldSingleOption | ConfigurableFieldMultiOption): 要配置的字段。

返回值:

  • RunnableSerializable: 一个新的 Runnable 对象,具有可配置的字段。

示例:

from langchain_core.runnables import ConfigurableField
from langchain_openai import ChatOpenAImodel = ChatOpenAI(max_tokens=20).configurable_fields(max_tokens=ConfigurableField(id="output_token_number",name="Max tokens in the output",description="The maximum number of tokens in the output",)
)# 使用默认的 max_tokens = 20
print("max_tokens_20: ", model.invoke("tell me something about chess").content)# 配置 max_tokens = 200
print("max_tokens_200: ", model.with_config(configurable={"output_token_number": 200}
).invoke("tell me something about chess").content)
3.6 configurable_alternatives() 方法

描述: 为 Runnable 配置替代模型,以便在运行时通过 RunnableConfig 进行切换。

签名:

configurable_alternatives(which: ConfigurableField, *, default_key: str = 'default', prefix_keys: bool = False, **kwargs: Runnable[Input, Output] | Callable[[], Runnable[Input, Output]]) → RunnableSerializable

参数:

  • which (ConfigurableField): 用于选择替代模型的字段。
  • default_key (str): 默认使用的替代模型键。
  • prefix_keys (bool): 是否为键添加前缀。
  • **kwargs (Runnable[Input, Output] | Callable[[], Runnable[Input, Output]]): 替代模型的键值对。

返回值:

  • RunnableSerializable: 一个新的 Runnable 对象,具有可配置的替代模型。

示例:

from langchain_anthropic import ChatAnthropic
from langchain_core.runnables.utils import ConfigurableField
from langchain_openai import ChatOpenAImodel = ChatAnthropic(model_name="claude-3-sonnet-20240229"
).configurable_alternatives(ConfigurableField(id="llm"),default_key="anthropic",openai=ChatOpenAI()
)# 使用默认模型 ChatAnthropic
print(model.invoke("which organization created you?").content)# 切换到 ChatOpenAI 模型
print(model.with_config(configurable={"llm": "openai"}).invoke("which organization created you?").content
)
3.7 with_types() 方法

描述: 为 Runnable 绑定输入和输出的类型。

签名:

with_types(*, input_type: type[Input] | None = None, output_type: type[Output] | None = None) → Runnable[Input, Output]

参数:

  • input_type (type[Input] | None): 要绑定的输入类型。
  • output_type (type[Output] | None): 要绑定的输出类型。

返回值:

  • Runnable[Input, Output]: 一个新的 Runnable 对象,具有绑定的输入和输出类型。

示例:

from typing import List
from pydantic import BaseModelclass InputModel(BaseModel):topic: strclass OutputModel(BaseModel):joke: strstructured_llm = llm.with_types(input_type=InputModel, output_type=OutputModel)input_data = InputModel(topic="bears")
result = structured_llm.invoke(input_data)
print(result.joke)

4. 创建自定义聊天模型

要创建自定义的聊天模型,开发者需要继承 BaseChatModel 并实现其抽象方法和属性。

必要的方法和属性
方法/属性描述必须实现
_generate使用提示生成聊天结果。必须
_llm_type (property)唯一标识模型类型,用于日志记录。必须
_identifying_params (property)表示模型参数化的追踪信息。可选
_stream实现流式输出。可选
_agenerate实现原生异步方法。可选
_astream实现 _stream 的异步版本。可选
示例:自定义聊天模型
from langchain_core.language_models.chat_models import BaseChatModel
from langchain_core.runnables import RunnableConfig
from langchain_core.messages import BaseMessage
from typing import List, Anyclass CustomChatModel(BaseChatModel):@propertydef _llm_type(self) -> str:return "custom_chat_model"def _generate(self, prompt: str, stop: List[str] | None = None, **kwargs: Any) -> BaseMessage:# 自定义生成逻辑response = f"Custom response to: {prompt}"return BaseMessage(content=response)async def _agenerate(self, prompt: str, stop: List[str] | None = None, **kwargs: Any) -> BaseMessage:# 自定义异步生成逻辑response = f"Async custom response to: {prompt}"return BaseMessage(content=response)

5. 属性和参数

BaseChatModel 类提供了一系列属性和参数,用于定制模型的行为。

5.1 cache 参数

描述: 是否缓存模型的响应。

类型: BaseCache | bool | None

行为:

  • True: 使用全局缓存。
  • False: 不使用缓存。
  • None: 如果设置了全局缓存,则使用全局缓存,否则不使用。
  • BaseCache 实例: 使用提供的缓存实例。

注意: 当前不支持对流式方法进行缓存。

5.2 callback_manager 参数

描述: 回调管理器,用于添加到运行跟踪中。

类型: BaseCallbackManager | None

状态: 自版本 0.1.7 起已弃用,建议使用 callbacks 参数代替。

5.3 callbacks 参数

描述: 用于添加到运行跟踪中的回调。

类型: Callbacks = None

5.4 custom_get_token_ids 参数

描述: 可选的编码器,用于计数 token。

类型: Callable[[str], list[int]] | None

5.5 disable_streaming 参数

描述: 是否禁用模型的流式输出。

类型: bool | Literal['tool_calling']

行为:

  • True: 始终禁用流式输出,stream()astream() 将调用 invoke()ainvoke()
  • 'tool_calling': 仅在模型调用时使用 tools 关键字参数时禁用流式输出。
  • False (默认): 如果可用,则始终使用流式输出。
5.6 metadata 参数

描述: 要添加到运行跟踪中的元数据。

类型: dict[str, Any] | None

5.7 rate_limiter 参数

描述: 可选的速率限制器,用于限制请求数量。

类型: BaseRateLimiter | None

5.8 tags 参数

描述: 要添加到运行跟踪中的标签。

类型: list[str] | None

5.9 verbose 参数

描述: 是否打印响应文本。

类型: bool [Optional]


6. 辅助方法

6.1 get_num_tokens() 方法

描述: 获取文本中的 token 数量,适用于检查输入是否符合模型的上下文窗口限制。

签名:

get_num_tokens(text: str)int

参数:

  • text (str): 要计数的文本。

返回值:

  • int: 文本中的 token 数量。

示例:

num_tokens = model.get_num_tokens("Hello, how are you?")
print(num_tokens)
# 输出示例: 6
6.2 get_num_tokens_from_messages() 方法

描述: 获取消息列表中的 token 数量,用于检查输入是否符合模型的上下文窗口限制。

签名:

get_num_tokens_from_messages(messages: list[BaseMessage], tools: Sequence | None = None)int

参数:

  • messages (list[BaseMessage]): 要计数的消息列表。
  • tools (Sequence | None): 如果提供,将工具转换为工具 schema 进行计数。

返回值:

  • int: 消息中的 token 数量总和。

注意: 基础实现忽略了工具 schema。

示例:

from langchain_core.messages import BaseMessagemessages = [BaseMessage(content="Hello!"), BaseMessage(content="How can I assist you today?")]
num_tokens = model.get_num_tokens_from_messages(messages)
print(num_tokens)
# 输出示例: 9
6.3 get_token_ids() 方法

描述: 返回文本中 token 的有序 ID 列表。

签名:

get_token_ids(text: str)list[int]

参数:

  • text (str): 要转换为 token ID 的文本。

返回值:

  • list[int]: 文本中 token 的 ID 列表,按出现顺序排列。

示例:

token_ids = model.get_token_ids("Hello")
print(token_ids)
# 输出示例: [15496]

7. 示例代码

7.1 绑定监听器

描述: 通过 with_listeners() 方法,为 Runnable 绑定生命周期监听器,以在运行开始、结束或出错时执行特定的回调函数。

示例:

from langchain_core.runnables import RunnableLambda
from langchain_core.tracers.schemas import Run
import time
import asynciodef format_t(t):return time.strftime("%Y-%m-%dT%H:%M:%S", time.localtime(t))def test_runnable(time_to_sleep: int):time.sleep(time_to_sleep)async def fn_start(run_obj: Run):print(f"on start callback starts at {format_t(time.time())}")await asyncio.sleep(3)print(f"on start callback ends at {format_t(time.time())}")async def fn_end(run_obj: Run):print(f"on end callback starts at {format_t(time.time())}")await asyncio.sleep(2)print(f"on end callback ends at {format_t(time.time())}")runnable = RunnableLambda(test_runnable).with_listeners(on_start=fn_start,on_end=fn_end
)async def concurrent_runs():await asyncio.gather(runnable.ainvoke(2), runnable.ainvoke(3))asyncio.run(concurrent_runs())

输出示例:

on start callback starts at 2024-05-16T14:20:29
on start callback starts at 2024-05-16T14:20:29
on start callback ends at 2024-05-16T14:20:32
on start callback ends at 2024-05-16T14:20:32
Runnable[2s]: starts at 2024-05-16T14:20:32
Runnable[3s]: starts at 2024-05-16T14:20:32
Runnable[2s]: ends at 2024-05-16T14:20:34
on end callback starts at 2024-05-16T14:20:34
Runnable[3s]: ends at 2024-05-16T14:20:35
on end callback starts at 2024-05-16T14:20:35
on end callback ends at 2024-05-16T14:20:37
on end callback ends at 2024-05-16T14:20:39
7.2 重试机制

描述: 通过 with_retry() 方法,为 Runnable 添加重试机制,在遇到指定类型的异常时自动重试。

示例:

from langchain_core.runnables import RunnableLambdacount = 0def _lambda(x: int) -> None:global countcount += 1if x == 1:raise ValueError("x is 1")else:passrunnable = RunnableLambda(_lambda)
try:runnable.with_retry(stop_after_attempt=2,retry_if_exception_type=(ValueError,),).invoke(1)
except ValueError:passassert count == 2

解释:

  • 定义了一个简单的 Lambda 函数 _lambda,当输入为 1 时抛出 ValueError 异常。
  • 使用 with_retry() 方法配置最多重试 2 次,并指定仅对 ValueError 类型的异常进行重试。
  • 调用 invoke(1),由于输入为 1,会抛出异常并触发重试机制。
  • 最终,count 的值为 2,表明重试机制正常工作。
7.3 结构化输出

描述: 通过 with_structured_output() 方法,使用指定的 schema 结构化模型的输出,使其符合特定的数据结构。

示例:

from pydantic import BaseModelclass AnswerWithJustification(BaseModel):'''An answer to the user question along with justification for the answer.'''answer: strjustification: strllm = ChatModel(model="model-name", temperature=0)
structured_llm = llm.with_structured_output(AnswerWithJustification)result = structured_llm.invoke("What weighs more, a pound of bricks or a pound of feathers?")
print(result)
# 输出示例:
# AnswerWithJustification(
#     answer='They weigh the same.',
#     justification='Both a pound of bricks and a pound of feathers weigh one pound. The weight is the same, but the volume or density of the objects may differ.'
# )
7.4 并行批量处理

描述: 通过 RunnableParallel 实现并行处理多个 Runnable,提高处理效率。

示例:

from langchain_core.runnables import RunnableParallel
from langchain_core.prompts import ChatPromptTemplate
from langchain_openai import ChatOpenAImodel = ChatOpenAI()
chain1 = ChatPromptTemplate.from_template("tell me a joke about {topic}") | model
chain2 = ChatPromptTemplate.from_template("write a short (2 line) poem about {topic}") | model
combined = RunnableParallel(joke=chain1, poem=chain2)# 同步调用
result = combined.invoke({"topic": "bears"})
print(result)
# 输出示例:
# {
#     'joke': AIMessage(content="Sure, here's a bear-related joke for you:\n\nWhy did the bear bring a ladder to the bar?\n\nBecause he heard the drinks were on the house!"),
#     'poem': AIMessage(content="In wilderness they roam,\nMajestic strength, nature's throne.")
# }# 批量调用
batch_results = combined.batch([{"topic": "bears"}, {"topic": "cats"}])
for res in batch_results:print(res)
# 输出示例:
# {
#     'joke': AIMessage(content="Sure, here's a bear joke for you:\n\nWhy don't bears wear shoes?\n\nBecause they have bear feet!"),
#     'poem': AIMessage(content="Majestic bears roam,\nNature's strength, beauty shown.")
# }
# {
#     'joke': AIMessage(content="Why don't cats play poker in the wild?\n\nToo many cheetahs!"),
#     'poem': AIMessage(content="Whiskers dance, eyes aglow,\nCats embrace the night's gentle flow.")
# }

8. 总结

BaseChatModel 类是 LangChain 中构建聊天模型的基础类,提供了一系列核心和声明方法,支持同步和异步调用、流式处理、批量处理、重试机制、回退机制、结构化输出等功能。通过继承和扩展 BaseChatModel,开发者可以创建功能强大且灵活的自定义聊天模型,满足不同应用场景的需求。

关键要点:

  • 核心方法:包括 invoke(), ainvoke(), stream(), astream() 等,用于与模型进行同步和异步交互。
  • 声明方法:如 with_retry(), with_fallbacks(), with_structured_output() 等,用于增强模型的功能。
  • 扩展性:通过继承 BaseChatModel,开发者可以实现自定义的生成逻辑和模型行为。
  • 配置与定制:支持通过参数和方法配置模型的行为,如缓存、速率限制、标签、元数据等。

MessagePlaceholder

MessagesPlaceholder 在提示模板中占据一个位置,用于动态地插入传递给 invoke 方法的消息列表。在本例中,variable_name="messages" 表示占位符将被替换为 state 中键为 "messages" 的值。

相关文章:

langchain runnable

LangChain 文档详细解析 LangChain 是一个用于构建与语言模型(如GPT-4)交互的框架。本文档介绍了LangChain v0.1版本中的Runnable接口及其相关功能。 目录 Runnable接口输入和输出模式使用示例异步方法事件流并行处理 1. Runnable接口 为了简化自定义…...

nginx配置不缓存资源

方法1 location / {index index.html index.htm;add_header Cache-Control no-cache,no-store;try_files $uri $uri/ /index.html;#include mime.types;if ($request_filename ~* .*\.(htm|html)$) {add_header Cache-Control "private, no-store, no-cache, must-revali…...

Linux系统程序设计--4.进程

程序与进程 内核中的进程结构 task_struct(进程表项和进程控制块) 位于/usr/src/linux-headers-4.15.0-213-generic/include/linux/sched.h C程序启动过程 进程终止方式 进程终止函数 atexit 小案例 #include<stdio.h> #include<string.h> #include<stdlib…...

springboot/ssm网购平台管理系统Java在线购物商城管理平台web电商源码

springboot/ssm网购平台管理系统Java在线购物商城管理平台web电商源码 基于springboot(可改ssm)vue项目 开发语言&#xff1a;Java 框架&#xff1a;springboot/可改ssm vue JDK版本&#xff1a;JDK1.8&#xff08;或11&#xff09; 服务器&#xff1a;tomcat 数据库&…...

2024年Android面试总结

2024年Android面试总结 1.动画类型有哪些&#xff1f;插值器原理&#xff1f; 2.StringBuffer和StringBuilder区别&#xff1f; 3.jvm内存模型&#xff1f; 4.线程池7大核心参数及原理&#xff1f; 5.Android多进程通信方式有哪些&#xff1f;各自的优缺点&#xff1f; 6…...

UE5 slate BlankProgram独立程序系列

源码版Engine\Source\Programs\中copy BlankProgram文件夹&#xff0c;重命名为ASlateLearning&#xff0c;修改所有文件命名及内部名称。 ASlateLearning.Target.cs // Copyright Epic Games, Inc. All Rights Reserved.using UnrealBuildTool; using System.Collections.Ge…...

小米PC电脑手机互联互通,小米妙享,小米电脑管家,老款小米笔记本怎么使用,其他品牌笔记本怎么使用,一分钟教会你

说在前面 之前我们体验过妙享中心&#xff0c;里面就有互联互通的全部能力&#xff0c;现在有了小米电脑管家&#xff0c;老款的笔记本竟然用不了&#xff0c;也可以理解&#xff0c;毕竟老款笔记本做系统研发的时候没有预留适配的文件补丁&#xff0c;至于其他品牌的winPC小米…...

家庭智慧工程师:如何通过科技提升家居生活质量

在今天的数字化时代&#xff0c;家居生活已经不再只是简单的“住”的地方。随着物联网&#xff08;IoT&#xff09;、人工智能&#xff08;AI&#xff09;以及自动化技术的快速发展&#xff0c;越来越多的家庭开始拥抱智慧家居技术&#xff0c;将他们的家变得更加智能化、便捷和…...

云计算-华为HCIA-学习笔记

笔者今年7月底考取了华为云计算方向的HCIE认证&#xff0c;回顾从IA到IE的学习和项目实战&#xff0c;想整合和分享自己的学习历程&#xff0c;欢迎志同道合的朋友们一起讨论&#xff01; 第二章&#xff1a;服务器基础 服务器是什么&#xff1f; 服务器本质上就是个性能超强的…...

webgl threejs 云渲染(服务器渲染、后端渲染)解决方案

云渲染和流式传输共享三维模型场景 1、本地无需高端GPU设备即可提供三维项目渲染 云渲染和云流化媒体都可以让3D模型共享变得简单便捷。配备强大GPU的远程服务器早就可以处理密集的处理工作&#xff0c;而专有应用程序&#xff0c;用户也可以从任何个人设备查看全保真模型并与…...

【中间件】Redis

一、什么是Redis Redis是一个开源&#xff08;BSD许可&#xff09;&#xff0c;内存存储的数据结构服务器&#xff0c;可用作数据库&#xff0c;高速缓存和消息队列代理。它支持字符串、哈希表、列表、集合、有序集合&#xff0c;位图&#xff0c;hyperloglogs等数据类型。内置…...

请结合给定资料中的具体事例,谈谈你对“海洋的污染将毁灭鱼儿的家园,但让人类不寒而栗的毁灭绝非仅此而已!”这句话的理解。(10分)

题目 【2010年国考省级以上&#xff08;含副省级&#xff09;申论真题】2&#xff0e;请结合给定资料中的具体事例&#xff0c;谈谈你对“海洋的污染将毁灭鱼儿的家园&#xff0c;但让人类不寒而栗的毁灭绝非仅此而已&#xff01;”这句话的理解。&#xff08;10分&#xff09…...

Java SE 与 Java EE:基础与进阶的探索之旅

在编程世界中&#xff0c;Java语言以其跨平台、面向对象、丰富的类库等特点&#xff0c;成为了众多开发者和企业的首选编程语言。而Java SE与Java EE&#xff0c;作为Java平台的两个重要组成部分&#xff0c;各自承载着不同的使命&#xff0c;同时又紧密相连&#xff0c;共同构…...

PH热榜 | 2024-11-24

DevNow 是一个精简的开源技术博客项目模版&#xff0c;支持 Vercel 一键部署&#xff0c;支持评论、搜索等功能&#xff0c;欢迎大家体验。 在线预览 1. AutoFlow Studio 标语&#xff1a;借助简化的AI质检&#xff0c;更快发布产品&#xff0c;更聪明地进行测试。 介绍&…...

LLM 系列学习教程

LLM101 检查 Tokenizer 词表大小与 LLM 的 Embedding 和 LM_head 输入大小是否匹配对 SBert 进行训练、预测、评估使其进行相似度计算对 BERT 进行训练、预测、评估使其进行文本分类使用 CLIP 模型进行文本图像匹配对 JoinBERT 进行训练、预测使其进行对话意图和槽位联合识别对…...

基于yolov8、yolov5的茶叶等级检测识别系统(含UI界面、训练好的模型、Python代码、数据集)

摘要&#xff1a;茶叶等级检测在茶叶生产、质量控制和市场销售中起着至关重要的作用&#xff0c;不仅能帮助相关部门实时监测茶叶质量&#xff0c;还为智能化检测系统提供了可靠的数据支撑。本文介绍了一款基于YOLOv8、YOLOv5等深度学习框架的茶叶等级检测模型&#xff0c;该模…...

Excel求和如何过滤错误值

一、问题的提出 平时&#xff0c;我们在使用Excel时&#xff0c;最常用的功能就是求和了&#xff0c;一说到求和你可能想到用sum函数&#xff0c;但是如果sum的求和区域有#value #Div等错误值怎么办&#xff1f;如下图&#xff0c;记算C列中工资的总和。 直接用肯定会报错&…...

头文件包含

大家好&#xff0c;今天我们来聊聊头文件包含这方面的知识&#xff0c;并且在这里提出几个问题&#xff0c;头文件多次包含有什么影响吗&#xff1f;“”和〈〉这两种方式都能包含标准头文件吗&#xff1f; 一.文件包含 #include指令可以使另外一个文件被编译。就像它实际出现…...

37_U-Net网络详解

1.U-Net 网络概述 U-Net 是一种深度学习模型&#xff0c;广泛用于图像的语义分割任务。U-Net 网络的结构特别适合医学影像分割&#xff0c;尤其在少量训练数据的情况下表现优异。该网络由一个编码器-解码器架构组成&#xff0c;具有对称的“U”形结构&#xff0c;因此得名为 U…...

fastapi入门

好的&#xff0c;我将为您生成一个更详细、易于理解的 FastAPI 入门学习文档&#xff0c;特别是对复杂概念&#xff08;如依赖注入&#xff09;进行深入解释&#xff0c;帮助您在没有太多基础的情况下也能顺利学习和掌握 FastAPI。 FastAPI 入门学习文档 目录 简介环境搭建 2…...

RabbitMQ 之 死信队列

一、死信的概念 先从概念解释上搞清楚这个定义&#xff0c;死信&#xff0c;顾名思义就是无法被消费的消息&#xff0c;字面意思可以这样理 解&#xff0c;一般来说&#xff0c;producer 将消息投递到 broker 或者直接到 queue 里了&#xff0c;consumer 从 queue 取出消息进行…...

Android-如何实现Apng动画播放

01 Apng是什么 Apng&#xff08;Animated Portable Network Graphics&#xff09;顾名思义是基于 PNG 格式扩展的一种动画格式&#xff0c;增加了对动画图像的支持&#xff0c;同时加入了 24 位图像和8位 Alpha 透明度的支持&#xff0c;并且向下兼容 PNG。 Google封面图 02 A…...

微服务系统架构图

微服务架构是一种将单一应用程序开发为一组小型服务的架构风格。每个服务都在自己的进程中运行&#xff0c;它们之间采用轻量级的通信机制&#xff08;如 HTTP/REST 或消息队列&#xff09;进行相互协作。以下是关于微服务系统架构的简要介绍&#xff1a;一、核心特点独立部署 …...

04 —— Webpack打包CSS代码

加载器css-loader &#xff1a;解析css代码 webpack 中文文档 | webpack中文文档 | webpack中文网 加载器style-loader&#xff1a;把解析后的css代码插入到DOM style-loader | webpack 中文文档 | webpack中文文档 | webpack中文网 准备css代码&#xff0c;放到src/login目…...

【数据结构专栏】二叉搜索树(Binary Search Tree)的剖析?

文章目录 &#x1f9e8;前言1、二叉搜索树的基本概念&#xff1f;2、二叉搜索树的节点结构组成&#xff1f;3、二叉搜索树的插入操作&#xff1f;4、二叉搜索树的删除操作&#xff1f;5、二叉搜索树的遍历&#xff1f; 6、二叉搜索树的性能分析&#xff1f; &#x1f389;完整代…...

SSM全家桶 1.Maven

或许总要彻彻底底地绝望一次 才能重新再活一次 —— 24.11.20 maven在如今的idea中已经实现自动配置&#xff0c;不需要我们手动下载 一、Maven的简介和快速入门 Maven 是一款为 Java 项目构建管理、依赖管理的工具(软件)&#xff0c;使用 Maven 可以自动化构建测试、打包和发…...

前端三剑客(二):CSS

目录 1. CSS 基础 1.1 什么是 CSS 1.2 语法格式 1.3 引入方式 1.3.1 行内样式 1.3.2 内部样式 1.3.3 外部样式 1.4 CSS 编码规范 2. 选择器 2.1 标签选择器 2.2 id 选择器 2.3 class 选择器(类选择器) 2.4 复合选择器 2.5 通配符选择器 3. 常用 CSS 样式 3.1 c…...

解析html将表格插入word文档

用到依赖包 <dependency><groupId>org.jsoup</groupId><artifactId>jsoup</artifactId><version>1.15.2</version></dependency><dependency><groupId>org.aspectj</groupId><artifactId>aspectjweav…...

Java核心知识详解:String类、StringBuffer、数组及日期时间的全面解析

&#x1f680; 作者 &#xff1a;“码上有前” &#x1f680; 文章简介 &#xff1a;Java &#x1f680; 欢迎小伙伴们 点赞&#x1f44d;、收藏⭐、留言&#x1f4ac; 标题 Java核心知识详解&#xff1a;String类、StringBuffer、数组及日期时间的全面解析 摘要 在Java中…...

唯一设备序列号(UID)、唯一产品识别码(UPI)和备份寄存器BKP

文章目录 一、唯一设备序列号UID二、唯一产品识别码UPI三、备份寄存器BKP 一、唯一设备序列号UID MCU 系列产品内置两个不同长度的唯一设备序列号&#xff0c;分别为 96 位的 UID(Unique device ID)和 128 位的UCID(Unique Customer ID)&#xff0c;这两个设备序列号存放在闪存…...

Kafka - 消费者程序仅消费一半分区消息的问题

1. 问题描述 修改安全服务状态有时逻辑正常有时候逻辑不正常&#xff0c;排查incident服务的日志发现消息可以正常发送到 kafka topic &#xff0c;但是incident-cron 服务有时候有拉取消息的日志有时候没有日志。 kafka 生产者可以将消息正常发送到 kafka topic &#xff0c…...

养老院管理系统+小程序项目需求分析文档

智慧综合养老服务平台是以业务为牵引、场景为驱动&#xff0c;围绕“老人”业务域&#xff0c;持续沉淀和打磨形成适应不同养老业务发展需要的业务能力&#xff0c;推动业务模式升级&#xff0c;为养老服务提供数字化解决方案&#xff0c;并依托实体站点与养老机构实现线上线下…...

K8s 下通过prometheus监控 nginx

k8s 下有两个版本的nginx ingress 分别是 ingress nginx 以及 nginx ingress Ingress-nginx 与 Nginx-ingress - LeoZhanggg - 博客园 这里我讨论的是 nginx ingress Nginx Ingress 使用Prometheus 导出数据 nginx ingress 本身支持通过支持这个提供prometheus 格式的…...

基于SpringBoot的京东绿谷旅游信息服务平台设计与实现(源码+定制+开发)

博主介绍&#xff1a; ✌我是阿龙&#xff0c;一名专注于Java技术领域的程序员&#xff0c;全网拥有10W粉丝。作为CSDN特邀作者、博客专家、新星计划导师&#xff0c;我在计算机毕业设计开发方面积累了丰富的经验。同时&#xff0c;我也是掘金、华为云、阿里云、InfoQ等平台…...

使用Redis生成全局唯一id

为了生成一个符合要求的分布式全局ID&#xff0c;我们可以使用 StringRedisTemplate 来实现。这个ID由三部分组成&#xff1a; 符号位&#xff08;1 bit&#xff09;&#xff1a;始终为0&#xff0c;表示正数。时间戳&#xff08;31 bit&#xff09;&#xff1a;表示从某个起始…...

pytorch自定义算子导出onnx

文章目录 1、为什么要自定义算子&#xff1f;2、如何自定义算子3、自定义算子导出onnx4、example1、重写一个pytorch 自定义算子&#xff08;实现自定义激活函数&#xff09;2、现有算子上封装pytorch 自定义算子&#xff08;实现动态放大超分辨率模型&#xff09; 1、为什么要…...

从搭建uni-app+vue3工程开始

技术栈 uni-app、vue3、typescript、vite、sass、uview-plus、pinia、axios 一、项目搭建 1、创建以 typescript 开发的工程 npx degit dcloudio/uni-preset-vue#vite-ts my-vue3-project2、安装sass npm install -D sass// 安装sass-loader&#xff0c;注意需要版本10&…...

波点音乐自动点击

波点音乐 import uiautomator2 as u2 import time import sys import os# 动态点击时间&#xff0c;打印剩余时间 def dynamic_sleep(seconds):wait_time secondsfor i in range(wait_time):print(f"Waiting... {wait_time - i} seconds remaining")sys.stdout.flu…...

【一篇搞定配置】wget 下载与安装(Window)

&#x1f308; 个人主页&#xff1a;十二月的猫-CSDN博客 &#x1f525; 系列专栏&#xff1a; &#x1f3c0;各种软件安装与配置_十二月的猫的博客-CSDN博客 &#x1f4aa;&#x1f3fb; 十二月的寒冬阻挡不了春天的脚步&#xff0c;十二点的黑夜遮蔽不住黎明的曙光 目录 1.…...

2025年春招修订版《C/C++笔面试系列》(1) C语言经典笔面试题(上)

C语言是嵌入式开发的常用语言&#xff0c;也是主要语言&#xff0c;很多企业在招聘嵌入式软件工程师时&#xff0c;C语言的熟练程度是一个重要考察点。笔试也是以C语言为主&#xff0c;所以想要拿到面试机会&#xff0c;还得通过C语言笔试&#xff0c;本专题总结了各大企业C语言…...

【042C】基于51RFID门禁系统(LCD12864显示)【Proteus仿真+Keil程序+报告+原理图】

☆、设计硬件组成&#xff1a;51单片机最小系统RFID读卡器4*4矩阵键盘AT24C02存储芯片LCD12864液晶显示继电器蜂鸣器LED灯。 1、设计采用STC89C52、AT89C52、AT89S52作为主控芯片&#xff0c;采用LCD12864液晶显示屏实时显示门禁系统&#xff1b; 2、系统集成两种解锁方式&am…...

scratch二次开发:blockly工作区垃圾桶和进度条的隐藏和显示

大家好&#xff0c;我是小黄。 本期给大家介绍的内容是实现blockly工作区的垃圾桶和进度条的显示和隐藏实现。 本次基于的项目源码大家可以关注小黄回复垃圾桶自行获取。 一.垃圾桶的显示和实现。 在blockly中&#xff0c;我们进行块的删除的时候最常用的两种方法是&#xf…...

【STM32】MPU6050初始化常用寄存器说明及示例代码

一、MPU6050常用配置寄存器 1、电源管理寄存器1&#xff08; PWR_MGMT_1 &#xff09; 此寄存器允许用户配置电源模式和时钟源。 DEVICE_RESET &#xff1a;用于控制复位的比特位。设置为1时复位 MPU6050&#xff0c;内部寄存器恢复为默认值&#xff0c;复位结束…...

LDR6020驱动的Type-C接口显示器解决方案

一、引言 随着科技的飞速发展&#xff0c;Type-C接口凭借其高速数据传输、强大的电力传输能力以及便捷的正反可插设计&#xff0c;正逐渐成为现代电子设备的主流接口标准。在显示器领域&#xff0c;Type-C接口的引入不仅简化了线缆连接&#xff0c;还为用户带来了更丰富的功能…...

Spring Boot + Android 实现登录功能

在移动互联网的今天&#xff0c;许多应用需要通过移动端实现与服务器的交互功能&#xff0c;其中登录是最常见且基础的一种功能。通过登录&#xff0c;用户可以获得独特的身份标识&#xff0c;从而访问特定的资源或服务。本篇博客将详细介绍如何使用 Spring Boot 和 Android 实…...

【通俗理解】边际化技巧在概率论中的应用——从公式到实例

【通俗理解】边际化技巧在概率论中的应用——从公式到实例 关键词提炼 #边际化技巧 #概率论 #联合概率 #条件概率 #积分计算 #概率分布 #贝叶斯推断 第一节&#xff1a;边际化技巧的类比与核心概念【尽可能通俗】 边际化技巧&#xff0c;就像是你在一个复杂的概率迷宫中&am…...

Chen_AdaMV-MoE_Adaptive_Multi-Task_Vision_Mixture-of-Experts 译文

摘要 稀疏激活的专家混合&#xff08;MoE&#xff09;正在成为多任务学习&#xff08;MTL&#xff09;的一个有前途的范例。 MoE 不是将多个任务的知识压缩到单个模型中&#xff0c;而是分离参数空间&#xff0c;仅利用给定任务类型及其输入的相关模型片段&#xff0c;从而提供…...

多线程下使用数据库 - 20241124

问题 并发性较低&#xff0c;每秒千次但是较高一致性&#xff0c;比如利用数据库中的数据进行判断是否执行某个操作 存在的问题是&#xff0c;如何只锁定判断相关的数据&#xff0c;而不影响数据库操作无关数据。脏读/不可重复读/幻读 解决方案 利用数据InnoDB引擎的LBCC和…...

GMAN解读(论文+代码)

一、注意力机制 注意力机制与传统的卷积神经网络不同的是&#xff0c;前者擅长捕获全局依赖和长程关系&#xff0c;权重会动态调整。而后者对于所有特征都使用同一个卷积核。关于更多注意力机制内容&#xff0c;详见&#xff1a; 注意力机制、自注意力机制、多头注意力机制、通…...

《文件操作》

一 . 文本文件和二进制文件 根据数据的组织形式&#xff0c;数据文件被分为了二进制文件和文本文件 数据在内存中是以二进制的形式存储&#xff0c;如果不加转换的输出到外存的文件中&#xff0c;就是二进制文件。 如果要求在外存上以ASCII 码的形式存储&#xff0c;则需要再存…...