Agente copilot

npm install -g @github/copilot
copilot

ollama

docker run --name ollama -v /media/jose/2Tb1/ia/usr_local_lib:/usr/local/lib -v /media/jose/2Tb1/ia/ollama/root_ollama:/root/.ollama -ti debian
apt-get install -f curl

Instalamos ollama. Lo instala en /usr/local/lib/ollama

curl -fsSL https://ollama.com/install.sh | sh

Arrancamos ollama:

ollama serve

Descargamos un LLM. Lo descarga en /root/.ollama

ollama pull gemma2:9b
ollama pull llama3.1:70b
ollama pull llama3.1:8b
apt install python3.13-venv
python3 -m venv /ollama-agente
source /ollama-agente/bin/activate

Para ejecutar un modelo concreto:

ollama run llama3.1:8b

Instalamos las tools:

pip install langchain langchain-ollama langchain_community

1. Código para usar el agente:

Configuración Inicial y Modelo Asegúrate de que Ollama esté ejecutándose (ollama serve) y luego define el modelo que usarás.

from langchain_community.chat_models import ChatOllama
from langchain_core.prompts import ChatPromptTemplate
from langchain_core.output_parsers import StrOutputParser

# 1. Definir el modelo que usará el agente
MODELO_OLLAMA = "llama3.1:8b" 

# 2. Inicializar el LLM
# Esto crea una conexión con tu modelo local de Ollama
llm = ChatOllama(model=MODELO_OLLAMA)

2. Definición de la Herramienta (Tool)

En este paso, defines qué acciones puede tomar tu agente. Para que el modelo pueda ejecutar comandos en la terminal (como pediste antes), adaptaremos la función en el formato de LangChain.

from langchain_core.tools import tool
import subprocess

# Usamos el decorador @tool de LangChain para convertir la función Python 
# en una herramienta que el LLM puede entender.

@tool
def ejecutar_comando_terminal(comando: str) -> str:
    """
    Ejecuta un comando en la terminal (shell) del sistema operativo.
    Usa esta herramienta para probar código o scripts como Playwright.
    """
    try:
        resultado = subprocess.run(
            comando,
            shell=True,
            capture_output=True,
            text=True,
            timeout=30
        )
        
        if resultado.returncode == 0:
            return f"Comando ejecutado con éxito. Salida:\n{resultado.stdout}"
        else:
            # Devuelve el error al LLM para que pueda intentar depurarlo
            return f"Error en el comando (código: {resultado.returncode}). Error:\n{resultado.stderr}\nSalida:\n{resultado.stdout}"

    except Exception as e:
        return f"Excepción al ejecutar el comando: {e}"

# Lista de herramientas disponibles para el agente
tools = [ejecutar_comando_terminal]

3. Unir y Ejecutar el Agente (El Bucle de Tools Calling)

Aquí es donde se produce la magia. LangChain usa el método .bind_tools() para informar al modelo de Ollama sobre las funciones que tiene disponibles. LangChain se encarga automáticamente del bucle de “solicitar herramienta → ejecutarla → enviar el resultado de vuelta al modelo”.

# 1. Unir el LLM con las herramientas
# LangChain usa las descripciones de las funciones (docstrings) para crear el JSON Schema 
# que Ollama necesita.
llm_with_tools = llm.bind_tools(tools)

# 2. Definir la pregunta para el agente
user_question = "Asumiendo que tengo un archivo llamado 'test_playwright.js', ejecuta el comando 'node test_playwright.js' en la terminal y dame el resumen del resultado."

# 3. Primer paso: El modelo decide si usa la herramienta
print("--- Paso 1: Agente decidiendo la acción ---")
response = llm_with_tools.invoke(user_question)

# 4. Comprobar si hay llamadas a herramientas
if response.tool_calls:
    print(f"🛠️ Llamada a herramienta detectada: {response.tool_calls[0].get('name')}")
    
    # 5. Ejecutar la herramienta (Manualmente para este ejemplo, pero LangChain tiene wrappers de Agente que lo automatizan)
    
    # Extraer los argumentos que el LLM generó
    tool_call = response.tool_calls[0]
    func_name = tool_call['name']
    func_args = tool_call['args']
    
    # Ejecutar la función real usando los argumentos
    tool_output = ejecutar_comando_terminal(**func_args)
    
    print(f"   -> Comando a ejecutar: {func_args.get('comando')}")
    print(f"   -> Salida de la terminal: \n{tool_output[:100]}...") # Mostrar un fragmento

    # 6. Segundo paso: Enviar el resultado de vuelta al modelo
    print("\n--- Paso 2: Enviando el resultado al LLM para la respuesta final ---")
    
    # Para la respuesta final, es necesario enviar el historial completo, incluyendo 
    # la respuesta del LLM y el resultado de la herramienta.
    
    messages = [
        ("user", user_question),
        response, # Respuesta del LLM que contenía la Tool Call
        ("tool", tool_output) # Resultado de la ejecución de la herramienta
    ]
    
    # Llamar al modelo por segunda vez con el resultado
    final_response = llm.invoke(messages)
    
    print("\n✅ RESPUESTA FINAL DEL AGENTE:")
    print(final_response.content)

else:
    # Si no hay Tool Call, el modelo responde directamente
    print(f"✅ RESPUESTA DIRECTA:\n{response.content}")

Todo el script junto

import subprocess
from langchain_community.chat_models import ChatOllama
from langchain_core.tools import tool

# --- PARTE 1: Configuración Inicial y Modelo ---

# Asegúrate de que Ollama esté ejecutándose (ollama serve)
MODELO_OLLAMA = "llama3.1:8b" 
llm = ChatOllama(model=MODELO_OLLAMA)

# ----------------------------------------------------------------------
# --- PARTE 2: Definición de la Herramienta (Tool) ---

@tool
def ejecutar_comando_terminal(comando: str) -> str:
    """
    Ejecuta un comando en la terminal (shell) del sistema operativo.
    Usa esta herramienta para probar código o scripts como Playwright.
    """
    print(f"\n[EJECUTANDO COMANDO EN TERMINAL]: {comando}")
    try:
        # Usa subprocess para ejecutar el comando
        resultado = subprocess.run(
            comando,
            shell=True,
            capture_output=True,
            text=True,
            timeout=30 # Límite de tiempo de 30 segundos
        )
        
        if resultado.returncode == 0:
            return f"Comando ejecutado con éxito. Salida:\n{resultado.stdout}"
        else:
            # Devuelve el error para que el LLM lo analice
            return f"Error en el comando (código: {resultado.returncode}). Error:\n{resultado.stderr}\nSalida:\n{resultado.stdout}"

    except Exception as e:
        return f"Excepción al ejecutar el comando: {e}"

# Lista de herramientas disponibles para el agente
tools = [ejecutar_comando_terminal] 

# ----------------------------------------------------------------------
# --- PARTE 3: Unir y Ejecutar la Lógica del Agente ---

# 1. Unir el LLM con las herramientas
# Esto crea una "cadena" o "Runnable" que sabe cómo manejar las llamadas a herramientas.
llm_with_tools = llm.bind_tools(tools)

# 2. Definir la pregunta para el agente
# **NOTA IMPORTANTE:** Para esta prueba, asegúrate de tener un script 'test_playwright.js' 
# o un entorno Playwright configurado que responda a este comando.
user_question = (
    "Asumiendo que tengo un archivo llamado 'test_playwright.js' listo para usar, "
    "ejecuta el comando 'node test_playwright.js' en la terminal. "
    "Analiza la salida de la terminal y dame un resumen claro del resultado."
)

print(f"Pregunta al agente: {user_question}")

# 3. Primer Paso: El modelo decide si usa la herramienta
response = llm_with_tools.invoke(user_question)

if response.tool_calls:
    
    # 4. El Agente ejecuta la Herramienta
    tool_call = response.tool_calls[0]
    func_args = tool_call['args']
    tool_output = ejecutar_comando_terminal(**func_args)
    
    # 5. Segundo Paso: Enviar el resultado de vuelta al modelo para la respuesta final
    
    # Prepara el historial completo, incluyendo el resultado de la herramienta
    messages = [
        ("user", user_question),
        response, # La respuesta del LLM con la Tool Call
        ("tool", tool_output) # El resultado de la terminal
    ]
    
    # Llama al modelo por segunda vez para que genere la respuesta final
    final_response = llm.invoke(messages)
    
    print("\n\n#####################################################")
    print("RESPUESTA FINAL DEL AGENTE (Basada en la ejecución):")
    print(final_response.content)
    print("#####################################################")

else:
    # Si no hay Tool Call, el modelo responde directamente (no debería pasar en este caso)
    print(f"\n RESPUESTA DIRECTA (sin usar la herramienta):\n{response.content}")