Skip to content

Tools y agents ​

Los tools son funciones que el modelo puede invocar (buscar en BD, llamar API, calcular). Un agent es un bucle donde el LLM decide que herramienta usar, con que argumentos y cuando ya tiene respuesta final.

Tools: definicion basica ​

Con el decorador @tool de LangChain:

python
from langchain_core.tools import tool

@tool
def multiply(a: int, b: int) -> int:
    """Multiplica dos enteros."""
    return a * b

@tool
def get_weather(city: str) -> str:
    """Devuelve el tiempo actual de una ciudad."""
    # En produccion: llamada real a API
    return f"Tiempo en {city}: soleado, 22C"

El docstring es critico: el modelo lo usa para elegir la herramienta.

Tool con schema Pydantic ​

python
from pydantic import BaseModel, Field
from langchain_core.tools import StructuredTool

class SearchInput(BaseModel):
    query: str = Field(description="Consulta de busqueda")
    limit: int = Field(default=5, description="Numero maximo de resultados")

def search_docs(query: str, limit: int = 5) -> str:
    return f"Resultados para '{query}' (limit={limit}): ..."

search_tool = StructuredTool.from_function(
    func=search_docs,
    name="search_docs",
    description="Busca en la documentacion interna",
    args_schema=SearchInput,
)

Agent con create_react_agent ​

Patron ReAct (Reason + Act):

python
from langchain_ollama import ChatOllama
from langgraph.prebuilt import create_react_agent

model = ChatOllama(model="llama3.1:8b", temperature=0)
tools = [multiply, get_weather]

agent = create_react_agent(model, tools)

result = agent.invoke({
    "messages": [("human", "Cuanto es 12 por 8 y que tiempo hace en Madrid?")]
})

print(result["messages"][-1].content)

LangGraph es el motor recomendado actual para agentes en el ecosistema LangChain.

Flujo del agente ​

txt
1. Usuario envia mensaje
2. LLM razona: necesito tool X con args Y
3. Se ejecuta la tool
4. Resultado vuelve al LLM
5. Repite hasta respuesta final o limite de iteraciones

Limite de iteraciones ​

Evita bucles infinitos:

python
agent = create_react_agent(model, tools)
config = {"recursion_limit": 10}

result = agent.invoke({"messages": [...]}, config=config)

Tools peligrosas ​

Nunca expongas sin control:

  • Ejecucion arbitraria de shell.
  • SQL sin parametrizar.
  • Escritura en sistemas de archivos de produccion.

Envuelve con validacion, allowlists y permisos por usuario.

python
ALLOWED_CITIES = {"Madrid", "Barcelona", "Valencia"}

@tool
def get_weather(city: str) -> str:
    """Tiempo en ciudades permitidas."""
    if city not in ALLOWED_CITIES:
        return "Ciudad no permitida"
    return fetch_weather(city)

Agent vs chain fija ​

EnfoqueCuando usarlo
Chain fijaFlujo conocido (RAG -> responder)
AgentEl usuario pide tareas variables; varias tools
AgentExploracion multi-paso con decisiones

Un RAG simple no necesita agente; un copiloto que consulta docs, tickets y metricas si.

Herramientas multiples y conflictos ​

  • Nombres cortos y descriptivos (search_docs, no tool1).
  • Docstrings unicos; evita descripciones solapadas.
  • Pocas tools por agente (5–10); mas confunde al modelo.

Streaming con agentes ​

python
for chunk in agent.stream(
    {"messages": [("human", "Multiplica 7 por 6")]},
    config={"recursion_limit": 5},
    stream_mode="values",
):
    last = chunk["messages"][-1]
    if hasattr(last, "content"):
        print(last.content)

Buenas practicas ​

  • Tests unitarios de cada tool sin LLM.
  • Logs de cada invocacion: tool, args, resultado, latencia.
  • Timeouts en llamadas externas.
  • Human-in-the-loop para acciones destructivas.
  • Versiona el system prompt del agente.

Errores habituales ​

  • Tools sin docstring o con descripcion vaga.
  • Demasiadas tools para el mismo dominio.
  • Confiar en argumentos del LLM sin validar tipos.
  • Sin limite de recursion (bucles costosos).
  • Ejecutar codigo arbitrario que devuelve el modelo.

Ejercicio guiado ​

  1. Crea dos tools: calculadora y conversor de unidades.
  2. Monta un agente ReAct con Ollama.
  3. Prueba una pregunta que requiera ambas tools.
  4. Anade recursion_limit y observa que pasa con preguntas ambiguas.

Siguiente paso ​

El capitulo 4 integra retrievers y vector stores en cadenas RAG con LangChain.