创建用于导入的 LangGraph 包

构建自定义的 LangGraph 代理,这些代理可导入到 watsonx Orchestrate 中,并在平台运行时环境中运行。

要求的文件结构

要导入一个 LangGraph 代理,请创建一个包,其中包含定义代理行为、部署设置和连接要求的文件。

所需的最低文件

每个 LangGraph 代理包必须包含:

  1. agent.yaml

    用于定义代理元数据、部署设置以及可选连接要求的配置文件。

  2. Python 模块

    一个包含用于创建代理 .py 的工厂函数的文件。

  3. requirements.txt

    列出代理所需的 Python 依赖项。

可选文件

您还可以添加:

  • 用于工具、实用程序或辅助函数的额外 Python 模块。
  • 使用子目录将代码划分为逻辑模块。

目录结构示例

一种简单的代理结构:

my-agent/
├── agent.yaml
├── agent.py
└── requirements.txt

一个由有序组件构成的更复杂的代理:

my-agent/
├── agent.yaml
├── agent.py
├── requirements.txt
├── core/
│   ├── __init__.py
│   ├── state.py
│   └── config.py
├── tools/
│   ├── __init__.py
│   └── api_tools.py
└── utils/
    ├── __init__.py
    └── logging.py

创建配置文件 agent.yaml

agent.yaml 文件定义了您的代理元数据,并指定了 watsonx Orchestrate 如何部署和运行该软件包。

必填字段

spec_version: v1
kind: agent
name: my_agent_name
description: Description of what your agent does
deployment:
  code_bundle:
    entrypoint: module:function

其中:

  • spec_version

    一定是 v1……

  • kind

    一定是 agent……

  • name

    您的代理的唯一标识符。 名称不能为空,也不能仅包含空格,且最长为40个字符。

  • description

    代理的功能说明。 该值不能为空,也不能仅包含空格。

    有关如何撰写描述的更多信息,请参阅 《代理描述建议》

  • deployment.code_bundle.entrypoint

    格式 module:function 为 的入口点。 该模块的路径为 Python ,该函数用于创建 LangGraph 图形。

可选字段

title: My Agent Display Name
framework: langgraph
checkpointer:
  type: postgres
  connection_string_key: db_connection_string

其中:

  • title

    代理的显示名称。

  • framework

    默认值为 langgraph. 这是唯一受支持的框架。

  • checkpointer

    状态持久化的可选配置。 使客服代表能够在不同交互中保持对话状态。 有关配置检查点的详细信息,请参阅 《为 LangGraph 代理启用状态持久化 》。

完整配置结构

spec_version: v1
kind: agent
name: <agent-name>
title: <optional-display-title>
description: <agent-description>
framework: langgraph
deployment:
  code_bundle:
    entrypoint: <module:function>
checkpointer:
  type: <postgres|sqlite|memory>
  connection_string_key: <key-name>
        

实现工厂函数

您的 Python 模块必须包含一个工厂函数,该函数用于创建并返回一个未编译的 StateGraph. watsonx Orchestrate 运行时负责编译、执行以及注入已配置的连接凭据。

工厂函数的要求

工厂函数必须:

  • 接受一个 RunnableConfig 参数。
  • 返回一个未编译的 StateGraph.
    重要提示: 请勿调用该 .compile() 方法来编译该文件 StateGraph
  • 请使用 module:function 格式 agent.yaml 进行指定。

工厂模式的基本结构

未登录:

from langchain_core.runnables.config import RunnableConfig
from langgraph.graph import StateGraph, START, END

def create_agent(config: RunnableConfig) -> StateGraph:
    """
    Factory function that creates and returns an uncompiled StateGraph.
    
    Args:
        config: Runtime configuration containing credentials, settings, and other runtime metadata
    
    Returns:
        StateGraph: The uncompiled agent graph
    """
    workflow = StateGraph(YourStateClass)
    
    # Add nodes and edges
    workflow.add_node("your_node", your_node_function)
    workflow.add_edge(START, "your_node")
    workflow.add_edge("your_node", END)
    
    # Return the UNCOMPILED graph
    return workflow

附带凭证:

from langchain_core.runnables.config import RunnableConfig
from langchain_openai import ChatOpenAI
from langgraph.graph import StateGraph, START, END

def create_agent(config: RunnableConfig) -> StateGraph:
    """
    Factory function that accesses credentials and creates an uncompiled StateGraph.
    
    Args:
        config: Runtime configuration containing credentials, settings, and other runtime metadata
    
    Returns:
        StateGraph: The uncompiled agent graph
    """
    # Access credentials from config
    credentials = config.get("configurable", {}).get("credentials", {})
    api_key = credentials.get("openai_api_api_key")
    
    # Initialize LLM with credentials
    llm = ChatOpenAI(model="gpt-4o-mini", api_key=api_key)
    
    # Build workflow
    workflow = StateGraph(YourStateClass)
    workflow.add_node("your_node", your_node_function)
    workflow.add_edge(START, "your_node")
    workflow.add_edge("your_node", END)
    
    return workflow

有关访问凭据和连接模式的详细信息,请参阅《 为 LangGraph 代理创建连接 》。

为模块和函数命名

您可以使用任何模块和函数名称。 请在 agent.yaml中指定它们,例如:

  • agent:create_agent

    函数 create_agent()agent.py.

  • my_agent:build_graph

    函数 build_graph()my_agent.py.

  • custom:my_factory

    函数 my_factory()custom.py.

实现示例

不使用大型语言模型的简单代理

此示例创建了一个会回应问候语的基本代理。

agent.py:

from typing import Annotated, List, TypedDict
from langchain_core.messages import AIMessage, BaseMessage
from langchain_core.runnables.config import RunnableConfig
from langgraph.graph import StateGraph, START, END

class AgentState(TypedDict):
    messages: Annotated[List[BaseMessage], "conversation history"]

def hello_world_node(state: AgentState) -> AgentState:
    response = AIMessage(content="Hello! How can I help you today?")
    return {"messages": state["messages"] + [response]}

def create_agent(config: RunnableConfig) -> StateGraph:
    workflow = StateGraph(AgentState)
    workflow.add_node("hello_world", hello_world_node)
    workflow.add_edge(START, "hello_world")
    workflow.add_edge("hello_world", END)
    return workflow

agent.yaml:

spec_version: v1
kind: agent
name: hello_world_agent
title: Hello World Agent
description: Simple agent that returns a greeting
deployment:
  code_bundle:
    entrypoint: agent:create_agent

requirements.txt:

langgraph>=0.2.0
langchain-core>=0.3.0

集成大语言模型的代理

此示例演示了如何读取注入的连接凭据,并从多个受支持的提供商中选择一个来初始化 LLM。

agent.py:

from typing import Annotated, List, TypedDict
from langchain_core.messages import BaseMessage
from langchain_core.runnables.config import RunnableConfig
from langchain_openai import ChatOpenAI
from langchain_google_genai import ChatGoogleGenerativeAI
from langgraph.graph import StateGraph, START, END

class AgentState(TypedDict):
    messages: Annotated[List[BaseMessage], "conversation history"]

def create_agent(config: RunnableConfig) -> StateGraph:
    # Get credentials from config
    credentials = config.get("configurable", {}).get("credentials", {})
    openai_api_key = credentials.get("openai_api_api_key")
    gemini_api_key = credentials.get("gemini_api_api_key")
    
    # Initialize LLM based on available credentials
    if openai_api_key:
        llm = ChatOpenAI(model="gpt-4o-mini", api_key=openai_api_key)
    elif gemini_api_key:
        llm = ChatGoogleGenerativeAI(
            model="gemini-2.0-flash-exp", 
            api_key=gemini_api_key
        )
    else:
        raise ValueError("No LLM credentials provided")
    
    def agent_node(state: AgentState):
        response = llm.invoke(state["messages"])
        return {"messages": [response]}
    
    workflow = StateGraph(AgentState)
    workflow.add_node("agent", agent_node)
    workflow.add_edge(START, "agent")
    workflow.add_edge("agent", END)
    
    return workflow

agent.yaml:

spec_version: v1
kind: agent
name: llm_agent
title: LLM-Powered Agent
description: Agent that uses an LLM to respond to queries
deployment:
  code_bundle:
    entrypoint: agent:create_agent

requirements.txt:

langgraph>=0.2.0
langchain-core>=0.3.0
langchain-openai>=0.2.0
langchain-google-genai>=2.0.0

携带工具的特工

此示例演示了如何创建一个能够使用工具的智能体。

agent.py:

from typing import Annotated, List, TypedDict
from langchain_core.messages import BaseMessage
from langchain_core.runnables.config import RunnableConfig
from langchain_openai import ChatOpenAI
from langgraph.graph import StateGraph, END
from langgraph.prebuilt import ToolNode, tools_condition

class AgentState(TypedDict):
    messages: Annotated[List[BaseMessage], "conversation history"]

def get_weather(location: str) -> str:
    """Get the current weather for a location."""
    return f"The weather in {location} is sunny and 72°F"

def create_agent(config: RunnableConfig) -> StateGraph:
    credentials = config.get("configurable", {}).get("credentials", {})
    llm = ChatOpenAI(
        model="gpt-4o-mini",
        api_key=credentials.get("openai_api_api_key")
    )
    
    tools = [get_weather]
    tool_node = ToolNode(tools)
    
    def agent_node(state: AgentState):
        response = llm.bind_tools(tools).invoke(state["messages"])
        return {"messages": [response]}
    
    workflow = StateGraph(AgentState)
    workflow.add_node("agent", agent_node)
    workflow.add_node("tools", tool_node)
    workflow.add_conditional_edges(
        "agent",
        tools_condition,
        {"tools": "tools", "__end__": END}
    )
    workflow.add_edge("tools", "agent")
    workflow.set_entry_point("agent")
    
    return workflow

打包您的代理

创建所需文件后,请将其打包为 ZIP 文件以便导入:

  1. 请前往您的代理目录。
  2. 选中所有文件和子目录。
  3. 创建一个 ZIP 压缩包。

请确保 ZIP 文件保留了文件的相对路径。 该 agent.yaml 文件必须位于包的根目录下。 如果您的 ZIP 文件仅包含一个顶级目录,导入过程会自动将其展开。

下一步操作