Escribir una tarea para un agente de código
Una tarea para un agente de código es la instrucción escrita de la que parte el agente. La tarea decide lo que recibes, así que una tarea clara te ahorra horas de comprobación.
Un agente de código es un programa que usa un modelo de lenguaje para leer un repositorio, cambiar archivos y ejecutar comandos. «Mejora la tienda» puede volver con cuarenta archivos cambiados. Una tarea clara vuelve con un cambio pequeño que puedes comprobar.
Al final de esta lección
Nota
Puedo escribir una especificación de tarea que un agente de código pueda terminar y yo pueda comprobar.
Palabras clave
| Palabra | Qué significa | Ejemplo |
|---|---|---|
| Agente de código | un programa que lee código, edita archivos y ejecuta comandos con un modelo | |
| Especificación de tarea | instrucciones escritas para un único trabajo | |
| Alcance | la parte del trabajo que se incluye | |
| Terminado cuando | una comprobación que muestra que el trabajo está hecho | node --test pasa |
| Fuera de alcance | lo que el trabajo no debe tocar |
Las celdas que rellenan los estudiantes quedan en blanco en esta vista previa.
Una tarea para un agente tiene cinco partes
El objetivo dice qué cambia, en una frase. El alcance dice qué parte del trabajo se incluye. La lista de archivos dice dónde puede escribir el agente.
Terminado cuando nombra una comprobación que puedes ejecutar, como un comando de tests. Fuera de alcance dice qué debe quedar como está. Un agente casi nunca para a preguntar, así que cada parte responde algo que adivinaría.
Ejemplo resuelto: tarea vaga y tarea clara
| Parte | Tarea vaga | Tarea clara |
|---|---|---|
| Objetivo | Mejorar la tienda | Añadir un descuento de estudiante del 10 % a total |
| Alcance | No se dice | solo total |
| Archivos | No se dice | shop.js y shop.test.js |
| Terminado cuando | No se dice | node --test pasa con 2 tests nuevos |
| Fuera de alcance | No se dice | los precios y asEuros |
Las celdas que rellenan los estudiantes quedan en blanco en esta vista previa.
Un error frecuente
Advertencia
Mucha gente cree que un agente pregunta cuando una tarea no está clara. La mayoría adivina y sigue, así que un hueco se convierte en una decisión que no tomaste tú. Escribe el fuera de alcance y el terminado cuando antes de arrancar el agente.
Un script revisa la tarea antes
Una lista de comprobación encuentra los huecos habituales en un segundo. Este script lleva tres especificaciones grabadas, A, B y C. Busca partes que faltan, palabras vagas como «mejorar», más de tres archivos y un terminado cuando sin test.
Aquí nada arranca el agente. El Run solo revisa las palabras, así que sus tres primeras líneas son iguales para todos.
Escribe el ayudante 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\";' '// Los tokens de una respuesta, o null si no trae ninguno.' 'function count(data, name) {' ' return data.usage && typeof data.usage[name] === \"number\" ? data.usage[name] : null;' '}' > 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.
Escribe el ayudante del modelo, parte 2
docker exec -w /home/node/project agent sh -c "printf '%s\n' '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 || 100 }),' ' signal: AbortSignal.timeout(30000),' ' });' ' if (res.ok === false) throw new Error(\"estado \" + res.status);' ' const d = await res.json();' ' return { text: d.choices[0].message.content, inTokens: count(d, \"prompt_tokens\"), outTokens: count(d, \"completion_tokens\"), recorded: false };' ' } catch (error) {' ' console.log(\"Muestra grabada: ningún modelo respondió (\" + error.message + \").\");' ' return { text: sample, inTokens: null, outTokens: null, recorded: true };' ' }' '}' '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.
Escribe el revisor de especificaciones, parte 1
docker exec -w /home/node/project agent sh -c "printf '%s\n' 'const { ask } = require(\"./model\");' 'const VAGUE = [\"mejor\", \"mejorar\", \"limpiar\", \"ordenar\", \"bonito\", \"bien\"];' 'const PARTS = [\"goal\", \"scope\", \"files\", \"done_when\", \"out_of_scope\"];' 'const specs = {' ' \"A\": { goal: \"Mejorar la tienda y limpiar el código\" },' ' \"B\": { goal: \"Añadir un descuento de estudiante del 10 por ciento a total\", scope: \"solo total\",' ' files: [\"shop.js\", \"shop.test.js\", \"prices.js\", \"README.md\"], done_when: \"node --test pasa\",' ' out_of_scope: \"los precios\" },' ' \"C\": { goal: \"Añadir un descuento de estudiante del 10 por ciento a total\", scope: \"solo total\",' ' files: [\"shop.js\", \"shop.test.js\"], done_when: \"node --test pasa con 2 tests nuevos\",' ' out_of_scope: \"los precios y asEuros\" },' '};' > spec.js"Se muestra aquí y no se ejecuta. Crea una cuenta gratuita para pulsar Ejecutar y escribirlo en el terminal de tu propio laboratorio.
Escribe el revisor de especificaciones, parte 2
docker exec -w /home/node/project agent sh -c "printf '%s\n' 'function problems(s) {' ' const out = PARTS.filter(function (p) { return s[p] === undefined || s[p].length === 0; })' ' .map(function (p) { return \"falta \" + p; });' ' if (s.goal) {' ' const words = s.goal.toLowerCase().split(\" \");' ' VAGUE.forEach(function (v) { if (words.indexOf(v) >= 0) out.push(\"vaga: \" + v); });' ' }' ' if (s.files && s.files.length > 3) out.push(\"demasiados archivos\");' ' if (s.done_when && s.done_when.indexOf(\"test\") < 0) out.push(\"done_when sin test\");' ' return out;' '}' >> spec.js"Se muestra aquí y no se ejecuta. Crea una cuenta gratuita para pulsar Ejecutar y escribirlo en el terminal de tu propio laboratorio.
Escribe el revisor de especificaciones, parte 3
docker exec -w /home/node/project agent sh -c "printf '%s\n' 'async function main() {' ' Object.keys(specs).forEach(function (name) {' ' const found = problems(specs[name]);' ' console.log(\"especificación \" + name + \": \" + (found.length === 0 ? \"lista\" : \"necesita cambios \" + JSON.stringify(found)));' ' });' ' const q = \"En una frase corta: ¿por qué una tarea para un agente de código necesita una comprobación de terminado?\";' ' const sample = \"Sin comprobación, el agente no sabe cuándo parar y tú no sabes si el trabajo está bien hecho.\";' ' const reply = await ask([{ role: \"user\", content: q }], sample, 60);' ' console.log(\"el modelo dijo: \" + reply.text);' '}' 'main();' >> spec.js"Se muestra aquí y no se ejecuta. Crea una cuenta gratuita para pulsar Ejecutar y escribirlo en el terminal de tu propio laboratorio.
Ejecuta el revisor de especificaciones
docker exec -w /home/node/project agent node spec.jsSe muestra aquí y no se ejecuta. Crea una cuenta gratuita para pulsar Ejecutar y escribirlo en el terminal de tu propio laboratorio.
Lo que imprime el Run
| Línea | Lo que muestra |
|---|---|
| especificación A: necesita cambios [...] | Faltan cuatro partes y hay dos palabras vagas |
| especificación B: necesita cambios ["demasiados archivos"] | Cuatro archivos son demasiados para una tarea |
| especificación C: lista | Están todas las partes y la comprobación es un test |
| el modelo dijo: ... | Una frase del laboratorio. Una línea de Muestra grabada si ningún modelo responde |
Las celdas que rellenan los estudiantes quedan en blanco en esta vista previa.