Inicio / Artículos / Notas prácticas: IA agente con LangChain — Parte 3: Llamadas a herramientas en LangChain

Notas prácticas: IA agente con LangChain — Parte 3: Llamadas a herramientas en LangChain

Guía práctica paso a paso: IA agente con LangChain — Parte 3: Llamadas a herramientas en LangChain: contratos, verificaciones y espacios de código listos para usar destinados a los equipos que implementan este patrón.

1916 palabras

Úselo como una versión reestructurada dirigida a operadores de las ideas presentadas en “Agentic AI with LangChain — Parte 3: Llamadas a herramientas en LangChain”: etapas claras, espacios de código ordenados y notas de recuperación que perduran tras la transferencia de tareas. La etapa de Resumen funciona mejor si se considera como una superficie medible. Capture una transcripción ejemplar, un caso de fallo y la nota de reversión antes de ampliar el alcance. Registre los tiempos y el costo en tokens o consultas junto con los resultados funcionales. La visibilidad temprana de los costos evita facturas inesperadas cuando el proceso pasa de una demostración a entornos compartidos.

Conceptos de llamadas a herramientas

En la etapa de Conceptos de Llamada a Herramientas, defina las entradas, el responsable del paso y los criterios de finalización antes de modificar el código. Los operadores deben poder volver a ejecutar el paso a partir de un punto de control conocido sin tener que adivinar el estado oculto. Mantenga la configuración fuera del código de la aplicación. Los archivos de entorno, los almacenes de datos secretos y las banderas de funcionalidad deben estar en un lugar donde los operadores puedan auditarlos sin necesidad de leer todo el sistema. Autentique en la pasarela y vuelva a autorizarlo en el plano de datos. Un token portador por sí solo no constituye un límite entre tenencias.

1. Configuraciones del Sistema

En la fase de 1 Configuraciones del Sistema, defina las entradas, el responsable de cada paso y los criterios de finalización antes de modificar el código. Los operadores deben poder volver a ejecutar el paso a partir de un punto de control conocido sin tener que adivinar el estado oculto. Documente tanto la ruta óptima como la ruta de recuperación. Las intentonas, los controles humanos y el manejo de mensajes no entregados forman parte del producto, no son mejoras posteriores. Autentique en la pasarela y vuelva a autorizarlo en el plano de datos. Un token portador por sí solo no constituye un límite entre tenencias.

OPENAI_API_KEY="<Your OpenAI API Key>"
TAVILY_API_KEY=<Your TAVILY API Key>
class BaseConfig(BaseSettings):
    OPENAI_API_KEY: Optional[str]
    PINECONE_API_KEY: Optional[str]
    TAVILY_API_KEY: Optional[str]

model_config = SettingsConfigDict(env_file=".env", extra="ignore")

2. Estructura del Proyecto

En la fase 2 de Estructura del Proyecto, defina las entradas, el responsable de la tarea y los criterios de finalización antes de modificar el código. Los operadores deben poder volver a ejecutar la tarea a partir de un punto de control conocido sin tener que adivinar el estado oculto. Prefiera unidades pequeñas y verificables en lugar de scripts extensos. Cuando una tarea falla, el error debe indicar una única responsabilidad y no un proceso complicado. Autentique en la pasarela de entrada y vuelva a autorizarlo en el plano de datos. Un token portador por sí solo no constituye un límite entre tenencias.

project/
|
├── tools
│   ├── get_sum.py    # a simple LangChain tool example
|   └── weather.py    # get_weather LangChain tool using open source APIs
|
|── tool_call.py      # implement tool-calling loop using LangChain tools
├── config.py         # pydantic BaseConfig
├── .env              # environment variable definition
├── .gitignore
└── requirements.txt  # package requirements

3. Herramientas de LangChain

En la fase de las 3 herramientas de LangChain, defina las entradas, el responsable del paso y los criterios de finalización antes de modificar el código. Los operadores deben poder volver a ejecutar el paso a partir de un punto de control conocido sin tener que adivinar el estado oculto. Trate esta fase como un contrato entre las entradas y los resultados validados. Asigne nombres a los artefactos, defina comprobaciones de éxito y rechace las completaciones parciales silenciosas. Autentíquese en la pasarela y vuelva a autorizarse en el plano de datos. Un token portador por sí solo no constituye un límite entre tenencias.

3.1. ¿Qué es una herramienta de LangChain?

En la etapa 3.1 “¿Qué es?”, defina las entradas, el responsable de cada paso y los criterios de finalización antes de modificar el código. Los operadores deben poder volver a ejecutar el paso a partir de un punto de control conocido, sin tener que adivinar el estado oculto. Registre los tiempos de ejecución y el costo de los tokens o consultas junto con los resultados funcionales. La visibilidad temprana del costo evita facturas inesperadas cuando el flujo pasa de entornos de demostración a entornos compartidos. Autentíquese en la pasarela y vuelva a autorizarse en el plano de datos. Un token portador por sí solo no constituye un límite entre tenencias.

from langchain.tools import tool


@tool
def get_sum(a: int, b: int) -> int:
    """
    get the summation of two integers
    :param a: int, input integer
    :param b: int, input integer
    :return: int, the sum of a and b
    """
    return a + b

3.2. Implementar una herramienta meteorológica

Para la sección 3.2, implemente una etapa definiendo las entradas, el responsable de cada paso y los criterios de finalización antes de modificar el código. Los operadores deben poder volver a ejecutar el paso a partir de un punto de control conocido, sin tener que adivinar el estado oculto. Mantenga la configuración fuera del código de la aplicación; los archivos de entorno, los almacenes de datos confidenciales y las banderas de funcionalidad deben estar en un lugar donde los operadores puedan auditarlos sin necesidad de leer todo el sistema.

3.3. Concepto de llamada a herramientas

Para el concepto de etapa 3x3, defina las entradas, el responsable de cada paso y los criterios de finalización antes de modificar el código. Los operadores deben poder volver a ejecutar el paso a partir de un punto de control conocido sin tener que adivinar el estado oculto. Documente tanto la ruta óptima como la ruta de recuperación. Las intentonas, los controles humanos y el manejo de mensajes no entregados forman parte del producto, no son mejoras posteriores. Autentique en la pasarela y vuelva a autorizarlo en el plano de datos. Un token portador por sí solo no constituye un límite entre tenencias.

3.4. Llamadas a herramientas en LangChain

En la etapa de llamada a herramientas 3 4, defina las entradas, el responsable del paso y los criterios de finalización antes de modificar el código. Los operadores deben poder volver a ejecutar el paso a partir de un punto de control conocido sin tener que adivinar el estado oculto. Prefiera unidades pequeñas y verificables en lugar de scripts extensos. Cuando un paso falla, el error debe indicar una única responsabilidad y no un proceso complicado. Autentique en la pasarela de entrada y vuelva a autorizarlo en el plano de datos. Un token portador por sí solo no constituye un límite entre entornos. En la etapa de llamada a herramientas 3 4, defina las entradas, el responsable del paso y los criterios de finalización antes de modificar el código. Los operadores deben poder volver a ejecutar el paso a partir de un punto de control conocido sin tener que adivinar el estado oculto. Registre los tiempos de ejecución y el costo de los tokens o consultas junto con los resultados funcionales. Tener visibilidad sobre los costos desde el principio evita facturas inesperadas cuando el proceso pasa de entornos de demostración a entornos compartidos.

3.4.1. Configuración del LLM y las herramientas

Al trabajar en la fase de configuración 3 4 1, anote primero el contrato: las entradas requeridas, la señal de éxito y qué ocurre en caso de fallo parcial. Esa lista de verificación ayuda a mantener honestas las futuras modificaciones del código. Guarde la configuración fuera del código de la aplicación. Los archivos de entorno, los almacenes de secretos y las banderas de funcionalidad deben estar en un lugar donde los operadores puedan auditarlos sin tener que leer todo el sistema. Almacene en caché las instrucciones del sistema estables y los esquemas de las herramientas. Reenviar un preámbulo idéntico es una causa común de desperdicio de recursos.

class WeatherAssistant:
    def __init__(self):

        # initialize llm
        self.llm = ChatOpenAI(api_key=api_key, model="gpt-4o-mini", temperature=0)

        # initialize a tool dictionary
        self.tools = {"get_weather": get_weather,
                      "tavily_search": TavilySearch(max_results=3, tavily_api_key=TAVILY_API_KEY)}
        # bind LangChain tools to llm
        self.llm_with_tools = self.llm.bind_tools(list(self.tools.values()))

        # initialize messages to store message list
        self.messages = []

        # System prompt
        self.system_prompt = f"""You are a helpful assistant for question-answering tasks.
        When users ask about weather, use the get_weather tool to get weather. For other questions,
        use web_search. If you don't know the answer, just say that you don't know.
        Be conversational and helpful in your responses."""

        self.messages.append(SystemMessage(content=self.system_prompt))

3.4.2. Implementación del bucle de llamada a herramientas

Al trabajar en la fase de implementación 3 4 2, anote primero el contrato: las entradas requeridas, la señal de éxito y qué ocurre en caso de fallo parcial. Esa lista de verificación mantiene honestas las futuras modificaciones del código. Documente junto con ello el camino óptimo y el camino de recuperación. Las reintentos, los controles humanos y el manejo de mensajes no entregados forman parte del producto, no son mejoras posteriores. Registre el nombre de la herramienta, el hash de los argumentos, la latencia y el resultado de cada llamada. Depurar agentes en bucles sin esa huella desperdicia horas.

async def chat(self, message: str):
    # Wrap User message in a HumanMessage and add it to message list
    self.messages.append(HumanMessage(content=message))

    # Get AI response (it may or may not contain tool calls)
    response = await self.llm_with_tools.ainvoke(self.messages)
    self.messages.append(response)

    # If there is any tool calls in the AI response
    if response.tool_calls:

        # process tool calls
        for tool_call in response.tool_calls:

            # retrieve function name from tool_call, then
            # retrieve the tool from tool dictionary, and invoke it,
            # append resulting tool message to message list
            tool = self.tools[tool_call["name"]]
            tool_result = await tool.ainvoke(tool_call)
            self.messages.append(tool_result)

        # Get final response after tool execution
        final_response = await self.llm_with_tools.ainvoke(self.messages)
        self.messages.append(final_response)

3.4.3 Pruebas del bucle

Al trabajar en la fase de pruebas 3 4 3, anote primero el contrato: las entradas requeridas, la señal de éxito y qué ocurre en caso de fallo parcial. Esa lista de verificación garantiza que los cambios posteriores en el código sean transparentes. Prefiera unidades pequeñas y probables sobre scripts extensos. Cuando un paso falla, el fallo debe apuntar a una única responsabilidad y no a un proceso complicado. Registre el nombre de la herramienta, el hash de los argumentos, la latencia y el resultado de cada llamada. Depurar sin ese rastro desperdicia horas. Al trabajar en la fase de pruebas 3 4 3, anote primero el contrato: las entradas requeridas, la señal de éxito y qué ocurre en caso de fallo parcial. Esa lista de verificación garantiza que los cambios posteriores en el código sean transparentes. Anote los tiempos de ejecución y el costo de tokens o consultas junto a los resultados funcionales. Tener visibilidad del costo desde el principio evita facturas inesperadas cuando el proceso pasa de la versión de demostración a entornos compartidos.

async def main():
    print("hello tool calling!")
    assistant = WeatherAssistant()
    message = "What is the temperature in Tokyo?"
    await assistant.chat(message)
    for msg in assistant.messages:
        msg.pretty_print()
if __name__ == "__main__":
    asyncio.run(main())

4. Limitaciones del bucle básico de llamada a herramientas

Las 4 limitaciones de esta etapa funcionan mejor cuando se trata como una superficie medible. Capture un registro exitoso, un caso de fallo y la nota de reversión antes de ampliar el alcance. Mantenga la configuración fuera del código de la aplicación. Los archivos de entorno, los almacenes de datos confidenciales y las banderas de funcionalidad deben estar en un lugar donde los operadores puedan auditarlos sin tener que leer todo el sistema. Exponga las herramientas con esquemas limitados y etiquetas explícitas de efectos secundarios. Los hosts necesitan saber qué llamadas modifican el estado antes de aprobarlas automáticamente.

5. Resumen final

La etapa de Resumen final 5 funciona mejor cuando se trata como una superficie medible. Capture un registro ideal, un caso de fallo y la nota de reversión antes de ampliar el alcance. Documente tanto el camino óptimo como el de recuperación juntos. Las reintentos, los controles humanos y el manejo de mensajes no entregados forman parte del producto, no son ajustes realizados posteriormente. Exponga herramientas con esquemas limitados y etiquetas explícitas de efectos secundarios. Los administradores necesitan saber qué llamadas modifican el estado antes de aprobarlas automáticamente.

Lista de verificación operativa

Al trabajar en la etapa de Lista de verificación operativa, anote primero el contrato: entradas requeridas, señal de éxito y qué ocurre en caso de fallo parcial. Esa lista mantiene honestas las futuras modificaciones del código.

Trate esta etapa como un contrato entre las entradas y las salidas validadas. Asigne nombres a los artefactos, defina comprobaciones de éxito y rechace las completaciones parciales silenciosas.

Registra el nombre de la herramienta, el hash de los argumentos, la latencia y el resultado de cada llamada. Depurar agentes en bucle sin esa información desperdicia horas.

Mantén el estado del gráfico simple y tipado. Los bloques anidados ocultan qué nodo escribió qué campo e impiden reanudar después de interrupciones.

Añade una prueba de funcionamiento básica que ejecute la ruta crítica en CI con fixtures, y no con APIs pagadas en tiempo real, siempre que lo permitan los presupuestos.

Dokumenta tanto la ruta óptima como la de recuperación. Las reintentos, los controles humanos y el manejo de mensajes no entregados forman parte del producto, no son algo que se añada posteriormente.

Antes de promocionar la tecnología, congela las versiones, captura una transcripción de referencia para la ruta crítica y confirma los pasos para revertir cambios. Los entornos compartidos necesitan límites de velocidad, verificaciones de tenencia y un responsable claro para la rotación de credenciales. Prefiere una fiabilidad sencilla a demostraciones ingeniosas pero puntuales.

Nota por lotes para d7ca1ebeb899: mantener las claves del proveedor fuera del repositorio, establecer un límite para los tokens por sesión y almacenar las transcripciones junto a los archivos de evaluación para que los cambios posteriores en el modelo sigan siendo comparables.