Juntar las piezas
Un agente de IA pequeño es un solo bucle que planifica, llama a herramientas, guarda notas y para según una regla. Has construido cada pieza por separado. La habilidad está en conectarlas para que el bucle sea fácil de probar.
Un bucle que solo funciona con un modelo real no se puede probar. Uno que corre sobre un modelo con guion, sí.
Al final de esta lección
Nota
Puedo construir un agente pequeño que planifica, llama a herramientas, recuerda y para.
Palabras clave
| Palabra | Qué significa |
|---|---|
| Bucle del agente | elegir una acción, ejecutarla, anotarla y repetir |
| Modelo con guion | un sustituto que devuelve acciones fijas |
| Rastro | una lista de lo que hizo cada paso |
| Acción final | la acción que acaba una ejecución |
| Doble de prueba | un sustituto que se usa en lugar de la pieza real |
Las celdas que rellenan los estudiantes quedan en blanco en esta vista previa.
El bucle del agente en una imagen
En cada vuelta se comprueba primero el presupuesto. El modelo elige una acción. Una acción final acaba la ejecución como terminada. Cualquier otra acción ejecuta una herramienta y anota el resultado.
Después el bucle cuenta los fallos seguidos. Suficientes fallos acaban la ejecución como atascada. Si no, da otra vuelta.
Escribir la ayuda del modelo, parte 1
docker exec -w /home/node/project agent sh -c "printf '%s\n' 'const base = process.env.AI_URL || \"http://ai:4000\";' 'async function ask(messages, sample, max) {' ' try {' ' const res = await fetch(base + \"/v1/chat/completions\", {' ' method: \"POST\",' ' headers: { \"content-type\": \"application/json\", authorization: \"Bearer lab\" },' ' body: JSON.stringify({ model: \"lab\", messages: messages, max_tokens: max || 200 }),' ' signal: AbortSignal.timeout(30000),' ' });' ' if (res.ok === false) throw new Error(\"estado \" + res.status);' ' return (await res.json()).choices[0].message.content;' > model.js"Se muestra aquí y no se ejecuta. Crea una cuenta gratuita para pulsar Ejecutar y escribirlo en el terminal de tu propio laboratorio.
Escribir la ayuda del modelo, parte 2
docker exec -w /home/node/project agent sh -c "printf '%s\n' ' } catch (error) {' ' console.log(\"Muestra grabada: ningún modelo respondió (\" + error.message + \").\");' ' const list = [].concat(sample);' ' const turn = messages.filter(function (m) { return m.role === \"assistant\"; }).length;' ' return list[Math.min(turn, list.length - 1)];' ' }' '}' 'module.exports = { ask };' >> model.js"Se muestra aquí y no se ejecuta. Crea una cuenta gratuita para pulsar Ejecutar y escribirlo en el terminal de tu propio laboratorio.
Escribir el agente pequeño, parte 1
docker exec -w /home/node/project agent sh -c "printf '%s\n' 'const { ask } = require(\"./model\");' 'const PRICES = { pan: 90, leche: 110 };' 'const notes = [];' 'const tools = {' ' get_price: function (item) {' ' if (PRICES[item] === undefined) return { ok: false, text: \"no hay precio de \" + item };' ' return { ok: true, text: item + \" \" + PRICES[item] + \" céntimos\" };' ' },' ' add_note: function (text) { notes.push(text); return { ok: true, text: \"anotada \" + notes.length }; },' '};' > agent1.js"Se muestra aquí y no se ejecuta. Crea una cuenta gratuita para pulsar Ejecutar y escribirlo en el terminal de tu propio laboratorio.
Escribir el agente pequeño, parte 2
docker exec -w /home/node/project agent sh -c "printf '%s\n' 'const script = [' ' { tool: \"get_price\", arg: \"pan\" },' ' { tool: \"get_price\", arg: \"kiwi\" },' ' { tool: \"get_price\", arg: \"leche\" },' ' { tool: \"add_note\", arg: \"pan 90, leche 110\" },' ' { tool: \"finish\", arg: \"El pan y la leche cuestan 200 céntimos.\" },' '];' '// Un modelo con guion da la misma acción en cada ejecución, así que el bucle se puede probar.' 'const scriptedModel = function (turn) { return JSON.stringify(script[turn]); };' >> agent1.js"Se muestra aquí y no se ejecuta. Crea una cuenta gratuita para pulsar Ejecutar y escribirlo en el terminal de tu propio laboratorio.
Escribir el agente pequeño, parte 3
docker exec -w /home/node/project agent sh -c "printf '%s\n' 'async function main() {' ' const budget = Number(process.argv[2] || 6), maxFails = 2;' ' let used = 0, fails = 0, outcome = \"presupuesto\", answer = \"\";' ' while (used < budget && used < script.length) {' ' const action = JSON.parse(scriptedModel(used));' ' used += 1;' ' if (action.tool === \"finish\") { outcome = \"terminado\"; answer = action.arg; break; }' ' const run = tools[action.tool];' ' const r = run ? run(action.arg) : { ok: false, text: \"herramienta desconocida \" + action.tool };' ' fails = r.ok ? 0 : fails + 1;' ' console.log(\"Paso \" + used + \": \" + action.tool + \"(\" + action.arg + \") -> \" + r.text);' ' if (fails === maxFails) { outcome = \"atascado\"; break; }' ' }' ' console.log(\"Resultado: \" + outcome + \" tras \" + used + \" pasos. Notas: \" + JSON.stringify(notes));' >> agent1.js"Se muestra aquí y no se ejecuta. Crea una cuenta gratuita para pulsar Ejecutar y escribirlo en el terminal de tu propio laboratorio.
Escribir el agente pequeño, parte 4
docker exec -w /home/node/project agent sh -c "printf '%s\n' ' if (outcome === \"terminado\") {' ' const request = [{ role: \"user\", content: \"Dile esto a un cliente en una frase amable: \" + answer }];' ' console.log(\"Respuesta: \" + await ask(request, answer, 60));' ' }' '}' 'main();' >> agent1.js"Se muestra aquí y no se ejecuta. Crea una cuenta gratuita para pulsar Ejecutar y escribirlo en el terminal de tu propio laboratorio.
Ejecutar el agente con presupuesto 6
docker exec -w /home/node/project agent node agent1.jsSe muestra aquí y no se ejecuta. Crea una cuenta gratuita para pulsar Ejecutar y escribirlo en el terminal de tu propio laboratorio.
Ejecutarlo otra vez con presupuesto 4
docker exec -w /home/node/project agent node agent1.js 4Se muestra aquí y no se ejecuta. Crea una cuenta gratuita para pulsar Ejecutar y escribirlo en el terminal de tu propio laboratorio.
Una salida posible
| Presupuesto | Qué muestra |
|---|---|
| 6 | El paso 2 falla por el kiwi, luego Resultado: terminado tras 5 pasos, y una respuesta de una frase |
| 4 | Cuatro pasos, luego Resultado: presupuesto tras 4 pasos, y ninguna respuesta |
Las celdas que rellenan los estudiantes quedan en blanco en esta vista previa.
Prueba el bucle con un modelo con guion
Un modelo con guion devuelve las mismas acciones en cada ejecución. Con él puedes probar el bucle para cada resultado: terminado, presupuesto, atascado y guion agotado.
Prueba el modelo real por separado, en lo que mejor hace: elegir una acción sensata. Nunca juzgues el bucle por una sola ejecución con suerte.
Un error frecuente
Advertencia
Mucha gente cree que un agente que funcionó una vez con un modelo real ya está probado. Un modelo da acciones distintas cada vez, así que una buena ejecución demuestra muy poco. Prueba el bucle con un guion y el modelo con muchos casos.