JoseAndresLopez's picture
Upload agent.py with huggingface_hub
d4920a2 verified
Raw
History Blame Contribute Delete
4.61 kB
"""Agente autónomo con LangChain + Groq + tool calling."""
import os
from typing import Iterator, Any
from langchain_groq import ChatGroq
from langchain_core.prompts import ChatPromptTemplate, MessagesPlaceholder
from langchain_classic.agents import AgentExecutor, create_tool_calling_agent
from tools import ALL_TOOLS
SYSTEM_PROMPT = """Eres un agente autónomo que razona paso a paso para resolver tareas.
Tienes acceso a estas herramientas:
- web_search: busca información actualizada en internet
- python_repl: ejecuta código Python para cálculos y análisis
- read_file: lee archivos subidos (PDF, CSV, TXT)
- get_weather: obtiene el tiempo actual de una ciudad
REGLAS:
1. Si ya sabes la respuesta con certeza desde tu entrenamiento, responde DIRECTAMENTE sin usar herramientas.
2. Usa web_search SOLO para datos en tiempo real: precios, noticias de hoy, eventos recientes.
3. Usa python_repl para cálculos numéricos, nunca calcules mentalmente.
4. Usa get_weather SIEMPRE que pregunten por el tiempo meteorológico de cualquier ciudad. Nunca respondas sobre el tiempo sin llamar a esta herramienta.
5. Usa read_file solo cuando el usuario haya subido un archivo.
6. Responde siempre en el mismo idioma que el usuario.
7. Si piden tabla o comparativa, usa formato tabla markdown (| col | col |).
FORMATO DE CÓDIGO PYTHON (crítico):
- Usa SIEMPRE saltos de línea reales entre sentencias, NUNCA en una sola línea.
- Indentación de 4 espacios para bloques (for, if, def, while).
- NO uses punto y coma para separar sentencias."""
def build_agent(
model: str = "llama-3.3-70b-versatile",
temperature: float = 0.1,
verbose: bool = True,
max_iterations: int = 10,
) -> AgentExecutor:
"""Construye el agente con las herramientas registradas."""
groq_key = os.getenv("GROQ_API_KEY")
if not groq_key:
raise ValueError(
"GROQ_API_KEY no configurada. Añádela en .env "
"(consigue una gratis en https://console.groq.com)"
)
llm = ChatGroq(
model=model,
temperature=temperature,
api_key=groq_key,
)
prompt = ChatPromptTemplate.from_messages([
("system", SYSTEM_PROMPT),
MessagesPlaceholder(variable_name="chat_history", optional=True),
("human", "{input}"),
MessagesPlaceholder(variable_name="agent_scratchpad"),
])
agent = create_tool_calling_agent(llm, ALL_TOOLS, prompt)
executor = AgentExecutor(
agent=agent,
tools=ALL_TOOLS,
verbose=verbose,
max_iterations=max_iterations,
return_intermediate_steps=True,
handle_parsing_errors=True,
)
return executor
def run_agent_stream(executor: AgentExecutor, user_input: str, chat_history=None, _retry: bool = True) -> Iterator[dict]:
chat_history = chat_history or []
try:
for chunk in executor.stream({"input": user_input, "chat_history": chat_history}):
if "actions" in chunk:
for action in chunk["actions"]:
yield {"type": "tool_start", "tool": action.tool, "input": action.tool_input}
if "steps" in chunk:
for step in chunk["steps"]:
yield {"type": "tool_end", "tool": step.action.tool, "output": str(step.observation)[:2000]}
if "output" in chunk:
yield {"type": "final", "output": chunk["output"]}
except Exception as e:
err = str(e).lower()
groq_tool_error = (
"tool call validation failed" in err
or "failed to call a function" in err
or "failed_generation" in err
)
if _retry and groq_tool_error:
# Retry telling the model to answer directly without tools
direct_prompt = (
f"{user_input}\n\n"
"(Responde directamente desde tu conocimiento sin usar herramientas externas.)"
)
try:
result = executor.invoke({"input": direct_prompt, "chat_history": chat_history})
yield {"type": "final", "output": result.get("output", str(result))}
except Exception as e2:
yield {"type": "error", "output": f"Error: {e2}"}
else:
yield {"type": "error", "output": f"Error en el agente: {e}"}
def run_agent_sync(executor: AgentExecutor, user_input: str, chat_history=None) -> dict:
"""Ejecuta el agente sin streaming (útil para tests)."""
chat_history = chat_history or []
result = executor.invoke({"input": user_input, "chat_history": chat_history})
return result