### Environment Setup and Project Start Source: https://tbice123123.github.io/langchain-dev-utils/zh/resource/example-project Steps to set up the environment by copying the example .env file and starting the project using 'langgraph dev'. ```bash cp .env.example .env # Edit .env file with your API keys (ZhipuAI and Tavily) langgraph dev ``` -------------------------------- ### Start the Project Source: https://tbice123123.github.io/langchain-dev-utils/zh/resource/example-project_q= Command to launch the Langchain-dev-utils example project after setting up dependencies and environment variables. This command initiates the agent systems. ```bash langgraph dev ``` -------------------------------- ### Clone Repository and Install Dependencies Source: https://tbice123123.github.io/langchain-dev-utils/zh/resource/example-project Instructions to clone the project repository and install its dependencies using uv. ```bash git clone https://github.com/TBice123123/langchain-dev-utils-example.git cd langchain-dev-utils-example uv sync ``` -------------------------------- ### Setup Environment Variables Source: https://tbice123123.github.io/langchain-dev-utils/zh/resource/example-project_q= Instructions to copy the example environment file and fill in necessary API keys for ZhipuAI and Tavily. This step is crucial for the project to function correctly. ```bash cp .env.example .env ``` -------------------------------- ### Registering Model Providers (Python) Source: https://tbice123123.github.io/langchain-dev-utils/zh/resource/example-project Example of registering custom model providers using register_model_provider. This is crucial for customizing chat and embedding models. ```python # Example for chat models from langchain_dev_utils.providers.chat_models import register_model_provider # Inside register_all_model_providers function: register_model_provider(...) # Example for embeddings from langchain_dev_utils.providers.embeddings import register_embeddings_provider # Inside register_all_embeddings_providers function: register_embeddings_provider(...) ``` -------------------------------- ### Format Prompt (Python) Source: https://tbice123123.github.io/langchain-dev-utils/zh/resource/example-project_q= Applies the `format_prompt` middleware, which is used for formatting prompts. This is a common step in preparing user input for agent interaction. ```python from langchain_dev_utils.middleware import format_prompt # Example usage within an agent or chain # prompt_formatter = format_prompt() def format_prompt(): # Middleware logic for formatting prompts pass ``` -------------------------------- ### Wrap Agents as Tool (Python) Source: https://tbice123123.github.io/langchain-dev-utils/zh/resource/example-project_q= Demonstrates the `wrap_all_agents_as_tool` function, used for creating multi-agent systems where individual agents are wrapped as tools for a supervisor agent. ```python from langchain_dev_utils.agents import wrap_all_agents_as_tool # Example: Wrapping multiple agents to be used by a supervisor # tools = wrap_all_agents_as_tool([agent1, agent2]) def wrap_all_agents_as_tool(agents): # Implementation to wrap agents as tools pass ``` -------------------------------- ### Run Agent Orchestration Examples (Python) Source: https://tbice123123.github.io/langchain-dev-utils/zh/adavance-guide/graph Provides example code to invoke the constructed graph with different queries. It demonstrates how the system handles both single-intent and mixed-intent queries, triggering parallel execution for the latter. ```python # 示例 1:单一意图(产品查询) response = graph.invoke({"query": "你好,我要查询一下之前购买的产品"}) print(response["final_answer"]) # 示例 2:混合意图(产品查询 + 退款政策),将触发并行执行 response = graph.invoke({"query": "推荐一款适合通勤的无线耳机并看看库存;同时,告诉我你们商品的退款政策?"}) print(response["final_answer"]) ``` -------------------------------- ### Format Sequence (Python) Source: https://tbice123123.github.io/langchain-dev-utils/zh/resource/example-project_q= Utilizes the `format_sequence` utility for formatting sequences, likely used in preparing input for language models or agent processing. ```python from langchain_dev_utils.common import format_sequence # Example: Formatting a sequence of messages # formatted_messages = format_sequence([HumanMessage(content="Hello"), AIMessage(content="Hi there!")]) def format_sequence(sequence): # Implementation for formatting sequences pass ``` -------------------------------- ### Handoff Agent Middleware (Python) Source: https://tbice123123.github.io/langchain-dev-utils/zh/resource/example-project_q= Utilizes the `HandoffAgentMiddleware` for managing agent handoffs in a sequential or conditional manner. This is key for the Handoffs Architecture. ```python from langchain_dev_utils.middleware import HandoffAgentMiddleware # Example: Applying the middleware to an agent or chain # agent_with_handoff = HandoffAgentMiddleware(agent) class HandoffAgentMiddleware: def __init__(self, agent): # Initialization logic pass # ... methods for handling handoffs ... ``` -------------------------------- ### Run Example Invocations (Python) Source: https://tbice123123.github.io/langchain-dev-utils/zh/adavance-guide/graph_q= Provides example code to invoke the constructed Langchain graph with different user queries. It demonstrates how the graph handles both single-intent queries and multi-intent queries that trigger parallel execution. ```python # 示例 1:单一意图(产品查询) response = graph.invoke({"query": "你好,我要查询一下之前购买的产品"}) print(response["final_answer"]) # 示例 2:混合意图(产品查询 + 退款政策),将触发并行执行 response = graph.invoke({"query": "推荐一款适合通勤的无线耳机并看看库存;同时,告诉我你们商品的退款政策?"}) print(response["final_answer"]) ``` -------------------------------- ### Supervisor Agent Custom Tools (Python) Source: https://tbice123123.github.io/langchain-dev-utils/zh/resource/example-project Guidance on adding custom tools for the main Supervisor agent. Tools should be defined in a separate file and passed to the create_agent function. ```python # src/agents/supervisor/tools.py def custom_supervisor_tool(task: str): """A custom tool for the supervisor agent.""" # Implementation details... pass # src/agents/supervisor/agent.py # ... import custom_supervisor_tool ... # ... pass custom_supervisor_tool to create_agent function ... ``` -------------------------------- ### Supervisor Agent Sub-Agent Tools (Python) Source: https://tbice123123.github.io/langchain-dev-utils/zh/resource/example-project Tools available for sub-agents within the Supervisor-Multi-Agent architecture. Custom tools can be added here. ```python # src/agents/supervisor/subagent/tools.py def custom_subagent_tool(query: str): """A custom tool for sub-agents.""" # Implementation details... pass ``` -------------------------------- ### Handoffs Architecture Tools (Python) Source: https://tbice123123.github.io/langchain-dev-utils/zh/resource/example-project Tools used across all agents in the Handoffs Architecture. New tools can be added directly to this file for specific agents. ```python # src/agents/handoffs/tools.py def specific_handoff_tool(input_data: str): """A tool for a specific agent in the handoffs architecture.""" # Implementation details... pass ``` -------------------------------- ### Define Handoffs Architecture Tools (Python) Source: https://tbice123123.github.io/langchain-dev-utils/zh/resource/example-project_q= Provides tool implementations for agents within the 'handoffs' architecture. Each agent can have its own set of tools for specific responsibilities. ```python from langchain_core.tools import tool @tool def process_data(data: str): """Process input data.""" # Implementation for data processing return f"Processed: {data}" @tool def analyze_results(results: str): """Analyze the results of a task.""" # Implementation for result analysis return f"Analysis: {results}" ``` -------------------------------- ### Format System Prompt with f-string Style (Python) Source: https://tbice123123.github.io/langchain-dev-utils/zh/adavance-guide/middleware/format Demonstrates using the global `format_prompt` instance for f-string style system prompts. Variables are resolved from the agent's state. Ensure `langchain-dev-utils` is installed. ```python from langchain_dev_utils.agents.middleware import format_prompt from langchain.agents import AgentState from langchain_core.messages import HumanMessage # Assuming create_agent is defined elsewhere and works with AgentState # class AssistantState(AgentState): # name: str # Placeholder for create_agent function for demonstration def create_agent(**kwargs): class MockAgent: def invoke(self, data, context=None): system_prompt = kwargs.get('system_prompt', '') state_name = data.get('name', 'default_name') context_user = getattr(context, 'user', 'default_user') formatted_prompt = system_prompt.format(name=state_name, user=context_user) return {"formatted_system_prompt": formatted_system_prompt, "input_data": data, "context_data": context} return MockAgent() class AssistantState(AgentState): name: str agent = create_agent( model="vllm:qwen2.5-7b", system_prompt="你是一个智能助手,你的名字叫做{name}。", middleware=[format_prompt], state_schema=AssistantState, ) # Calling the agent, providing 'name' in the state response = agent.invoke( {"messages": [HumanMessage(content="你好啊")], "name": "assistant"} ) print(response) ``` -------------------------------- ### Single Agent Tools (Python) Source: https://tbice123123.github.io/langchain-dev-utils/zh/resource/example-project Implementation of tools for the Single Agent architecture, including functions for persisting and retrieving user memory. ```python # src/agents/simple_agent/tools.py def save_user_memory(user_id: str, memory: str): """Persists user memory.""" # Implementation details... pass def get_user_memory(user_id: str): """Retrieves user memory.""" # Implementation details... pass ``` -------------------------------- ### Define Simple Agent Tools (Python) Source: https://tbice123123.github.io/langchain-dev-utils/zh/resource/example-project_q= Shows the implementation of tools for the 'simple-agent', including `save_user_memory` and `get_user_memory`. These tools enable persistent memory for the agent. ```python from langchain_core.tools import tool @tool def save_user_memory(memory: str): """Persist user memory.""" # Implementation to save memory print(f"Saving memory: {memory}") @tool def get_user_memory() -> str: """Retrieve user memory.""" # Implementation to retrieve memory return "Previous memory content" ``` -------------------------------- ### Using PlanMiddleware for Task Planning with Langchain Agents Source: https://tbice123123.github.io/langchain-dev-utils/zh/adavance-guide/middleware/plan Demonstrates how to integrate PlanMiddleware into a Langchain agent to handle task planning. It shows the initialization of the agent with the middleware and provides an example of invoking the agent with a user request for planning a trip. ```python from langchain_dev_utils.agents.middleware import PlanMiddleware from langchain_core.messages import HumanMessage # Assuming create_agent is a function that sets up a Langchain agent # For demonstration purposes, we'll mock it or assume its existence. # In a real scenario, you would import and use your actual agent creation function. def create_agent(**kwargs): # This is a placeholder for the actual agent creation logic. # It should return an object with an 'invoke' method. class MockAgent: def invoke(self, input): print(f"MockAgent invoked with: {input}") # Simulate a response return {"messages": [HumanMessage(content="Planning response...")]} return MockAgent() agent = create_agent( model="openai:gpt-4o", middleware=[ PlanMiddleware( custom_plan_tool_descriptions={ "write_plan": "用于写计划,将任务拆解为多个有序的子任务。", "finish_sub_plan": "用于完成子任务,更新子任务状态为已完成。", "read_plan": "用于查询当前的任务规划列表。" }, use_read_plan_tool=True, # If you don't use the read plan tool, set this to False ) ], ) response = agent.invoke( {"messages": [HumanMessage(content="我要去New York玩几天,帮我规划行程")]} ) print(response) ``` -------------------------------- ### Load Chat Model (Python) Source: https://tbice123123.github.io/langchain-dev-utils/zh/resource/example-project_q= Illustrates how to load a chat model using `load_chat_model`. This function supports keyword arguments for model-specific configurations, enhancing flexibility. ```python from langchain_dev_utils.providers import load_chat_model # Example: Loading a chat model with specific parameters # chat_model = load_chat_model("openai_compatible", model="glm-5", api_key="YOUR_API_KEY") def load_chat_model(provider_name: str, **kwargs): # Logic to load the chat model based on provider_name and kwargs pass ``` -------------------------------- ### Format Prompt with Jinja2 Style using `FormatPromptMiddleware` Source: https://tbice123123.github.io/langchain-dev-utils/zh/adavance-guide/middleware/format_q= Shows how to use `FormatPromptMiddleware` for Jinja2 style templating in system prompts, enabling complex logic like loops and conditionals. This requires installing `langchain-dev-utils[standard]` and manually instantiating the middleware. ```python from langchain_dev_utils.agents.middleware import FormatPromptMiddleware from dataclasses import dataclass from typing import Optional from langchain_core.messages import HumanMessage @dataclass class Context: user_role: Optional[str] = None # 用户角色,例如 "VIP", "Admin" # 手动实例化中间件,指定格式为 jinja2 jinja2_formatter = FormatPromptMiddleware(template_format="jinja2") # Assuming create_agent is defined elsewhere # agent = create_agent( # model="vllm:qwen2.5-7b", # # 使用 {{ }} 语法 # system_prompt=( # "你是一个智能助手。\n" # "{% if user_role == 'VIP' %}" # "请务必提供尊贵、周到的服务。\n" # "{% elif user_role == 'Admin' %}" # "请展示系统管理员的权限和严谨性。\n" # "{% else %}" # "请提供标准的用户服务。\n" # "{% endif %}" # ), # middleware=[jinja2_formatter], # context_schema=Context, # ) # # 示例 1:普通用户 # response = agent.invoke( # {"messages": [HumanMessage(content="你好")]}, # context=Context(user_role="Guest"), # ) # # 示例 2:VIP 用户 # # 系统提示词将包含 "请务必提供尊贵、周到的服务" # response = agent.invoke( # {"messages": [HumanMessage(content="你好")]}, # context=Context(user_role="VIP"), # ) ``` -------------------------------- ### Load Embeddings (Python) Source: https://tbice123123.github.io/langchain-dev-utils/zh/resource/example-project_q= Demonstrates loading an embeddings model using `load_embeddings`. This function facilitates the retrieval of embedding models for tasks like semantic search. ```python from langchain_dev_utils.providers import load_embeddings # Example: Loading an embeddings model # embeddings = load_embeddings("openai_compatible", api_key="YOUR_API_KEY") def load_embeddings(provider_name: str, **kwargs): # Logic to load the embeddings model pass ``` -------------------------------- ### Loading Chat and Embedding Models (Python) Source: https://tbice123123.github.io/langchain-dev-utils/zh/resource/example-project Demonstrates how to load chat and embedding models using load_chat_model and load_embeddings. It highlights the use of keyword arguments for flexibility. ```python # Example for chat models from langchain_dev_utils.providers.chat_models import load_chat_model # Load a specific model with potential extra parameters chat_model = load_chat_model(model_name="glm-5", temperature=0.7, api_key="YOUR_API_KEY") # Example for embeddings from langchain_dev_utils.providers.embeddings import load_embeddings # Load an embedding model embeddings = load_embeddings(model_name="text-embedding-ada-002", api_key="YOUR_API_KEY") ``` -------------------------------- ### Register Embeddings Provider (Python) Source: https://tbice123123.github.io/langchain-dev-utils/zh/resource/example-project_q= Shows the process of registering a custom embeddings provider using `register_embeddings_provider`. Similar to model providers, this allows integration of various embedding models. ```python from langchain_dev_utils.providers import register_embeddings_provider # Example: Registering a hypothetical embeddings provider # register_embeddings_provider("my_embedding_provider", MyEmbeddingModel) def register_all_embeddings_providers(): # Existing registrations... pass ``` -------------------------------- ### Initialize HandoffAgentMiddleware with Agent Configuration Source: https://tbice123123.github.io/langchain-dev-utils/zh/adavance-guide/middleware/handoffs_q= Demonstrates how to initialize the HandoffAgentMiddleware with the agent configuration. This middleware is then passed to the `create_agent` function, enabling multi-agent capabilities. The example shows a basic invocation with a human message. ```python from langchain_dev_utils.agents.middleware import HandoffAgentMiddleware agent = create_agent( model="vllm:qwen2.5-7b", middleware=[HandoffAgentMiddleware(agents_config=agent_config)], ) response = agent.invoke({"messages": [HumanMessage(content="当前时间是多少?")]}) print(response) ``` -------------------------------- ### LangChain Agent and Model Integration with vLLM Source: https://tbice123123.github.io/langchain-dev-utils/zh/index Demonstrates how to register an OpenAI-Compatible model provider (vLLM), load a chat model dynamically using a string, and create an agent with tools. This example showcases the library's ability to simplify model management and agent creation. ```python from langchain.tools import tool from langchain_core.messages import HumanMessage from langchain_dev_utils.chat_models import register_model_provider, load_chat_model from langchain_dev_utils.agents import create_agent # Register model provider register_model_provider("vllm", "openai-compatible", base_url="http://localhost:8000/v1") @tool def get_current_weather(location: str) -> str: """获取指定地点的当前天气""" return f"25度,{location}" # Dynamically load model using string model = load_chat_model("vllm:qwen2.5-7b") response = model.invoke("你好") print(response) # Create agent agent = create_agent("vllm:qwen2.5-7b", tools=[get_current_weather]) response = agent.invoke({"messages": [HumanMessage(content="今天纽约的天气如何?")]}) print(response) ``` -------------------------------- ### Direct Tool Calling with Langchain Source: https://tbice123123.github.io/langchain-dev-utils/zh/adavance-guide/openai-compatible/chat Demonstrates how to enable direct tool calling when a model supports it using the `bind_tools` method. This example shows a simple tool to get the current timestamp. ```python from langchain_core.messages import HumanMessage from langchain_core.tools import tool import datetime @tool def get_current_time() -> str: """获取当前时间戳""" return str(datetime.datetime.now().timestamp()) model = ChatVLLM(model="qwen2.5-7b").bind_tools([get_current_time]) response = model.invoke([HumanMessage("获取当前时间戳")]) print(response) ``` -------------------------------- ### Parallel Tool Calls in Langchain Source: https://tbice123123.github.io/langchain-dev-utils/zh/adavance-guide/openai-compatible/chat_q= Explains how to enable parallel tool calls by setting `parallel_tool_calls=True` in the `bind_tools` method. This allows the model to invoke multiple tools simultaneously if the underlying model supports it. The example shows a tool for getting weather information. ```python from langchain_core.messages import HumanMessage from langchain_core.tools import tool @tool def get_current_weather(location: str) -> str: """获取当前天气""" return f"当前{location}的天气是晴朗" model = ChatVLLM(model="qwen2.5-7b").bind_tools( [get_current_weather], parallel_tool_calls=True ) response = model.invoke([HumanMessage("获取洛杉矶和伦敦的天气")]) print(response) ``` -------------------------------- ### Structured Output with Pydantic Models in Langchain Source: https://tbice123123.github.io/langchain-dev-utils/zh/adavance-guide/openai-compatible/chat_q= Shows how to use `with_structured_output` to get model responses in a structured format, specifically using Pydantic models. The example defines a `User` model and invokes the chat model with a message containing user information, expecting a structured output. ```python from langchain_core.messages import HumanMessage from pydantic import BaseModel class User(BaseModel): name: str age: int model = ChatVLLM(model="qwen2.5-7b").with_structured_output(User) response = model.invoke([HumanMessage("你好,我叫张三,今年25岁")]) print(response) ``` -------------------------------- ### Chat Model Usage Examples Source: https://tbice123123.github.io/langchain-dev-utils/zh/adavance-guide/openai-compatible/chat_q= Provides examples of how to use the created chat model for various invocation methods, including standard invocation, asynchronous invocation, streaming, and asynchronous streaming. ```APIDOC ## Chat Model Invocation ### Description Examples demonstrating how to invoke the created chat model using different methods. ### Methods #### 1. Standard Invocation (`invoke`) ```python from langchain_core.messages import HumanMessage from langchain_dev_utils.chat_models.adapters import create_openai_compatible_model # Assuming ChatVLLM is created as shown previously ChatVLLM = create_openai_compatible_model( model_provider="vllm", base_url="http://localhost:8000/v1", chat_model_cls_name="ChatVLLM" ) model = ChatVLLM(model="qwen2.5-7b") response = model.invoke([HumanMessage("Hello")]) print(response) ``` #### 2. Asynchronous Invocation (`ainvoke`) ```python import asyncio from langchain_core.messages import HumanMessage from langchain_dev_utils.chat_models.adapters import create_openai_compatible_model # Assuming ChatVLLM is created as shown previously ChatVLLM = create_openai_compatible_model( model_provider="vllm", base_url="http://localhost:8000/v1", chat_model_cls_name="ChatVLLM" ) async def main(): model = ChatVLLM(model="qwen2.5-7b") response = await model.ainvoke([HumanMessage("Hello")]) print(response) asyncio.run(main()) ``` #### 3. Streaming Invocation (`stream`) ```python from langchain_core.messages import HumanMessage from langchain_dev_utils.chat_models.adapters import create_openai_compatible_model # Assuming ChatVLLM is created as shown previously ChatVLLM = create_openai_compatible_model( model_provider="vllm", base_url="http://localhost:8000/v1", chat_model_cls_name="ChatVLLM" ) model = ChatVLLM(model="qwen2.5-7b") for chunk in model.stream([HumanMessage("Hello")]): print(chunk) ``` #### 4. Asynchronous Streaming Invocation (`astream`) ```python import asyncio from langchain_core.messages import HumanMessage from langchain_dev_utils.chat_models.adapters import create_openai_compatible_model # Assuming ChatVLLM is created as shown previously ChatVLLM = create_openai_compatible_model( model_provider="vllm", base_url="http://localhost:8000/v1", chat_model_cls_name="ChatVLLM" ) async def main(): model = ChatVLLM(model="qwen2.5-7b") async for chunk in model.astream([HumanMessage("Hello")]): print(chunk) asyncio.run(main()) ``` ### Streaming Output Options Streaming output can include token usage information by setting `stream_options={"include_usage": True}`. This is enabled by default. To disable it, pass `include_usage=False` in the `compatibility_options` when creating the model class. ``` -------------------------------- ### Using PlanMiddleware for Task Planning with Custom Tools Source: https://tbice123123.github.io/langchain-dev-utils/zh/adavance-guide/middleware/plan_q= This example demonstrates how to integrate PlanMiddleware into a Langchain agent. It shows the initialization of the middleware with custom descriptions for plan-related tools (`write_plan`, `finish_sub_plan`, `read_plan`) and enables the read plan tool. The agent is then invoked with a user's request to plan a trip, showcasing the middleware's capability to decompose and manage the task. ```python from langchain_dev_utils.agents.middleware import PlanMiddleware from langchain_core.messages import HumanMessage # Assuming create_agent is a function that sets up the agent with middleware # from your_agent_library import create_agent # Placeholder for create_agent function for demonstration purposes def create_agent(**kwargs): class MockAgent: def invoke(self, input_data): print("Mock agent invoked with:", input_data) # Simulate a response that might include a plan or task execution details return {"response": "Planning your trip to New York..."} return MockAgent() agent = create_agent( model="openai:gpt-4o", middleware=[ PlanMiddleware( custom_plan_tool_descriptions={ "write_plan": "用于写计划,将任务拆解为多个有序的子任务。", "finish_sub_plan": "用于完成子任务,更新子任务状态为已完成。", "read_plan": "用于查询当前的任务规划列表。" }, use_read_plan_tool=True, # If you don't want to use the read plan tool, set this to False ) ], ) response = agent.invoke( {"messages": [HumanMessage(content="我要去New York玩几天,帮我规划行程")]} ) print(response) ``` -------------------------------- ### Variable Override Example with f-string (Python) Source: https://tbice123123.github.io/langchain-dev-utils/zh/adavance-guide/middleware/format Demonstrates how variables defined in `state` take precedence over variables with the same name in `context` when using f-string formatting. Requires `langchain-dev-utils`. ```python from langchain_dev_utils.agents.middleware import format_prompt from langchain.agents import AgentState from langchain_core.messages import HumanMessage from dataclasses import dataclass @dataclass class Context: name: str # context defines 'name' user: str # Assuming create_agent is defined elsewhere and works with AgentState and Context # class AssistantState(AgentState): # name: str # state also defines 'name' # Placeholder for create_agent function for demonstration def create_agent(**kwargs): class MockAgent: def invoke(self, data, context=None): system_prompt = kwargs.get('system_prompt', '') state_name = data.get('name', 'default_name') context_user = getattr(context, 'user', 'default_user') context_name = getattr(context, 'name', 'default_context_name') # Simple formatting logic to show override formatted_prompt = system_prompt.replace('{name}', state_name).replace('{user}', context_user) return {"formatted_system_prompt": formatted_prompt, "input_data": data, "context_data": context} return MockAgent() class AssistantState(AgentState): name: str agent = create_agent( model="vllm:qwen2.5-7b", system_prompt="你是一个智能助手,你的名字叫做{name}。你的使用者叫做{user}。", middleware=[format_prompt], state_schema=AssistantState, context_schema=Context, ) # Calling the agent, providing 'name' in both state and context response = agent.invoke( { "messages": [HumanMessage(content="你叫什么名字?")], "name": "assistant-1", # This value should be used }, context=Context(name="assistant-2", user="张三"), # This value should be overridden ) # The final system prompt will be "你是一个智能助手,你的名字叫做assistant-1。你的使用者叫做张三。" # because state has higher priority print(response) ``` -------------------------------- ### 预处理智能体输入 (pre_input_hooks) Source: https://tbice123123.github.io/langchain-dev-utils/zh/adavance-guide/multi-agent 通过 `pre_input_hooks` 在智能体运行前对输入进行预处理。这可以用于输入增强、上下文注入等。钩子函数可以接收原始请求和 `ToolRuntime` 对象,并返回处理后的输入。支持同步函数、异步函数或两者的元组作为钩子。 ```python from langchain.tools import ToolRuntime from langchain_dev_utils.agents import wrap_agent_as_tool def process_input(request: str, runtime: ToolRuntime) -> str: original_user_message = next( message for message in runtime.state["messages"] if message.type == "human" ) prompt = ( "你正在协助处理以下用户询问:\n\n" f"{original_user_message.text}\n\n" "你被分配了以下子任务:\n\n" f"{request}" ) return prompt # 假设 agent 已定义 # agent = ... call_agent_tool = wrap_agent_as_tool(agent, pre_input_hooks=process_input) ``` -------------------------------- ### Format System Prompt with Jinja2 Style (Python) Source: https://tbice123123.github.io/langchain-dev-utils/zh/adavance-guide/middleware/format Demonstrates using `FormatPromptMiddleware` for Jinja2 style system prompts, enabling complex logic like conditional statements. Requires `langchain-dev-utils[standard]`. ```python from langchain_dev_utils.agents.middleware import FormatPromptMiddleware from langchain.agents import AgentState from langchain_core.messages import HumanMessage from dataclasses import dataclass from typing import Optional @dataclass class Context: user_role: Optional[str] = None # e.g., "VIP", "Admin" # Placeholder for create_agent function for demonstration def create_agent(**kwargs): class MockAgent: def invoke(self, data, context=None): system_prompt_template = kwargs.get('system_prompt', '') # Simulate Jinja2 rendering user_role = getattr(context, 'user_role', 'Guest') prompt_body = system_prompt_template if '{{% if user_role == "VIP" %}}' in prompt_body: if user_role == 'VIP': prompt_body = prompt_body.replace('{% if user_role == \'VIP\' %}\n请务必提供尊贵、周到的服务。\n{% elif user_role == \'Admin\' %}\n请展示系统管理员的权限和严谨性。\n{% else %}\n请提供标准的用户服务。\n{% endif %}', '请务必提供尊贵、周到的服务。') elif user_role == 'Admin': prompt_body = prompt_body.replace('{% if user_role == \'VIP\' %}\n请务必提供尊贵、周到的服务。\n{% elif user_role == \'Admin\' %}\n请展示系统管理员的权限和严谨性。\n{% else %}\n请提供标准的用户服务。\n{% endif %}', '请展示系统管理员的权限和严谨性。') else: prompt_body = prompt_body.replace('{% if user_role == \'VIP\' %}\n请务必提供尊贵、周到的服务。\n{% elif user_role == \'Admin\' %}\n请展示系统管理员的权限和严谨性。\n{% else %}\n请提供标准的用户服务。\n{% endif %}', '请提供标准的用户服务。') return {"formatted_system_prompt": prompt_body.strip(), "input_data": data, "context_data": context} return MockAgent() # Manually instantiate the middleware, specifying Jinja2 format jinja2_formatter = FormatPromptMiddleware(template_format="jinja2") agent = create_agent( model="vllm:qwen2.5-7b", # Using {{ }} syntax for Jinja2 system_prompt=( "你是一个智能助手。\n" "{% if user_role == 'VIP' %}" "请务必提供尊贵、周到的服务。\n" "{% elif user_role == 'Admin' %}" "请展示系统管理员的权限和严谨性。\n" "{% else %}" "请提供标准的用户服务。\n" "{% endif %}" ), middleware=[jinja2_formatter], context_schema=Context, ) # Example 1: Regular user response_guest = agent.invoke( {"messages": [HumanMessage(content="你好")]}, context=Context(user_role="Guest"), ) print("Guest Response:", response_guest) # Example 2: VIP user # The system prompt will include "请务必提供尊贵、周到的服务" response_vip = agent.invoke( {"messages": [HumanMessage(content="你好")]}, context=Context(user_role="VIP"), ) print("VIP Response:", response_vip) # Example 3: Admin user response_admin = agent.invoke( {"messages": [HumanMessage(content="你好")]}, context=Context(user_role="Admin"), ) print("Admin Response:", response_admin) ``` -------------------------------- ### Batch Register Embedding Providers (Python) Source: https://tbice123123.github.io/langchain-dev-utils/zh/api-reference/embeddings_q= Allows for the registration of multiple embedding model providers in a single call. It accepts a list of EmbeddingProvider configurations, simplifying the setup process for multiple providers. ```python def batch_register_embeddings_provider( providers: list[EmbeddingProvider] ) -> None: """Batches register embedding model providers.""" pass # Example Usage: batch_register_embeddings_provider([ {"provider_name": "fakeembeddings", "embeddings_model": FakeEmbeddings}, {"provider_name": "vllm", "embeddings_model": "openai-compatible", "base_url": "http://localhost:8000/v1"}, ]) ``` -------------------------------- ### 后处理智能体输出 (post_output_hooks) Source: https://tbice123123.github.io/langchain-dev-utils/zh/adavance-guide/multi-agent 通过 `post_output_hooks` 在智能体运行完成后对其输出进行后处理,生成工具的最终返回值。钩子函数接收原始输入、代理返回的响应和 `ToolRuntime` 对象,并返回可序列化的字符串或 `Command` 对象。支持同步函数、异步函数或两者的元组作为钩子。 ```python import json from langchain.tools import ToolRuntime from langchain_dev_utils.agents import wrap_agent_as_tool def process_output(request: str, response: dict[str, Any], runtime: ToolRuntime) -> str: return json.dumps( { "status": "success", "event_id": "evt_123", "summary": response["messages"][-1].text, } ) # 假设 agent 已定义 # agent = ... call_agent_tool = wrap_agent_as_tool(agent, post_output_hooks=process_output) ``` -------------------------------- ### Execute Parallel Graph Source: https://tbice123123.github.io/langchain-dev-utils/zh/adavance-guide/graph Provides an example of how to invoke the created parallel graph with a user's message. The graph processes the input concurrently through the defined agents and returns the combined response. ```python response = graph.invoke( {"messages": [HumanMessage("我想买一副无线耳机,数量2,收货地址X市X区X路X号")]} ) print(response) ``` -------------------------------- ### Format Prompt with f-string Style using `format_prompt` Source: https://tbice123123.github.io/langchain-dev-utils/zh/adavance-guide/middleware/format_q= Demonstrates using the global `format_prompt` instance for f-string style variable formatting in system prompts. Variables are resolved first from `state` and then from `context`. This is the recommended approach for most scenarios. ```python from langchain_dev_utils.agents.middleware import format_prompt from langchain.agents import AgentState from langchain_core.messages import HumanMessage # Assuming create_agent is defined elsewhere and works with AgentState # class AssistantState(AgentState): # name: str # agent = create_agent( # model="vllm:qwen2.5-7b", # system_prompt="你是一个智能助手,你的名字叫做{name}。", # middleware=[format_prompt], # state_schema=AssistantState, # ) # # 调用时,必须为 state 提供 'name' 的值 # response = agent.invoke( # {"messages": [HumanMessage(content="你好啊")], "name": "assistant"} # ) # print(response) ``` -------------------------------- ### Deploy Qwen2.5-VL-7B with vLLM Source: https://tbice123123.github.io/langchain-dev-utils/zh/adavance-guide/openai-compatible/overview_q= This command deploys the Qwen2.5-VL-7B-Instruct model using vLLM, enabling OpenAI-compatible API access for vision-language tasks. It includes the `--trust-remote-code` flag for custom code execution. The model is served on host 0.0.0.0 and port 8000 with the served model name 'qwen2.5-vl-7b'. ```bash vllm serve Qwen/Qwen2.5-VL-7B-Instruct \ --trust-remote-code \ --host 0.0.0.0 --port 8000 \ --served-model-name qwen2.5-vl-7b ``` -------------------------------- ### Standard Usage of ToolCallRepairMiddleware Source: https://tbice123123.github.io/langchain-dev-utils/zh/adavance-guide/middleware/tool-call-repair_q= Demonstrates the standard way to integrate ToolCallRepairMiddleware into a LangChain agent. This involves importing the middleware and including it in the agent's middleware list during creation. Ensure `langchain-dev-utils[standard]` is installed. ```python from langchain_dev_utils.agents.middleware import ToolCallRepairMiddleware agent = create_agent( model="vllm:qwen2.5-7b", tools=[run_python_code, get_current_time], middleware=[ ToolCallRepairMiddleware() ], ) ``` -------------------------------- ### Asynchronous Invoke Chat Model Source: https://tbice123123.github.io/langchain-dev-utils/zh/adavance-guide/openai-compatible/chat_q= Illustrates how to perform an asynchronous invocation of a chat model using the `ainvoke` method. This is useful in non-blocking applications. The example uses `HumanMessage` and prints the awaited response. ```python import asyncio from langchain_core.messages import HumanMessage # Assuming ChatVLLM is already created as shown in previous examples # model = ChatVLLM(model="qwen2.5-7b") # Placeholder for async model instantiation if not already done class MockAsyncChatModel: async def ainvoke(self, messages): await asyncio.sleep(0.1) # Simulate async operation return "Mock async response to Hello" async def main(): model = MockAsyncChatModel() response = await model.ainvoke([HumanMessage("Hello")]) print(response) # asyncio.run(main()) # Note: asyncio.run(main()) is commented out to make the snippet runnable without an event loop context. # In a real async application, you would call asyncio.run(main()) or await main() within an existing loop. ``` -------------------------------- ### LangChain Agent and Model Integration with vLLM Source: https://tbice123123.github.io/langchain-dev-utils/zh/index_q= Demonstrates how to register an OpenAI-Compatible model provider (vLLM), load a chat model dynamically using a string, and create an agent with a custom tool. This example showcases the library's ability to simplify model management and agent creation. ```python from langchain.tools import tool from langchain_core.messages import HumanMessage from langchain_dev_utils.chat_models import register_model_provider, load_chat_model from langchain_dev_utils.agents import create_agent # Register model provider register_model_provider("vllm", "openai-compatible", base_url="http://localhost:8000/v1") @tool def get_current_weather(location: str) -> str: """Get the current weather for a specified location""" return f"25 degrees, {location}" # Dynamically load model using string model = load_chat_model("vllm:qwen2.5-7b") response = model.invoke("Hello") print(response) # Create an agent agent = create_agent("vllm:qwen2.5-7b", tools=[get_current_weather]) response = agent.invoke({"messages": [HumanMessage(content="What's the weather like in New York today?")]}) print(response) ``` -------------------------------- ### Configuring Structured Output Methods in Langchain Source: https://tbice123123.github.io/langchain-dev-utils/zh/adavance-guide/openai-compatible/chat Explains the different structured output methods (`json_schema`, `function_calling`, `json_mode`) and how to configure provider support using `supported_response_format`. This example declares vLLM support for `json_schema`. ```python from langchain_dev_utils.chat_models.adapters import create_openai_compatible_model ChatVLLM = create_openai_compatible_model( model_provider="vllm", chat_model_cls_name="ChatVLLM", compatibility_options={"supported_response_format": ["json_schema"]}, ) model = ChatVLLM(model="qwen2.5-7b") ``` -------------------------------- ### PlanMiddleware Configuration and Usage Source: https://tbice123123.github.io/langchain-dev-utils/zh/adavance-guide/middleware/plan Demonstrates how to configure and use the PlanMiddleware with a Langchain agent for task planning. ```APIDOC ## PlanMiddleware API ### Description The `PlanMiddleware` is designed for structured decomposition and process management before executing complex tasks. It breaks down a main task into a series of ordered sub-tasks (a 'plan') and executes them sequentially, dynamically updating the status of each sub-task upon completion. ### Method N/A (This is a middleware configuration, not a direct API endpoint) ### Endpoint N/A ### Parameters #### Path Parameters N/A #### Query Parameters N/A #### Request Body N/A ### Middleware Configuration Parameters - **`system_prompt`** (str) - Optional - The system prompt to use. If `None`, a default prompt is used. - **`custom_plan_tool_descriptions`** (dict) - Optional - Custom descriptions for the plan-related tools. The keys can be `write_plan`, `finish_sub_plan`, or `read_plan`. - **`write_plan`** (str) - Description for the tool that writes or decomposes tasks into sub-tasks. - **`finish_sub_plan`** (str) - Description for the tool that marks a sub-task as completed. - **`read_plan`** (str) - Description for the tool that queries the current task plan list. - **`use_read_plan_tool`** (bool) - Optional - Whether to enable the read plan tool. Defaults to `True`. ### Usage Example ```python from langchain_dev_utils.agents.middleware import PlanMiddleware from langchain_core.messages import HumanMessage # Assuming create_agent is a function that initializes a Langchain agent # agent = create_agent( # model="openai:gpt-4o", # middleware=[ # PlanMiddleware( # custom_plan_tool_descriptions={ # "write_plan": "用于写计划,将任务拆解为多个有序的子任务。", # "finish_sub_plan": "用于完成子任务,更新子任务状态为已完成。", # "read_plan": "用于查询当前的任务规划列表。" # }, # use_read_plan_tool=True, # Set to False if you don't want to use the read plan tool # ) # ], # ) # response = agent.invoke( # {"messages": [HumanMessage(content="我要去New York玩几天,帮我规划行程")]} # ) # print(response) ``` ### Tool Requirements The `PlanMiddleware` requires the use of the `write_plan` and `finish_sub_plan` tools. The `read_plan` tool is enabled by default but can be disabled by setting `use_read_plan_tool` to `False`. ### Comparison with Official To-do List Middleware This middleware is similar in function to LangChain's official **To-do list middleware** but differs in its tool design: | Feature | Official To-do List Middleware | PlanMiddleware | |---|---|---| | Number of Tools | 1 (`write_todo`) | 3 (`write_plan`, `finish_sub_plan`, `read_plan`) | | Functional Focus | To-do lists | Plan lists | | Operation Method | Add/modify via one tool | Write, modify, and query via separate tools | The key differentiator for `PlanMiddleware` is the provision of three dedicated tools: `write_plan`, `finish_sub_plan`, and `read_plan`. ```