HiAPI
Blog

Guía de uso

Grok 4.7: recopilatorio de prompts con 5 escenarios listos para copiar

5 prompts ya ejecutados: diagnóstico de concurrencia, revisión de código JSON, comparación de soluciones, explicación de conceptos y análisis con pandas, con salidas reales y coste por ejecución

Oct 29, 2026
Grok 4.7: recopilatorio de prompts con 5 escenarios listos para copiar

TL;DR: 5 escenarios, todos ejecutados realmente con grok-4.7 en el entorno de producción de HiAPI, con la salida pegada tal cual. El coste por consulta es de $0.007–0.021; las 5 juntas cuestan unos $0.06. El enlace bajo cada prompt rellena automáticamente el mismo prompt en la página del modelo; basta con enviarlo para reproducirlo. Grok 4.7 ya está disponible en HiAPI: abre la página del modelo y pruébalo directamente; los nuevos usuarios registrados reciben 200 créditos.

Escenario 1: diagnosticar un bloqueo por concurrencia

La causa raíz es que el objeto de respuesta no se libera y la conexión sigue ocupando una ranura del pool del connector.

El ClientResponse devuelto por session.get() solo devuelve la conexión al TCPConnector cuando se llama a release() / close() (o cuando sale del gestor de contexto asíncrono). La forma actual no tiene ni async with ni release() explícito. Leer el body no devuelve la conexión; además, la respuesta y la connection mantienen una referencia circular, así que solo se libera cuando el GC de ciclos ejecuta __del__.

Por defecto, cada ClientSession tiene un límite de 100 conexiones. Los 20 workers tienen cada uno su propia session y envían peticiones en serie; cada worker procesa unos 250 URL. Si las conexiones no se devuelven:

  1. El servidor aplica un RST a las conexiones ocupadas por timeout de inactividad o por límite de conexiones; aiohttp emite ConnectionResetError en la capa de protocolo (no necesariamente se lanza desde tu await, así que except no lo captura ni puede limpiarlo).
  2. La ranura sigue ocupada. Al llegar a 100, la siguiente llamada a session.get() se queda bloqueada en connector.acquire(), y esa espera a menudo no está sujeta al timeout.
  3. Todos los workers se atascan en acquire, dejan de llamar a queue.get() y dejan de llamar a task_done(). El event loop no tiene nuevas asignaciones, el GC de ciclos deja de ejecutarse, __del__ no puede recuperar conexiones y se produce un interbloqueo. queue.join() tampoco termina nunca.

except Exception: pass solo se traga las excepciones de la corrutina del usuario, no libera conexiones, así que «error» y «bloqueo» aparecen juntos.

Cambio mínimo:

async def fetch(url, session):
    async with session.get(url) as r:
        return await r.json()

async with pasa por __aexit__ → release() tanto en la ruta de retorno normal como en la de excepción:

  • La conexión vuelve inmediatamente al pool, las ranuras no se acumulan hasta 100, session.get() ya no se bloquea para siempre en acquire y los workers pueden seguir consumiendo la cola. Esto resuelve el bloqueo.
  • La conexión ya no queda ocupada mucho tiempo esperando el RST del servidor, y el ConnectionResetError de la capa de protocolo desaparece; incluso si se produce una desconexión real al leer el body, el gestor de contexto sigue devolviendo/cerrando esa conexión, y un fallo no deja el pool atascado. Esto resuelve el error y garantiza que la cola siga avanzando tras el error.

Prompt completo:

下面这段 Python 代码在并发量稍大时会随机出现 ConnectionResetError,随后整个 worker 卡死不再消费队列。请找出根本原因,给出最小改动的修复,并解释为什么你的修复能同时解决「报错」和「卡死」两个问题。

```python
import asyncio, aiohttp

async def fetch(url, session):
    r = await session.get(url)
    return await r.json()

async def worker(queue):
    session = aiohttp.ClientSession()
    while True:
        url = await queue.get()
        try:
            data = await fetch(url, session)
            print(data)
        except Exception:
            pass
        queue.task_done()

async def main():
    queue = asyncio.Queue()
    for i in range(5000):
        queue.put_nowait(f"https://api.example.com/item/{i}")
    workers = [asyncio.create_task(worker(queue)) for _ in range(20)]
    await queue.join()

asyncio.run(main())
```

Generar con este prompt →

grok-4.7, nivel de razonamiento high por defecto, max_tokens limitado a 6000, ejecución real 107.7s, entrada 3,572 / salida 7,301 tokens, unos $0.021.

Da de una vez el síntoma, el código y la restricción de «explicar ambos problemas a la vez»; solo así el modelo localiza la causa raíz en la capa del pool de conexiones, en lugar de quedarse en un parche superficial de try-catch.

Escenario 2: revisión de código con salida JSON

{"issues":[{"severity":"high","line":8,"problem":"La comprobación de saldo y el cargo están separados; existe una condición de carrera TOCTOU: peticiones concurrentes pueden pasar la comprobación de saldo y duplicar el cargo, provocando sobregiro o doble gasto","fix":"Cambiar a una única actualización condicional (por ejemplo, $inc solo si balance>=amount) o usar bloqueo de fila/bloqueo optimista dentro de una transacción para hacer la comprobación y el cargo de forma atómica"},{"severity":"high","line":9,"problem":"El cargo y el abono son dos escrituras independientes, sin transacción; si la primera tiene éxito y la segunda falla, el dinero desaparece de from y no se puede revertir","fix":"Poner ambas actualizaciones en la misma transacción de base de datos, de modo que cualquier fallo revierta todo, y confirmar que la cuenta to existe antes de hacer commit"}]
,"summary":"Este endpoint de transferencia carece de transacción atómica, autenticación y validación de parámetros; bajo concurrencia puede provocar doble gasto o pérdida de dinero, y en la ruta de excepción deja la petición colgada."}

(Extracto: la salida original es un JSON de una sola línea; se conservan los dos primeros problemas de severidad high y el summary, el resto se omite)

Prompt completo:

请审查下面的 Node.js 路由代码,找出所有会导致生产事故的问题(安全、并发、资源泄漏都算),按严重程度排序。严格用 JSON 输出,格式:{"issues": [{"severity": "high|medium|low", "line": 行号, "problem": "问题", "fix": "修法"}], "summary": "一句话总结"}。

```js
const express = require('express');
const db = require('./db');
const router = express.Router();

router.post('/transfer', async (req, res) => {
  const { from, to, amount } = req.body;
  const fromAccount = await db.findOne({ id: from });
  if (fromAccount.balance >= amount) {
    await db.update({ id: from }, { $inc: { balance: -amount } });
    await db.update({ id: to }, { $inc: { balance: amount } });
    res.json({ ok: true });
  } else {
    res.status(400).json({ ok: false });
  }
});

module.exports = router;
```

Generar con este prompt →

grok-4.7, nivel de razonamiento high por defecto, max_tokens limitado a 4000, ejecución real 40.1s, entrada 3,576 / salida 2,734 tokens, unos $0.010.

Si escribes directamente en el prompt el esqueleto JSON que quieres (nombres de campos, reglas de ordenación), grok-4.7 respeta estrictamente el formato y la salida se puede integrar directamente en el pipeline.

Escenario 3: comparación de soluciones técnicas

Recomiendo «latido de actividad + TTL de Redis + sondeo corto bajo demanda», sin WebSocket/SSE para envío masivo de presencia. Que el indicador se ponga gris a los 5 minutos no requiere notificaciones al segundo; con 100k DAU el sondeo aguanta perfectamente y encaja mejor con Next.js.

Comparación de soluciones

Sondeo SSE WebSocket
Dirección El cliente hace pull El servidor envía en un sentido Bidireccional
Encaje con «gris tras 5 minutos sin actividad» Alto. Refrescar cada 30–60 s es suficiente para el punto verde Medio. El envío es más rápido, pero el paso a gris por timeout hay que calcularlo aparte Bajo a medio. Estar conectado ≠ estar activo
Adaptación a Next.js La mejor. Un Route Handler normal Mala. Las conexiones largas no encajan con Serverless ni con múltiples instancias La peor. Requiere un proceso WS independiente, sesiones pegajosas o un tercero
Coste de conexiones Sin conexiones largas 1 por cada usuario en línea 1 por cada usuario en línea, más heartbeat para mantenerla viva
Escalado Sin estado, escalado horizontal sencillo Hay que gestionar desconexiones, reconexiones y fan-out entre instancias Igual, pero más pesado
Modo de fallo Falla una petición, se vuelve a consultar en la siguiente Tras una desconexión el estado deja de actualizarse y hay que recuperarlo Igual, con una pasarela más compleja
¿Vale la pena con 100k DAU? Sí, como opción por defecto Solo si ya existe un canal de notificaciones push Solo si ya existe una pasarela de chat/colaboración

Cálculo aproximado del pico: 100 mil usuarios activos diarios, con un 5%–15% en línea a la vez, unas 5 mil–15 mil conexiones. Un heartbeat cada 45 segundos son unas 100–300 escrituras/s; cada persona consulta cada 30 segundos el estado de un lote de usuarios visibles, y las lecturas también están en la zona cómoda de Redis. El cuello de botella no estará en el «punto verde».

Recomendación y motivos

Usa Redis como fuente de verdad de la presencia, PostgreSQL solo para el last_seen en frío, y que el cliente solo consulte a los usuarios que hay en pantalla.

  1. La semántica del producto es «5 minutos sin actividad», no «el TCP sigue conectado». Una página abierta sin interacción debe ponerse gris, así que incluso con WS haría falta un heartbeat de actividad aparte. La conexión por sí sola no resuelve el requisito.
  2. El punto verde admite un margen de decenas de segundos. Un intervalo de sondeo de 30–60 segundos es suficiente frente a una ventana de 5 minutos.
  3. Next.js (especialmente en Vercel / Serverless) no es adecuado para sostener conexiones largas. WS/SSE te arrastran a un servicio de tiempo real independiente, rutas pegajosas y compensación de desconexiones, con muy poco beneficio.
  4. Quién debe ver el estado de quién suele ser local (amigos, lista de conversaciones, avatares de la página actual), no una difusión global. Consultar Redis por lotes de ids es un orden de magnitud más sencillo que mantener relaciones de suscripción.
  5. La expiración de claves de Redis expresa de forma natural «desconexión por timeout», sin necesidad de keyspace notifications ni de escanear tablas enteras.
存在即在线 a nivel de usuario (solución principal recomendada):

```text
presence:u:{userId}   STRING  valor = unix en milisegundos del servidor
                      TTL = 300 segundos
                      en el heartbeat, SET key value EX 300
                      en línea = la clave existe
```

No uses la hora del cliente. No tiene sentido que el TTL sea 2–3 veces mayor que el intervalo de heartbeat; aquí el heartbeat es de 45–60 segundos y el TTL de 300 segundos, así que perder dos o tres heartbeats sigue contando como en línea, lo que encaja con «5 minutos sin actividad».

(Extracto: conclusión de la recomendación, los 5 primeros motivos y la solución principal a nivel de usuario del diseño de claves de Redis)

Prompt completo:

我要给一个日活 10 万的 Web 应用加「实时在线状态」功能(用户头像旁显示绿点,5 分钟无活动变灰)。技术栈是 Next.js + PostgreSQL + Redis。请先给出方案对比(WebSocket / SSE / 轮询),说明你推荐哪一个以及理由,再列出实现步骤和 Redis 键设计。不要写完整代码,关键片段可以贴。

Generar con este prompt →

grok-4.7, nivel de razonamiento high por defecto, max_tokens limitado a 6000, ejecución real 69.8s, entrada 3,429 / salida 4,247 tokens, unos $0.014.

Primero delimita el stack y el volumen de negocio, y luego pide «primero comparar y después recomendar»; la salida es una propuesta lista para revisión, no una explicación neutra.

Escenario 4: explicación de conceptos

Primero pongamos el escenario en claro. Imagina que estás implementando un pedido: hay que guardar el pedido en la base de datos y, al mismo tiempo, publicar un mensaje en la cola para que los sistemas posteriores (inventario, puntos, notificaciones) hagan su trabajo. Esas dos acciones no están en la misma «transacción», y si falla cualquier paso intermedio aparece una grieta en el sistema: «una parte tuvo éxito y la otra nunca ocurrió».

Por qué se pierden mensajes si primero escribes en la base de datos y luego publicas

El commit de la base de datos tiene éxito y el pedido queda guardado. Justo después, el proceso tiene que publicar el mensaje, y en ese momento puede pasar que:

  • la red falle un instante y no se pueda enviar;
  • la cola de mensajes no esté disponible temporalmente;
  • lo más habitual: el proceso se caiga justo después del commit y antes de publicar (reinicio de la máquina, OOM, despliegue progresivo).

El pedido está en la base de datos, pero el mensaje nunca se publicó. Los sistemas posteriores no saben nada de ese pedido: no se descuenta inventario ni se envía la notificación. Reintentar después no sirve: el proceso que se cayó ya no está; a menos que hayas implementado otra compensación fiable, ese mensaje se ha perdido. Para alguien que solo ha trabajado con monolitos, esto es como anotar «cobrado» en el libro de cuentas y luego ir a la oficina de correos a enviar la carta de aviso; la carta se pierde por el camino, pero el libro ya está modificado y las dos partes no cuadran.

(Extracto: el mecanismo de pérdida de mensajes de «primero la base de datos y luego publicar» y la metáfora central)

Prompt completo:

用一位有 3 年经验但完全没接触过分布式系统的后端工程师能懂的语言,解释为什么「先写数据库再发消息队列」可能导致消息丢失,而「先发消息队列再写数据库」也不行。请给出业界常用的两种正确姿势(本地消息表 / 事务消息)各自适合什么场景。

Generar con este prompt →

grok-4.7, nivel de razonamiento high por defecto, max_tokens limitado a 4000, ejecución real 41.3s, entrada 3,410 / salida 2,478 tokens, unos $0.009.

En lugar de «explícalo con claridad», usa «explícalo a una persona con este perfil concreto»; así el modelo elige el nivel de detalle adecuado: de ahí salen las metáforas del libro de cuentas y la oficina de correos.

Escenario 5: script de análisis de datos

```python
import pandas as pd
import numpy as np

# datos de ejemplo (puedes sustituirlos por tu df real)
np.random.seed(42)
n = 500
df = pd.DataFrame({
    "order_id": range(1, n + 1),
    "user_id": np.random.randint(1, 80, n),
    "amount": np.round(np.random.uniform(20, 500, n), 2),
    "created_at": pd.date_range("2023-01-01", periods=n, freq="D").astype(str),  # fechas simuladas como cadenas
    "status": np.random.choice(["paid", "paid", "paid", "cancelled"], n),
})

# ---------- 0. Tratamiento de fechas: convertir cadenas a datetime ----------
df["created_at"] = pd.to_datetime(df["created_at"], errors="coerce")
df = df.dropna(subset=["created_at", "amount", "user_id"])

# Opcional: contar solo pedidos válidos (ajusta los valores de status según tu negocio real)
df_valid = df[df["status"] == "paid"].copy()

# ---------- 1. GMV y número de pedidos por mes ----------
df_valid["month"] = df_valid["created_at"].dt.to_period("M")
monthly = (
    df_valid.groupby("month", as_index=False)
    .agg(GMV=("amount", "sum"), order_count=("order_id", "count"))
    .sort_values("month")
)
monthly["month"] = monthly["month"].astype(str)
print("=== GMV y pedidos por mes ===")
print(monthly)
```

(Extracto: primera mitad del código (tratamiento de fechas + GMV mensual); se omiten el ranking de usuarios y la tendencia del primer pedido)

Prompt completo:

我用 pandas 分析一份电商订单数据,数据框 df 有列:order_id, user_id, amount, created_at, status。请给我一段完整可运行的 Python 代码,算出:1) 每个月的 GMV 和订单数;2) 每个用户的累计消费排名(只要前 20);3) 新用户首单平均金额按月的趋势。要求处理 created_at 是字符串的情况,并注释关键步骤。

Generar con este prompt →

grok-4.7, nivel de razonamiento high por defecto, max_tokens limitado a 5000, ejecución real 18.5s, entrada 3,440 / salida 1,427 tokens, unos $0.007.

Enumera uno a uno los nombres de columnas, las métricas que hay que calcular y los casos límite (created_at es una cadena); el código generado se puede ejecutar directamente, sin retrabajo.

Cómo escribir prompts

  1. Pega código real y nombres de columnas reales; no digas «hay un código», pégalo directamente.
  2. Escribe el formato de salida en el prompt: si quieres JSON, da el esqueleto JSON; si quieres código, di «completo y ejecutable».
  3. Cuanto más concretas sean las restricciones, mejor: reglas de ordenación, solo los 20 primeros, no escribir código completo y pegar solo los fragmentos clave.

Preguntas frecuentes

¿Se pueden usar estos prompts tal cual? Sí. Los 5 son prompts originales que hemos ejecutado en HiAPI, y la salida mostrada es el resultado real. Pulsa «Generar con este prompt» debajo de cada uno: la página del modelo se rellena automáticamente y basta con cambiar el código o los datos por los tuyos para usarlo.

¿Qué tal se le da a grok-4.7 escribir código? xAI lo posiciona para programación y trabajo del conocimiento; según sus cifras oficiales, Terminal-Bench 4.0 pasa del 20,3% de grok-4.6 al 38,0%. La localización de la causa raíz del escenario 1 y la lista de revisión del escenario 2 son resultados reales de nuestras ejecuciones, puedes juzgarlo tú mismo.

¿Cuánto cuesta aproximadamente una llamada? Según el precio de la plataforma HiAPI (entrada $0.84 / salida $2.52 por 1M tokens), las 5 juntas cuestan unos $0.06. La más barata, el escenario 5, cuesta solo unos $0.007; la más cara, el escenario 1, unos $0.021.

¿Para qué sirve el contexto de 500K? Puedes pegar en una sola petición los archivos de un repositorio mediano o cientos de páginas de logs para hacer revisión, diagnóstico o refactorización, sin tener que dividirlos tú. Los prompts cortos del día a día no llenan ese contexto y tampoco cuestan más: se factura por tokens reales.

Más información

Artículos relacionados

Ver todos los artículos →

Empieza a crear con artefactos de IA persistentes

Consigue tu API key y llama a modelos de imagen, vídeo y audio a través de una única API basada en tasks.

Leer la documentación de la API