Creación de un paquete « LangGraph » para su importación

Crea agentes personalizados de « LangGraph » que se puedan importar a « watsonx Orchestrate » para ejecutarlos en el entorno de ejecución de la plataforma.

Estructura de archivos requerida

Para importar un agente de LangGraph, cree un paquete que contenga los archivos que definen el comportamiento del agente, la configuración de implementación y los requisitos de conexión.

Archivos mínimos necesarios

Todos los paquetes de agentes de « LangGraph » deben incluir:

  1. agent.yaml

    Archivo de configuración que define los metadatos del agente, los parámetros de implementación y los requisitos de conexión opcionales.

  2. Python módulo

    Un .py archivo que contiene la función de fábrica que crea tu agente.

  3. requirements.txt

    Enumera las dependencias de Python que necesita tu agente.

Archivos opcionales

También puedes incluir:

  • Módulos adicionales de « Python » para herramientas, utilidades o funciones auxiliares.
  • Subdirectorios para organizar tu código en componentes lógicos.

Ejemplo de estructura de directorios

Una estructura de agentes sencilla:

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

Un agente más complejo con componentes organizados:

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

Creación del archivo agent.yaml de configuración

El agent.yaml archivo define los metadatos de tu agente y especifica cómo watsonx Orchestrate implementa y ejecuta el paquete.

Campos obligatorios

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

Donde:

  • spec_version

    Debe ser así v1.

  • kind

    Debe ser así agent.

  • name

    El identificador único de tu agente. El nombre no puede estar vacío ni contener solo espacios, y tiene un máximo de 40 caracteres.

  • description

    Descripción de las funciones del agente. El valor no debe estar vacío ni contener solo espacios en blanco.

    Para obtener más información sobre cómo redactar descripciones, consulta las Recomendaciones para las descripciones de los agentes.

  • deployment.code_bundle.entrypoint

    Punto de entrada en module:function formato. El módulo es la ruta de módulo Python y la función crea el gráfico LangGraph.

Campos opcionales

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

Donde:

  • title

    Un nombre de visualización para el agente.

  • framework

    El valor predeterminado es langgraph. Este es el único marco compatible.

  • checkpointer

    Configuración opcional para la persistencia del estado. Permite al agente mantener el estado de la conversación a lo largo de las interacciones. Para obtener información detallada sobre la configuración de los checkpointers, consulte «Habilitación de la persistencia de estado para los agentes de LangGraph ».

Estructura completa de la configuración

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>
        

Implementación de la función de fábrica

Tu módulo ` Python ` debe contener una función de fábrica que cree y devuelva un archivo sin compilar StateGraph. El motor de ejecución de « watsonx Orchestrate » se encarga de la compilación, la ejecución y la inserción de las credenciales de conexión configuradas.

Requisitos de las funciones de fábrica

La función de fábrica debe:

  • Acepta un RunnableConfig parámetro.
  • Devuelve un archivo sin compilar StateGraph.
    Importante: No llames al .compile() método para compilar el StateGraph.
  • Se debe especificar agent.yaml utilizando el module:function formato.

Estructura básica de las funciones de fábrica

Sin credenciales:

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

Con credenciales:

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

Para obtener información detallada sobre el acceso a las credenciales y los patrones de conexión, consulte «Creación de conexiones para los agentes de LangGraph ».

Cómo nombrar tu módulo y tu función

Puedes utilizar cualquier nombre de módulo y función. Especifícalos en agent.yaml, por ejemplo:

  • agent:create_agent

    Función create_agent() en agent.py.

  • my_agent:build_graph

    Función build_graph() en my_agent.py.

  • custom:my_factory

    Función my_factory() en custom.py.

Ejemplo de implementación

Agente simple sin modelo de lenguaje grande (LLM)

En este ejemplo se crea un agente básico que responde con un saludo.

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

Agente con integración de LLM

Este ejemplo muestra cómo leer las credenciales de conexión introducidas e inicializar un modelo de lenguaje grande (LLM) de uno de los varios proveedores compatibles.

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

Agente con herramientas

Este ejemplo muestra cómo crear un agente capaz de utilizar herramientas.

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

Configuración de tu agente

Una vez que hayas creado los archivos necesarios, comprímelos en un archivo ZIP para importarlos:

  1. Ve al directorio de agentes.
  2. Selecciona todos los archivos y subdirectorios.
  3. Crea un archivo ZIP.

Asegúrate de que el archivo ZIP conserve las rutas relativas de tus archivos. El agent.yaml archivo debe estar en el directorio raíz del paquete. Si tu archivo ZIP contiene un único directorio de nivel superior, el proceso de importación lo desestructura automáticamente.

Qué hacer a continuación