Tools en Langchain: cuando el modelo necesita salir a Internet¶

En los artículos anteriores aprendimos a inicializar modelos, a construir agentes conversacionales y a dominar el prompt para controlar sus respuestas. Pero hay un límite duro que ninguna técnica de prompting puede romper: el conocimiento del modelo está congelado en su fecha de entrenamiento.

Esto significa que el agente puede razonar, escribir, resumir y hasta inventar con mucha elegancia; pero no sabe qué pasó ayer, no conoce el precio actual de Bitcoin y no puede verificar si una noticia es real. La solución son las tools (herramientas): funciones que le damos al agente para que extienda sus capacidades más allá de su memoria interna.

Seguiremos con nuestro ejemplo guía de conversiones absurdas, pero ahora con un giro que solo tiene sentido si la información es actual: ¿cuántos plátanos necesitaría vender alguien hoy para comprar un Bitcoin?

Objetivos de este notebook:

  1. Observar la limitación de un modelo sin herramientas ante preguntas que dependen de datos actualizados.
  2. Crear una herramienta de búsqueda web con Tavily.
  3. Darle la herramienta a un agente y ver cómo obtiene respuestas actuales.
  4. Crear una herramienta personalizada para realizar un cálculo concreto.
  5. Combinar ambas herramientas para resolver una pregunta que requiere información externa + cálculo.
In [1]:
# Cargamos variables de entorno. Buscamos el archivo .env hacia arriba desde
# la carpeta donde se ejecuta el notebook, para que funcione tanto si lo corres
# desde el directorio raíz como desde notebooks/module-1/.
from dotenv import load_dotenv
import os

load_dotenv()

OPENROUTER_API_KEY = os.environ["OPENROUTER_API_KEY"]
OPENROUTER_BASE_URL = "https://openrouter.ai/api/v1"

Antes de empezar necesitas:

  • Python 3.10+
  • pip install langchain langchain-openai python-dotenv tavily-python
  • Un archivo .env con OPENROUTER_API_KEY=... y TAVILY_API_KEY=...

1. El problema: un modelo con conocimiento congelado¶

Preguntémosle al agente algo cuyo valor cambia constantemente: el precio actual de Bitcoin. Un modelo puro solo puede responder con lo que aprendió durante su entrenamiento, así que su respuesta estará desactualizada o, peor aún, será una negativa honesta.

In [2]:
from langchain_openai import ChatOpenAI
from langchain.agents import create_agent
from langchain_core.messages import HumanMessage

# Reutilizamos la misma configuración de OpenRouter de los artículos anteriores
model = ChatOpenAI(
    model="openai/gpt-4o-mini",
    api_key=OPENROUTER_API_KEY,
    base_url=OPENROUTER_BASE_URL
)

# Agente sin herramientas: solo tiene acceso a su conocimiento interno
agent_sin_tools = create_agent(model)
In [3]:
pregunta = HumanMessage(content="¿Cuál es el precio actual de Bitcoin en dólares?")

respuesta = agent_sin_tools.invoke({"messages": [pregunta]})
print(respuesta["messages"][-1].content)
Lo siento, pero no puedo proporcionar información en tiempo real, incluido el precio actual de Bitcoin. Te recomendaría que consultes un sitio web de finanzas o una plataforma de intercambio para obtener la información más actualizada.

Nota didáctica: la respuesta ilustra el cuello de botella central de los LLMs: son excelentes generando texto y razonando, pero no pueden consultar fuentes externas por sí solos. Esto no es un bug, es una característica arquitectural. La solución es darles herramientas.

2. Primera herramienta: búsqueda web con Tavily¶

Vamos a crear una herramienta que le permita al agente buscar información actualizada en Internet. Usaremos Tavily, un motor de búsqueda diseñado para agentes de IA. El decorador @tool convierte una función de Python en una herramienta que Langchain puede entregar al agente.

In [4]:
from langchain.tools import tool
from tavily import TavilyClient

# Inicializamos el cliente de Tavily; usa la variable TAVILY_API_KEY del .env
tavily_client = TavilyClient()

@tool
def web_search(query: str) -> dict:
    """Busca información actualizada en Internet.

    Útil para precios de activos, eventos recientes o cualquier dato que cambie con el tiempo.
    """
    return tavily_client.search(query)
In [5]:
# Probamos la herramienta directamente, sin pasar por el agente
resultado_busqueda = web_search.invoke({"query": "Bitcoin price USD today"})

# Tavily devuelve un diccionario con resultados y metadatos
print("Claves del resultado:", list(resultado_busqueda.keys()))
print()
print("Primer resultado:")
print(resultado_busqueda["results"][0]["title"])
print(resultado_busqueda["results"][0]["content"][:200] + "...")
Claves del resultado: ['query', 'follow_up_questions', 'answer', 'images', 'results', 'response_time', 'request_id']

Primer resultado:
Bitcoin price today, BTC to USD live price, marketcap and chart | CoinMarketCap
# Bitcoin price. Why is BTC’s price down today? ## Bitcoin to USD Chart. We are using the coin’s open price in the selected time frame to display ups (green) and downs (red) of the coin’s trend. Macro...
In [6]:
# Ahora el agente tiene acceso a Internet
agent_con_busqueda = create_agent(
    model,
    tools=[web_search],
    system_prompt="Eres un asistente útil. Si necesitas información actualizada, usa la herramienta de búsqueda web."
)
In [7]:
# Misma pregunta, pero ahora el agente puede buscar en Internet
respuesta = agent_con_busqueda.invoke({"messages": [pregunta]})
print(respuesta["messages"][-1].content)
El precio actual de Bitcoin (BTC) es de aproximadamente **65,330.80 USD**. La capitalización de mercado es de alrededor de 1.3 billones de dólares, y ha tenido una variación de -1.63% en las últimas 24 horas. 

Si deseas más detalles o información adicional, no dudes en pedirlo.

Nota didáctica: el agente no "sabe" buscar en Google por su cuenta. Lo que hace es decidir, basándose en la descripción de la herramienta, que necesita consultar una fuente externa. Esa decisión se traduce en una tool_call que Langchain ejecuta y cuyo resultado devuelve al modelo.

3. Herramienta personalizada: la calculadora de plátanos¶

La búsqueda web resuelve el problema de la información actualizada, pero hay tareas que un LLM no debería hacer directamente: cálculos exactos, conversiones de unidades, llamadas a APIs internas, etc. Para eso creamos herramientas personalizadas.

Volvamos a nuestro ejemplo guía y creemos una herramienta que convierta dólares a plátanos.

In [8]:
@tool
def usd_to_bananas(amount_usd: float, banana_price_usd: float = 0.25) -> float:
    """Convierte una cantidad en dólares estadounidenses a número de plátanos.

    Úsala cuando necesites expresar un valor monetario en plátanos.
    El precio por plátano puede variar; por defecto se asume 0.25 USD.
    """
    return amount_usd / banana_price_usd
In [9]:
# Probamos la herramienta directamente
print("100 dólares =", usd_to_bananas.invoke({"amount_usd": 100}), "plátanos")
100 dólares = 400.0 plátanos
In [10]:
# Agente con ambas herramientas: puede buscar información actual y hacer conversiones
agent_completo = create_agent(
    model,
    tools=[web_search, usd_to_bananas],
    system_prompt=(
        "Eres un asistente especializado en conversiones absurdas. "
        "Tienes dos herramientas: una para buscar información actual en Internet "
        "y otra para convertir dólares a plátanos. Usa las herramientas cuando sea necesario."
    )
)
In [11]:
pregunta_combinada = HumanMessage(
    content="¿Cuántos plátanos necesitaría vender hoy alguien para comprar un Bitcoin? Asume un plátano a 0.25 dólares."
)

respuesta = agent_completo.invoke({"messages": [pregunta_combinada]})
print(respuesta["messages"][-1].content)
Hoy, el precio de un Bitcoin es de aproximadamente 65,330.80 dólares. Si consideramos que un plátano cuesta 0.25 dólares, necesitarías vender aproximadamente **261,323 plátanos** para comprar un Bitcoin.

4. ¿Cómo decide el agente cuándo usar cada herramienta?¶

La magia no está en el agente, está en las descripciones. Cuando le damos una herramienta al agente, Langchain lee su docstring y sus anotaciones de tipo. El modelo usa esa información para decidir si necesita la herramienta y, de ser así, con qué argumentos llamarla.

Inspeccionemos el flujo completo de mensajes de la última respuesta.

In [12]:
from pprint import pprint

pprint(respuesta["messages"])
[HumanMessage(content='¿Cuántos plátanos necesitaría vender hoy alguien para comprar un Bitcoin? Asume un plátano a 0.25 dólares.', additional_kwargs={}, response_metadata={}, id='79155650-59e5-40a7-b8ac-33eed1b46413'),
 AIMessage(content='', additional_kwargs={'refusal': None}, response_metadata={'token_usage': {'completion_tokens': 17, 'prompt_tokens': 218, 'total_tokens': 235, 'completion_tokens_details': {'accepted_prediction_tokens': None, 'audio_tokens': 0, 'reasoning_tokens': 0, 'rejected_prediction_tokens': None, 'image_tokens': 0}, 'prompt_tokens_details': {'audio_tokens': 0, 'cached_tokens': 0, 'cache_write_tokens': 0, 'video_tokens': 0}, 'cost': 4.29e-05, 'is_byok': False, 'cost_details': {'upstream_inference_cost': 4.29e-05, 'upstream_inference_prompt_cost': 3.27e-05, 'upstream_inference_completions_cost': 1.02e-05}}, 'model_provider': 'openai', 'model_name': 'openai/gpt-4o-mini', 'system_fingerprint': 'fp_ee57c47580', 'id': 'gen-1784078441-Ebc3ZM93ptPhxeTtDzLT', 'finish_reason': 'tool_calls', 'logprobs': None}, id='lc_run--019f635c-9a36-7b82-82b8-0a8f25cad72c-0', tool_calls=[{'name': 'web_search', 'args': {'query': 'precio actual de Bitcoin'}, 'id': 'call_yh9vosI52HfMRF5cZbHNDQoY', 'type': 'tool_call'}], invalid_tool_calls=[], usage_metadata={'input_tokens': 218, 'output_tokens': 17, 'total_tokens': 235, 'input_token_details': {'audio': 0, 'cache_read': 0}, 'output_token_details': {'audio': 0, 'reasoning': 0}}),
 ToolMessage(content='{"query": "precio actual de Bitcoin", "follow_up_questions": null, "answer": null, "images": [], "results": [{"url": "https://www.binance.com/es/price/bitcoin", "title": "Precio de Bitcoin hoy | Precio de BTC en tiempo real ...", "content": "# Precio de Bitcoin hoy: BTC a USD, capitalización y gráfico. # Precio de Bitcoin (BTC). La popularidad se calcula en función de la capitalización de mercado relativa de los activos. La capitalización de mercado se calcula multiplicando el suministro en circulación del activo por su precio actual. El valor total en dólares de todas las transacciones de este activo en las últimas 24 horas. La variedad de monedas en circulación en el mercado y disponibles para el público para realizar operaciones, de manera similar a las acciones que se cotizan en bolsa. El precio en tiempo real de Bitcoin es de 65.330,8 US$ por (BTC/USD) con una capitalización de mercado actual de 1,3 billones $USD. El volumen de trading a 24 horas es de 24 348,1 millones $USD.El precio de BTC en USD se actualiza en tiempo real.Bitcoin ha variado en -1,63 % en las últimas 24 horas, con un suministro en circulación de 20 millones.", "score": 0.90830135, "raw_content": null}, {"url": "https://es.investing.com/crypto/bitcoin", "title": "Precio del Bitcoin hoy | Cotización BTC", "content": "# Bitcoin. La criptomoneda Bitcoin (BTC) es un tipo de moneda digital utilizada como reserva de valor, minería, para realizar transacciones entre pares o para ser usada en otros hitos tecnológicos. En esta página encontrará información sobre las variaciones en el precio del Bitcoin hoy, además de otros datos complementarios como noticias, análisis, datos históricos, gráficos o incluso un foro de opiniones para estar actualizado e intercambiar comentarios con otros inversores. Active las alertas y acceda a todos los datos del mercado sobre la cotización del Bitcoin en tiempo real. **¿Cuál es el precio en tiempo real de la criptomoneda Bitcoin?**. El precio del Bitcoin hoy es de 62.656,9. **¿Cuál es el símbolo del Bitcoin en bolsa?**. El símbolo bursátil del Bitcoin es \\"BTC\\". **¿Es Bitcoin una buena criptomoneda en la que invertir?**. Para invertir en Bitcoin, puede hacerlo directamente en el instrumento financiero o mediante ETFs de Bitcoin. |  | BTC/USD | · | Investing.com | · | USD | Tiempo real |.", "score": 0.878825, "raw_content": null}, {"url": "https://www.revolut.com/es-ES/crypto/price/btc", "title": "Precio de Bitcoin: BTC/EUR", "content": "Estás en la versión para España. Selecciona tu país o región para ver contenido específico para tu ubicación. Cómo protegemos tu dineroInformar de un dispositivo perdidoInforme sobre la seguridad de los consumidores. # Precio de Bitcoin: BTC/EUR. Aquí tienes todos los datos que necesitas para ganar confianza en el mundo de las criptomonedas. Los precios anteriores no incluyen las comisiones de Revolut por la compra de criptomonedas. Los precios de las criptomonedas son volátiles; el valor de tu inversión puede subir o bajar muy rápido, e incluso caer a cero. ## Precio de BTC en EUR. #### ¿Cuál es el precio actual de Bitcoin? Para calcular este valor, se multiplica el suministro en circulación por el precio actual por Bitcoin. Actualmente, el suministro en circulación de Bitcoin es de 20.056.131 BTC, que representa el número de tokens que se pueden negociar hoy en el mercado.La oferta máxima es de 21.000.000 BTC.", "score": 0.829285, "raw_content": null}, {"url": "https://bitflyer.com/en-us/bitcoin-chart", "title": "Bitcoin Price Chart (BTC/USD)", "content": "[![Image 1: bitFlyer](https://msm07s-cdn.bitflyer.com/pub/common/bitFlyer-logo.svg)](https://bitflyer.com/en-us/). [![Image 4: bitFlyer](https://msm07s-cdn.bitflyer.com/pub/common/bitFlyer-logo.svg)](https://bitflyer.com/en-us/). ![Image 5](https://msm07s-cdn.bitflyer.com/pub/common/app/84p84twyfrvojquy.svg). ![Image 6](https://msm07s-cdn.bitflyer.com/pub/buysell/icons/arrow-up.svg)+0.45%. *   [![Image 7](https://msm07s-cdn.bitflyer.com/pub/common/app/g3vy9wm4wtahjpx7.svg)Ethereum ETH/USD](https://bitflyer.com/en-us/ethereum-chart) ![Image 8](https://msm07s-cdn.bitflyer.com/pub/buysell/icons/arrow-up.svg)+0.13% 1,753.95 USD. *   [![Image 9](https://msm07s-cdn.bitflyer.com/pub/common/app/e9yd6cgyx4yn4qqq.svg)Bitcoin Cash BCH/USD](https://bitflyer.com/en-us/bitcoin-cash-chart) ![Image 10](https://msm07s-cdn.bitflyer.com/pub/buysell/icons/arrow-up.svg)+0.44% 238.76 USD. *   [![Image 11](https://msm07s-cdn.bitflyer.com/pub/common/theme/images/withdrawal/icon-currency-dot.svg)Polkadot DOT/USD](https://bitflyer.com/en-us/polkadot-chart) 0.00% 0.84 USD. *   [![Image 12](https://msm07s-cdn.bitflyer.com/pub/common/app/qf4tywcvtxa4hv84.svg)Litecoin LTC/USD](https://bitflyer.com/en-us/litecoin-chart) ![Image 13](https://msm07s-cdn.bitflyer.com/pub/buysell/icons/arrow-up.svg)+0.52% 44.65 USD. *   [![Image 14](https://msm07s-cdn.bitflyer.com/pub/common/app/iepzqj4kd4sam6g3.svg)Stellar Lumens XLM/USD](https://bitflyer.com/en-us/stellar-lumens-chart) ![Image 15](https://msm07s-cdn.bitflyer.com/pub/buysell/icons/arrow-up.svg)+5.56% 0.19 USD. *   [![Image 16](https://msm07s-cdn.bitflyer.com/pub/common/app/awup4h7t9athwkn6.svg)Ethereum Classic ETC/USD](https://bitflyer.com/en-us/ethereum-classic-chart) ![Image 17](https://msm07s-cdn.bitflyer.com/pub/buysell/icons/arrow-up.svg)+1.59% 7.02 USD. *   [![Image 18](https://msm07s-cdn.bitflyer.com/pub/common/theme/images/withdrawal/icon-currency-xtz.svg)Tezos XTZ/USD](https://bitflyer.com/en-us/tezos-chart) ![Image 19](https://msm07s-cdn.bitflyer.com/pub/buysell/icons/arrow-down.svg)-4.00% 0.24 USD. *   [![Image 20](https://msm07s-cdn.bitflyer.com/pub/common/app/28fyjzj8twzul9pe.svg)Basic Attention Token BAT/USD](https://bitflyer.com/en-us/basic-attention-token-chart) ![Image 21](https://msm07s-cdn.bitflyer.com/pub/buysell/icons/arrow-up.svg)+12.50% 0.09 USD. ![Image 22](https://msm07s-cdn.bitflyer.com/pub/common/app/84p84twyfrvojquy.svg). [Read more](https://bitflyer.com/en-us/s/glossary/bitcoin). *   [Bitcoin peels back to $62K as Fed-wary futures traders cut risk: Is the BTC rally over?](https://cointelegraph.com/markets/bitcoin-peels-back-to-62k-as-fed-wary-futures-traders-cut-risk-is-the-btc-rally-over?utm_source=rss_feed&utm_medium=rss-bitflyer&utm_campaign=rss_partner_inbound)Cointelegraph 7/8/2026 11:41  ![Image 24](https://s3-images.ctmedia.io/media/article-covers/article-covers-70719-bitcoin-golden-cross-due-in-days-as-bears-draw-a-line-at-47k-btc-price.jpg). *   [Bitcoin slides as Iran ceasefire collapse sees $75 oil on Hormuz blockade threats](https://cointelegraph.com/markets/bitcoin-slides-as-iran-ceasefire-collapse-brings-back-hormuz-blockade-threat?utm_source=rss_feed&utm_medium=rss-bitflyer&utm_campaign=rss_partner_inbound)Cointelegraph 7/8/2026 8:35  ![Image 25](https://s3-images.ctmedia.io/media/article-covers/hi-how-to-make-a-profit-when-bitcoin-prices-are-stagnant-oil.jpg). *   [Bull Bitcoin asks French court to strike down DAC8 implementing decree](https://cointelegraph.com/news/bull-bitcoin-legal-action-france-dac8?utm_source=rss_feed&utm_medium=rss-bitflyer&utm_campaign=rss_partner_inbound)Cointelegraph 7/8/2026 6:36  ![Image 26](https://s3-images.ctmedia.io/media/article-covers/big-brother-is-watching.jpg). *   [BTC speculators in focus as analysis says \'textbook Bitcoin bottom\' is underway](https://cointelegraph.com/markets/btc-speculators-in-focus-as-analysis-says-textbook-bitcoin-bottom-is-underway?utm_source=rss_feed&utm_medium=rss-bitflyer&utm_campaign=rss_partner_inbound)Cointelegraph 7/8/2026 5:59  ![Image 27](https://s3-images.ctmedia.io/media/article-covers/market-red-graph-falling-danger-stones-bitcoin.jpg).", "score": 0.76490957, "raw_content": null}, {"url": "https://es-us.finanzas.yahoo.com/quote/BTC-USD", "title": "Bitcoin USD Precio (BTC-USD)", "content": "Criptomoneda • USD • #1 por capitalización bursátil. # Bitcoin USD Precio (BTC-USD). A partir del 8:07:12 a.m. UTC. Cargando gráfico de BTC-USD. El valor de mercado total del suministro en circulación de una criptomoneda. Capitalización bursátil = Precio actual × Suministro en circulación. El valor totalmente diluido (FDV) es una estimación de la capitalización bursátil de una criptomoneda, si el suministro máximo estuviera en circulación. FDV = Precio actual × Suministro máximo. El valor total de una criptomoneda negociado en todos los mercados de cambio en las últimas 24 horas. Los índices más altos sugieren que el activo se negocia más activamente y es más fácil realizar una compra/venta cerca de su valor real. La porción de la oferta total que está disponible públicamente y circula activamente en el mercado. Es similar a lo que sucede con las \\"acciones en circulación\\" en el mercado accionario. Más acerca de Bitcoin USD. USDC-USD  USD Coin USD.", "score": 0.6450534, "raw_content": null}], "response_time": 0.0, "request_id": "1cc2e3d4-6c3b-4849-add2-a3f514f43c44"}', name='web_search', id='5d275862-72bc-4ee3-8a51-d4b06fe95ebb', tool_call_id='call_yh9vosI52HfMRF5cZbHNDQoY'),
 AIMessage(content='', additional_kwargs={'refusal': None}, response_metadata={'token_usage': {'completion_tokens': 23, 'prompt_tokens': 2829, 'total_tokens': 2852, 'completion_tokens_details': {'accepted_prediction_tokens': None, 'audio_tokens': 0, 'reasoning_tokens': 0, 'rejected_prediction_tokens': None, 'image_tokens': 0}, 'prompt_tokens_details': {'audio_tokens': 0, 'cached_tokens': 0, 'cache_write_tokens': 0, 'video_tokens': 0}, 'cost': 0.00043815, 'is_byok': False, 'cost_details': {'upstream_inference_cost': 0.00043815, 'upstream_inference_prompt_cost': 0.00042435, 'upstream_inference_completions_cost': 1.38e-05}}, 'model_provider': 'openai', 'model_name': 'openai/gpt-4o-mini', 'system_fingerprint': 'fp_ee57c47580', 'id': 'gen-1784078442-OV28DOVQ7ONP9epo3Zoj', 'finish_reason': 'tool_calls', 'logprobs': None}, id='lc_run--019f635c-9e22-71d0-9576-2f0d0fa7c3d1-0', tool_calls=[{'name': 'usd_to_bananas', 'args': {'amount_usd': 65330.8}, 'id': 'call_Ypwqj9KcJzwDmF6SnlEpkyIX', 'type': 'tool_call'}], invalid_tool_calls=[], usage_metadata={'input_tokens': 2829, 'output_tokens': 23, 'total_tokens': 2852, 'input_token_details': {'audio': 0, 'cache_read': 0}, 'output_token_details': {'audio': 0, 'reasoning': 0}}),
 ToolMessage(content='261323.2', name='usd_to_bananas', id='5c116f64-a03f-4c17-96fc-45b1a3e5217e', tool_call_id='call_Ypwqj9KcJzwDmF6SnlEpkyIX'),
 AIMessage(content='Hoy, el precio de un Bitcoin es de aproximadamente 65,330.80 dólares. Si consideramos que un plátano cuesta 0.25 dólares, necesitarías vender aproximadamente **261,323 plátanos** para comprar un Bitcoin.', additional_kwargs={'refusal': None}, response_metadata={'token_usage': {'completion_tokens': 51, 'prompt_tokens': 2867, 'total_tokens': 2918, 'completion_tokens_details': {'accepted_prediction_tokens': None, 'audio_tokens': 0, 'reasoning_tokens': 0, 'rejected_prediction_tokens': None, 'image_tokens': 0}, 'prompt_tokens_details': {'audio_tokens': 0, 'cached_tokens': 2816, 'cache_write_tokens': 0, 'video_tokens': 0}, 'cost': 0.00024945, 'is_byok': False, 'cost_details': {'upstream_inference_cost': 0.00024945, 'upstream_inference_prompt_cost': 0.00021885, 'upstream_inference_completions_cost': 3.06e-05}}, 'model_provider': 'openai', 'model_name': 'openai/gpt-4o-mini', 'system_fingerprint': 'fp_ee57c47580', 'id': 'gen-1784078443-MDqusZQYCeVKo2fBJKul', 'finish_reason': 'stop', 'logprobs': None}, id='lc_run--019f635c-a250-7952-b044-2acb02290a9b-0', tool_calls=[], invalid_tool_calls=[], usage_metadata={'input_tokens': 2867, 'output_tokens': 51, 'total_tokens': 2918, 'input_token_details': {'audio': 0, 'cache_read': 2816}, 'output_token_details': {'audio': 0, 'reasoning': 0}})]
In [13]:
# Extraemos solo las llamadas a herramientas para ver el orden y los argumentos
for i, mensaje in enumerate(respuesta["messages"]):
    if hasattr(mensaje, "tool_calls") and mensaje.tool_calls:
        print(f"Mensaje {i}: {mensaje.type}")
        for tool_call in mensaje.tool_calls:
            print(f"  → Herramienta: {tool_call['name']}")
            print(f"    Argumentos: {tool_call['args']}")
Mensaje 1: ai
  → Herramienta: web_search
    Argumentos: {'query': 'precio actual de Bitcoin'}
Mensaje 3: ai
  → Herramienta: usd_to_bananas
    Argumentos: {'amount_usd': 65330.8}

Nota didáctica: fíjate en el patrón: el modelo primero emite un AIMessage con tool_calls (la intención de usar la herramienta), Langchain ejecuta la herramienta y devuelve un ToolMessage con el resultado, y finalmente el modelo genera la respuesta en lenguaje natural. Diseñar buenas descripciones en los docstrings es clave: un docstring vago lleva a llamadas incorrectas; uno preciso lleva a resultados útiles.

Cierre y próximos pasos¶

En este artículo dimos el salto de "modelo que responde con su conocimiento interno" a "agente que interactúa con el mundo exterior". Aprendimos a:

  • Detectar cuándo un modelo necesita información actualizada.
  • Crear una herramienta de búsqueda web con Tavily.
  • Construir herramientas personalizadas con el decorador @tool.
  • Combinar múltiples herramientas en un solo agente.
  • Inspeccionar las tool_calls para entender cómo el agente toma decisiones.

Las herramientas resuelven el problema de la información actual, pero introducen una nueva pregunta: ¿cómo hacemos que el agente recuerde lo que ya conversamos o aprendió en ejecuciones anteriores? Eso es exactamente lo que veremos en el próximo artículo: memoria y estado persistente en Langchain.