Pedir pasos primero y la respuesta después
Pedir paso a paso significa decirle a un modelo que escriba su razonamiento antes de la respuesta. En una suma o un plan, los pasos pueden hacer más probable que la respuesta sea correcta.
Los pasos cuestan palabras, y las palabras cuestan dinero y tiempo. La destreza está en saber cuándo pedirlos y en comprobar la respuesta cuando los pides.
Al final de esta lección
Nota
Puedo pedir pasos cuando ayudan y no pedirlos cuando no.
Palabras clave
| Palabra | Qué significa |
|---|---|
| Paso | un trozo pequeño del razonamiento |
| Razonamiento | los pasos que llevan a una respuesta |
| Línea de respuesta | la última línea, que solo trae la respuesta |
| Comprobación | una prueba de que la respuesta es correcta |
| Coste | los tokens y el tiempo que gasta una respuesta |
| Grabada | una respuesta guardada antes, no hecha ahora |
Las celdas que rellenan los estudiantes quedan en blanco en esta vista previa.
¿Por qué pueden ayudar los pasos?
Un modelo escribe un trozo de texto cada vez, y cada trozo puede usar lo que ya escribió. Con el razonamiento en la página, el paso siguiente lo aprovecha. Llegar a 30 es más fácil pasando por 2, luego 6 y luego 30.
Esto ayuda en sumas, planes y reglas con varias partes. Ayuda poco en una consulta simple, como la capital de un país.
Cuándo pedir pasos
| Pregunta | ¿Pasos? | Por qué |
|---|---|---|
| Coste total de 15 viajes en autobús a 2 euros | Sí | Dos cuentas encadenadas |
| ¿Cuál de estas normas incumplió la persona? | Sí | Varias partes que revisar |
| Reescribe esta línea con más educación | No | Un solo movimiento, nada que calcular |
| ¿Este comentario es bueno o malo? | No | Una etiqueta es toda la respuesta |
Las celdas que rellenan los estudiantes quedan en blanco en esta vista previa.
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 separador de pasos, parte 1
docker exec -w /home/node/project agent sh -c "printf '%s\n' 'const { ask } = require(\"./model\");' 'const QUESTION = \"Un billete de autobús cuesta 2 euros. Marta hace 3 viajes al día durante 5 días. ¿Cuánto gasta en total?\";' 'const RECORDED = \"Paso 1: Un viaje cuesta 2 euros.\nPaso 2: 3 viajes al día cuestan 6 euros.\nPaso 3: 5 días cuestan 30 euros.\nRespuesta: 30 euros\";' > steps3.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 separador de pasos, parte 2
docker exec -w /home/node/project agent sh -c "printf '%s\n' 'function split(reply) {' ' const steps = [];' ' let answer = \"\";' ' for (const line of reply.split(\"\n\")) {' ' if (line.startsWith(\"Paso \")) steps.push(line.slice(line.indexOf(\":\") + 1).trim());' ' if (line.startsWith(\"Respuesta:\")) answer = line.slice(10).trim();' ' }' ' return { steps: steps, answer: answer };' '}' 'function show(label, reply) {' ' const r = split(reply);' ' console.log(label + \": \" + r.steps.length + \" pasos, respuesta \" + (r.answer || \"ninguna\"));' '}' >> steps3.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 separador de pasos, parte 3
docker exec -w /home/node/project agent sh -c "printf '%s\n' 'async function main() {' ' show(\"grabada\", RECORDED);' ' const form = \" Trabaja en pasos cortos que empiecen por Paso 1: y así. Termina con una línea que empiece por Respuesta:\";' ' const reply = await ask([{ role: \"user\", content: QUESTION + form }], RECORDED, 150);' ' show(\"modelo\", reply.text);' '}' 'main();' >> steps3.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 y separa una respuesta
docker exec -w /home/node/project agent node steps3.jsSe muestra aquí y no se ejecuta. Crea una cuenta gratuita para pulsar Ejecutar y escribirlo en el terminal de tu propio laboratorio.
Qué imprime el Run
La primera línea separa una respuesta grabada: 3 pasos, respuesta 30 euros. La segunda hace lo mismo con el modelo del laboratorio. Sin modelo, imprime una Muestra grabada y la segunda línea es igual que la primera.
Un modelo puede no respetar tu formato. Si su línea dice respuesta ninguna, no escribió una línea que empiece por Respuesta:. Tu código debe contar con eso.
Un error frecuente
Advertencia
Mucha gente cree que, si los pasos parecen sensatos, la respuesta es correcta. Una respuesta puede mostrar pasos ordenados y luego escribir otro resultado. Compara siempre la línea de respuesta con el último paso, o con un valor que conozcas.