mlflow.langchain
- mlflow.langchain.autolog(disable=False, exclusive=False, disable_for_unsupported_versions=False, silent=False, log_traces=True, run_tracer_inline=False)[source]
注意
自动日志记录已确认兼容以下包版本:
0.3.12<=langchain<=1.1.3。当使用此范围之外的包版本时,自动日志记录可能不会成功。启用(或禁用)并配置从 Langchain 到 MLflow 的自动日志记录。
- 参数
disable – 如果为
True,则禁用 Langchain 自动日志记录集成。如果为False,则启用 Langchain 自动日志记录集成。exclusive – 如果为
True,则自动记录的内容不会记录到用户创建的流畅运行中。如果为False,则自动记录的内容将记录到活动的流畅运行中,该运行可能是用户创建的。disable_for_unsupported_versions – 如果为
True,则禁用与此 MLflow 客户端版本未经测试或不兼容的 langchain 版本进行自动日志记录。silent – 如果为
True,则在 Langchain 自动日志记录期间抑制 MLflow 的所有事件日志和警告。如果为False,则在 Langchain 自动日志记录期间显示所有事件和警告。log_traces – 如果为
True,则通过使用 MlflowLangchainTracer 作为推理过程中的回调来记录 Langchain 模型的跟踪。如果为False,则在推理过程中不收集跟踪。默认为True。run_tracer_inline – 如果为
True,MLflow 跟踪器回调将在主异步任务中运行,而不是被卸载到线程池。这可确保在异步场景(例如 LangGraph 的ainvoke)中将自动跟踪与手动@mlflow.trace装饰器结合使用时,实现正确的上下文传播。出于向后兼容性的考虑,默认为False。如果您在 LangGraph 节点或工具中使用手动@mlflow.trace装饰器,并且需要将它们正确嵌套在自动跟踪中,请将其设置为True。
- mlflow.langchain.load_model(model_uri, dst_path=None)[source]
注意
“langchain” MLflow Models 集成已确认兼容
0.3.12<=langchain<=1.1.3。当使用此范围之外的包版本时,MLflow Models 与 langchain 的集成可能不会成功。从本地文件或运行加载 LangChain 模型。
- 参数
model_uri –
MLflow 模型在 URI 格式中的位置。例如:
/Users/me/path/to/local/modelrelative/path/to/local/models3://my_bucket/path/to/modelruns:/<mlflow_run_id>/run-relative/path/to/model
有关支持的 URI 方案的更多信息,请参阅 引用 Artifacts。
dst_path – The local filesystem path to which to download the model artifact. This directory must already exist. If unspecified, a local output path will be created.
- 返回
LangChain 模型实例。
- mlflow.langchain.log_model(lc_model, artifact_path: str | None = None, conda_env=None, code_paths=None, registered_model_name=None, signature: mlflow.models.signature.ModelSignature = None, input_example: Union[pandas.core.frame.DataFrame, numpy.ndarray, dict, list, csr_matrix, csc_matrix, str, bytes, tuple] = None, await_registration_for=300, pip_requirements=None, extra_pip_requirements=None, metadata=None, loader_fn=None, persist_dir=None, run_id=None, model_config=None, streamable=None, resources: list[mlflow.models.resources.Resource] | str | None = None, prompts: list[str | Prompt] | None = None, name: str | None = None, params: dict[str, typing.Any] | None = None, tags: dict[str, typing.Any] | None = None, model_type: str | None = None, step: int = 0, model_id: str | None = None)[source]
注意
“langchain” MLflow Models 集成已确认兼容
0.3.12<=langchain<=1.1.3。当使用此范围之外的包版本时,MLflow Models 与 langchain 的集成可能不会成功。将 LangChain 模型记录为当前运行的 MLflow 工件。
- 参数
lc_model –
LangChain 模型,可以是 Chain、Agent 或 retriever,或者包含上述类型的LangChain 模型代码 <https://github.com/mlflow/mlflow/blob/master/examples/langchain/chain_as_code_driver.py> 的路径。使用模型作为路径时,请务必使用
mlflow.models.set_model()进行设置。注意
实验性:将模型作为路径使用可能会在未来版本中更改或移除,恕不另行通知。
artifact_path – Deprecated. Use name instead.
conda_env –
Conda 环境的字典表示形式或 Conda 环境 yaml 文件的路径。如果提供,这将描述模型应运行的环境。至少,它应指定 get_default_conda_env() 中包含的依赖项。如果为
None,则将包含由mlflow.models.infer_pip_requirements()推断出的 pip 依赖项的 Conda 环境添加到模型中。如果依赖项推断失败,它将回退到使用 get_default_pip_requirements。从conda_env中的 pip 依赖项将写入 piprequirements.txt文件,而完整的 Conda 环境将写入conda.yaml。以下是 Conda 环境的字典表示形式的示例{ "name": "mlflow-env", "channels": ["conda-forge"], "dependencies": [ "python=3.8.15", { "pip": [ "langchain==x.y.z" ], }, ], }
code_paths –
A list of local filesystem paths to Python file dependencies (or directories containing file dependencies). These files are prepended to the system path when the model is loaded. Files declared as dependencies for a given model should have relative imports declared from a common root path if multiple files are defined with import dependencies between them to avoid import errors when loading the model.
For a detailed explanation of
code_pathsfunctionality, recommended usage patterns and limitations, see the code_paths usage guide.registered_model_name – 如果提供,则在
registered_model_name下创建一个模型版本,如果给定名称的注册模型不存在,也会创建该注册模型。signature –
ModelSignature描述了模型的输入和输出Schema。如果未指定,则模型签名将根据 lc_model.input_keys 和 lc_model.output_keys 作为列名,并以 DataType.string 作为列类型进行设置。或者,您可以显式指定模型签名。模型签名可以从具有有效模型输入的(例如,省略目标列的训练数据集)和有效模型输出的(例如,在训练数据集上生成的模型预测)数据集推断,例如from mlflow.models import infer_signature chain = LLMChain(llm=llm, prompt=prompt) prediction = chain.run(input_str) input_columns = [ {"type": "string", "name": input_key} for input_key in chain.input_keys ] signature = infer_signature(input_columns, predictions)
input_example – 一个或多个有效的模型输入实例。输入示例用作要馈送给模型的数据的提示。它将被转换为 Pandas DataFrame,然后使用 Pandas 的面向拆分(split-oriented)格式序列化为 json,或者转换为 numpy 数组,其中示例将通过转换为列表来序列化为 json。字节将进行 base64 编码。当
signature参数为None时,输入示例用于推断模型签名。await_registration_for – 等待模型版本完成创建并处于
READY状态的秒数。默认情况下,函数等待五分钟。指定 0 或 None 可跳过等待。pip_requirements – pip 依赖项字符串的可迭代对象(例如
["langchain", "-r requirements.txt", "-c constraints.txt"])或本地文件系统上 pip 依赖项文件的字符串路径(例如"requirements.txt")。如果提供,这将描述模型应运行的环境。如果为None,则将通过mlflow.models.infer_pip_requirements()从当前软件环境中推断出默认依赖项列表。如果依赖项推断失败,它将回退到使用 get_default_pip_requirements。依赖项和约束都会被自动解析并分别写入模型部分的requirements.txt和constraints.txt文件,并作为模型的一部分进行存储。依赖项也会被写入模型 Conda 环境(conda.yaml)文件的pip部分。extra_pip_requirements –
pip 依赖项字符串的可迭代对象(例如
["pandas", "-r requirements.txt", "-c constraints.txt"])或本地文件系统上 pip 依赖项文件的字符串路径(例如"requirements.txt")。如果提供,这将描述附加到根据用户当前软件环境自动生成的默认 pip 依赖项集合的其他 pip 依赖项。依赖项和约束都会被自动解析并分别写入模型部分的requirements.txt和constraints.txt文件,并作为模型的一部分进行存储。依赖项也会被写入模型 Conda 环境(conda.yaml)文件的pip部分。警告
以下参数不能同时指定
conda_envpip_requirementsextra_pip_requirements
此示例演示了如何使用
pip_requirements和extra_pip_requirements指定 pip requirements。metadata – 传递给模型并存储在 MLmodel 文件中的自定义元数据字典。
loader_fn –
对于包含 LangChain 未能本机序列化的对象的模型,需要此函数。此函数以字符串 persist_dir 作为参数,并返回模型所需的特定对象。根据模型,这可能是检索器、向量存储、requests_wrapper、embeddings 或数据库。对于 RetrievalQA Chain 和检索器模型,该对象是(retriever)。对于 APIChain 模型,它是(requests_wrapper)。对于 HypotheticalDocumentEmbedder 模型,它是(embeddings)。对于 SQLDatabaseChain 模型,它是(database)。
persist_dir –
存储对象的目录。loader_fn 以此字符串作为参数来加载对象。对于包含 LangChain 未能本机序列化的对象的模型,此参数是可选的。MLflow 将此目录中的内容作为工件记录在名为 persist_dir_data 的子目录中。
以下是使用 loader_fn 和 persist_dir 记录 RetrievalQA 链的代码片段
注意
在 langchain_community >= 0.0.27 中,加载 pickled 数据需要提供
allow_dangerous_deserialization参数。qa = RetrievalQA.from_llm(llm=OpenAI(), retriever=db.as_retriever()) def load_retriever(persist_directory): embeddings = OpenAIEmbeddings() vectorstore = FAISS.load_local( persist_directory, embeddings, # you may need to add the line below # for langchain_community >= 0.0.27 allow_dangerous_deserialization=True, ) return vectorstore.as_retriever() with mlflow.start_run() as run: logged_model = mlflow.langchain.log_model( qa, name="retrieval_qa", loader_fn=load_retriever, persist_dir=persist_dir, )
请参阅 examples/langchain/retrieval_qa_chain.py 中的完整示例。
run_id – 要与此模型版本关联的 run_id。如果指定,我们将恢复该运行并向其记录模型。否则,将创建一个新运行。默认为 None。
model_config –
从代码保存模型时要应用于模型的模型配置。此配置在模型加载期间可用。
注意
Experimental: This parameter may change or be removed in a future release without warning. (实验性:此参数可能在未来的版本中更改或移除,恕不另行通知。)
streamable – 指示模型是否支持流式预测的布尔值。如果为 True,模型必须实现 stream 方法。如果为 None,如果模型实现 stream 方法,则 streamable 设置为 True。默认为 None。
resources – 模型资源列表或包含服务模型所需资源列表的 resources.yaml 文件。如果记录具有依赖项(例如,依赖于 LLM 模型服务终结点)的 LangChain 模型,我们建议通过此参数显式传递依赖项。否则,
log_model将尝试推断依赖项,但依赖项自动推断是尽力而为,并且可能遗漏某些依赖项。prompts –
与模型关联的 MLflow 提示注册表中已注册的提示 URI 列表。每个提示 URI 格式应为
prompt:/<name>/<version>。应在将提示与模型关联之前在 MLflow 提示注册表中注册这些提示。这将创建模型和提示之间的双向链接。关联的提示可以在 MLmodel 文件中存储的模型元数据中看到。从提示注册表 UI,您也可以导航到模型。
import mlflow prompt_template = "Hi, {name}! How are you doing today?" # Register a prompt in the MLflow Prompt Registry mlflow.prompts.register_prompt("my_prompt", prompt_template, description="A simple prompt") # Log a model with the registered prompt with mlflow.start_run(): model_info = mlflow.pyfunc.log_model( name=MyModel(), name="model", prompts=["prompt:/my_prompt/1"] ) print(model_info.prompts) # Output: ['prompt:/my_prompt/1'] # Load the prompt prompt = mlflow.genai.load_prompt(model_info.prompts[0])
name – 模型名称。
params – 要与模型一起记录的参数字典。
tags – 要与模型一起记录的标签字典。
model_type – 模型的类型。
step – 记录模型输出和指标的步骤
model_id – 模型的 ID。
- 返回
一个
ModelInfo实例,其中包含已记录模型的元数据。
- mlflow.langchain.save_model(lc_model, path, conda_env=None, code_paths=None, mlflow_model=None, signature: mlflow.models.signature.ModelSignature = None, input_example: Union[pandas.core.frame.DataFrame, numpy.ndarray, dict, list, csr_matrix, csc_matrix, str, bytes, tuple] = None, pip_requirements=None, extra_pip_requirements=None, metadata=None, loader_fn=None, persist_dir=None, model_config=None, streamable: bool | None = None)[source]
注意
“langchain” MLflow Models 集成已确认兼容
0.3.12<=langchain<=1.1.3。当使用此范围之外的包版本时,MLflow Models 与 langchain 的集成可能不会成功。将 LangChain 模型保存到本地文件系统的路径。
- 参数
lc_model –
LangChain 模型,可以是 Chain、Agent、retriever 或 RunnableSequence,或者包含上述类型的LangChain 模型代码 <https://github.com/mlflow/mlflow/blob/master/examples/langchain/chain_as_code_driver.py> 的路径。使用模型作为路径时,请务必使用
mlflow.models.set_model()进行设置。注意
实验性:将模型作为路径使用可能会在未来版本中更改或移除,恕不另行通知。
path – 要将序列化模型(YAML 格式)保存到的本地路径。
conda_env –
Conda 环境的字典表示形式或 Conda 环境 yaml 文件的路径。如果提供,这将描述模型应运行的环境。至少,它应指定 get_default_conda_env() 中包含的依赖项。如果为
None,则将包含由mlflow.models.infer_pip_requirements()推断出的 pip 依赖项的 Conda 环境添加到模型中。如果依赖项推断失败,它将回退到使用 get_default_pip_requirements。从conda_env中的 pip 依赖项将写入 piprequirements.txt文件,而完整的 Conda 环境将写入conda.yaml。以下是 Conda 环境的字典表示形式的示例{ "name": "mlflow-env", "channels": ["conda-forge"], "dependencies": [ "python=3.8.15", { "pip": [ "langchain==x.y.z" ], }, ], }
code_paths –
A list of local filesystem paths to Python file dependencies (or directories containing file dependencies). These files are prepended to the system path when the model is loaded. Files declared as dependencies for a given model should have relative imports declared from a common root path if multiple files are defined with import dependencies between them to avoid import errors when loading the model.
For a detailed explanation of
code_pathsfunctionality, recommended usage patterns and limitations, see the code_paths usage guide.mlflow_model – 要添加此 flavor 的
mlflow.models.Model。signature –
ModelSignature描述了模型的输入和输出Schema。如果未指定,则模型签名将根据 lc_model.input_keys 和 lc_model.output_keys 作为列名,并以 DataType.string 作为列类型进行设置。或者,您可以显式指定模型签名。模型签名可以从具有有效模型输入的(例如,省略目标列的训练数据集)和有效模型输出的(例如,在训练数据集上生成的模型预测)数据集推断,例如from mlflow.models import infer_signature chain = LLMChain(llm=llm, prompt=prompt) prediction = chain.run(input_str) input_columns = [ {"type": "string", "name": input_key} for input_key in chain.input_keys ] signature = infer_signature(input_columns, predictions)
input_example – 一个或多个有效的模型输入实例。输入示例用作要馈送给模型的数据的提示。它将被转换为 Pandas DataFrame,然后使用 Pandas 的面向拆分(split-oriented)格式序列化为 json,或者转换为 numpy 数组,其中示例将通过转换为列表来序列化为 json。字节将进行 base64 编码。当
signature参数为None时,输入示例用于推断模型签名。pip_requirements – pip 依赖项字符串的可迭代对象(例如
["langchain", "-r requirements.txt", "-c constraints.txt"])或本地文件系统上 pip 依赖项文件的字符串路径(例如"requirements.txt")。如果提供,这将描述模型应运行的环境。如果为None,则将通过mlflow.models.infer_pip_requirements()从当前软件环境中推断出默认依赖项列表。如果依赖项推断失败,它将回退到使用 get_default_pip_requirements。依赖项和约束都会被自动解析并分别写入模型部分的requirements.txt和constraints.txt文件,并作为模型的一部分进行存储。依赖项也会被写入模型 Conda 环境(conda.yaml)文件的pip部分。extra_pip_requirements –
pip 依赖项字符串的可迭代对象(例如
["pandas", "-r requirements.txt", "-c constraints.txt"])或本地文件系统上 pip 依赖项文件的字符串路径(例如"requirements.txt")。如果提供,这将描述附加到根据用户当前软件环境自动生成的默认 pip 依赖项集合的其他 pip 依赖项。依赖项和约束都会被自动解析并分别写入模型部分的requirements.txt和constraints.txt文件,并作为模型的一部分进行存储。依赖项也会被写入模型 Conda 环境(conda.yaml)文件的pip部分。警告
以下参数不能同时指定
conda_envpip_requirementsextra_pip_requirements
此示例演示了如何使用
pip_requirements和extra_pip_requirements指定 pip requirements。metadata – 传递给模型并存储在 MLmodel 文件中的自定义元数据字典。
loader_fn –
对于包含 LangChain 未能本机序列化的对象的模型,需要此函数。此函数以字符串 persist_dir 作为参数,并返回模型所需的特定对象。根据模型,这可能是检索器、向量存储、requests_wrapper、embeddings 或数据库。对于 RetrievalQA Chain 和检索器模型,该对象是(retriever)。对于 APIChain 模型,它是(requests_wrapper)。对于 HypotheticalDocumentEmbedder 模型,它是(embeddings)。对于 SQLDatabaseChain 模型,它是(database)。
persist_dir –
存储对象的目录。loader_fn 以此字符串作为参数来加载对象。对于包含 LangChain 未能本机序列化的对象的模型,此参数是可选的。MLflow 将此目录中的内容作为工件记录在名为 persist_dir_data 的子目录中。
以下是使用 loader_fn 和 persist_dir 记录 RetrievalQA 链的代码片段
注意
在 langchain_community >= 0.0.27 中,加载 pickled 数据需要提供
allow_dangerous_deserialization参数。qa = RetrievalQA.from_llm(llm=OpenAI(), retriever=db.as_retriever()) def load_retriever(persist_directory): embeddings = OpenAIEmbeddings() vectorstore = FAISS.load_local( persist_directory, embeddings, # you may need to add the line below # for langchain_community >= 0.0.27 allow_dangerous_deserialization=True, ) return vectorstore.as_retriever() with mlflow.start_run() as run: logged_model = mlflow.langchain.log_model( qa, name="retrieval_qa", loader_fn=load_retriever, persist_dir=persist_dir, )
请参阅 examples/langchain/retrieval_qa_chain.py 中的完整示例。
model_config –
从代码保存模型时要应用于模型的模型配置。此配置在模型加载期间可用。
注意
Experimental: This parameter may change or be removed in a future release without warning. (实验性:此参数可能在未来的版本中更改或移除,恕不另行通知。)
streamable – 指示模型是否支持流式预测的布尔值。如果为 True,模型必须实现 stream 方法。如果为 None,如果模型实现 stream 方法,则 streamable 设置为 True。默认为 None。
- class mlflow.langchain.chat_agent_langgraph.ChatAgentState[source]
辅助类,用于构建一个 LangGraph Agent,该 Agent 在状态更新时生成 ChatAgent 兼容的消息。其他 ChatAgent 请求字段(custom_inputs、context)和响应字段(custom_outputs)在状态中也暴露出来,以便在 Agent 执行过程中使用和更新。请将此类与
ChatAgentToolNode一起使用。LangGraph ChatAgent 示例
此示例已测试,可与 LangGraph 0.2.70 一起使用。
步骤 1:创建 LangGraph Agent
此示例改编自 LangGraph 的 create_react_agent 文档。主要区别在于对 ChatAgent 兼容性的修改。这些修改包括:
我们使用
ChatAgentState,它有一个ChatAgentMessage对象内部状态,以及底层custom_outputs属性。我们使用
ChatAgentToolNode而不是 LangGraph 的 ToolNode,以支持从 LangChain 和 UnityCatalog 工具返回附件和 custom_outputs。
from typing import Optional, Sequence, Union from langchain_core.language_models import LanguageModelLike from langchain_core.runnables import RunnableConfig, RunnableLambda from langchain_core.tools import BaseTool from langgraph.graph import END, StateGraph from langgraph.graph.state import CompiledStateGraph from langgraph.prebuilt import ToolNode from mlflow.langchain.chat_agent_langgraph import ChatAgentState, ChatAgentToolNode def create_tool_calling_agent( model: LanguageModelLike, tools: Union[ToolNode, Sequence[BaseTool]], agent_prompt: Optional[str] = None, ) -> CompiledStateGraph: model = model.bind_tools(tools) def routing_logic(state: ChatAgentState): last_message = state["messages"][-1] if last_message.get("tool_calls"): return "continue" else: return "end" if agent_prompt: system_message = {"role": "system", "content": agent_prompt} preprocessor = RunnableLambda( lambda state: [system_message] + state["messages"] ) else: preprocessor = RunnableLambda(lambda state: state["messages"]) model_runnable = preprocessor | model def call_model( state: ChatAgentState, config: RunnableConfig, ): response = model_runnable.invoke(state, config) return {"messages": [response]} workflow = StateGraph(ChatAgentState) workflow.add_node("agent", RunnableLambda(call_model)) workflow.add_node("tools", ChatAgentToolNode(tools)) workflow.set_entry_point("agent") workflow.add_conditional_edges( "agent", routing_logic, { "continue": "tools", "end": END, }, ) workflow.add_edge("tools", "agent") return workflow.compile()
步骤 2:定义 LLM 和您的工具
如果您想从工具中返回附件和 custom_outputs,可以返回一个包含“content”、“attachments”和“custom_outputs”键的字典。此字典将由 ChatAgentToolNode 解析,并正确存储在您的 LangGraph 状态中。
from random import randint from typing import Any from databricks_langchain import ChatDatabricks from langchain_core.tools import tool @tool def generate_random_ints(min: int, max: int, size: int) -> dict[str, Any]: """Generate size random ints in the range [min, max].""" attachments = {"min": min, "max": max} custom_outputs = [randint(min, max) for _ in range(size)] content = f"Successfully generated array of {size} random ints in [{min}, {max}]." return { "content": content, "attachments": attachments, "custom_outputs": {"random_nums": custom_outputs}, } mlflow.langchain.autolog() tools = [generate_random_ints] llm = ChatDatabricks(endpoint="databricks-meta-llama-3-3-70b-instruct") langgraph_agent = create_tool_calling_agent(llm, tools)
步骤 3:包装您的 LangGraph Agent 与 ChatAgent
这使得您的 Agent 可以轻松地使用 serving 中的 PyFunc flavor 进行日志记录和部署。
from typing import Any, Generator, Optional from langgraph.graph.state import CompiledStateGraph from mlflow.pyfunc import ChatAgent from mlflow.types.agent import ( ChatAgentChunk, ChatAgentMessage, ChatAgentResponse, ChatContext, ) class LangGraphChatAgent(ChatAgent): def __init__(self, agent: CompiledStateGraph): self.agent = agent def predict( self, messages: list[ChatAgentMessage], context: Optional[ChatContext] = None, custom_inputs: Optional[dict[str, Any]] = None, ) -> ChatAgentResponse: request = {"messages": self._convert_messages_to_dict(messages)} messages = [] for event in self.agent.stream(request, stream_mode="updates"): for node_data in event.values(): messages.extend( ChatAgentMessage(**msg) for msg in node_data.get("messages", []) ) return ChatAgentResponse(messages=messages) def predict_stream( self, messages: list[ChatAgentMessage], context: Optional[ChatContext] = None, custom_inputs: Optional[dict[str, Any]] = None, ) -> Generator[ChatAgentChunk, None, None]: request = {"messages": self._convert_messages_to_dict(messages)} for event in self.agent.stream(request, stream_mode="updates"): for node_data in event.values(): yield from ( ChatAgentChunk(**{"delta": msg}) for msg in node_data["messages"] ) chat_agent = LangGraphChatAgent(langgraph_agent)
步骤 4:测试您的模型
使用 ChatAgentRequest 架构的字典调用
.predict()和.predict_stream。chat_agent.predict({"messages": [{"role": "user", "content": "What is 10 + 10?"}]}) for event in chat_agent.predict_stream( {"messages": [{"role": "user", "content": "Generate me a few random nums"}]} ): print(event)
此 LangGraph ChatAgent 可以使用
ChatAgent的 docstring 中“Logging a ChatAgent”部分的日志记录代码进行记录。
- class mlflow.langchain.chat_agent_langgraph.ChatAgentToolNode(*args: Any, **kwargs: Any)[source]
辅助类,使 ToolNodes 与
ChatAgentState兼容。从 LangGraph 工具的字符串输出中解析attachments和custom_outputs键。
- class mlflow.langchain.output_parsers.ChatAgentOutputParser(*args: Any, name: str | None = None)[source]
OutputParser,它将字符串输出包装成
ChatAgentResponse或ChatAgentChunk的字典表示形式,以便于互操作。