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
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
ClientResponsedevuelto porsession.get()solo devuelve la conexión alTCPConnectorcuando se llama arelease()/close()(o cuando sale del gestor de contexto asíncrono). La forma actual no tiene niasync withnirelease()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
ClientSessiontiene 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:
- El servidor aplica un RST a las conexiones ocupadas por timeout de inactividad o por límite de conexiones; aiohttp emite
ConnectionResetErroren la capa de protocolo (no necesariamente se lanza desde tuawait, así queexceptno lo captura ni puede limpiarlo).- La ranura sigue ocupada. Al llegar a 100, la siguiente llamada a
session.get()se queda bloqueada enconnector.acquire(), y esa espera a menudo no está sujeta al timeout.- Todos los workers se atascan en acquire, dejan de llamar a
queue.get()y dejan de llamar atask_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: passsolo 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 withpasa 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
ConnectionResetErrorde 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())
```
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;
```
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_seenen frío, y que el cliente solo consulte a los usuarios que hay en pantalla.
- 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.
- 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.
- 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.
- 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.
- 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 键设计。不要写完整代码,关键片段可以贴。
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 年经验但完全没接触过分布式系统的后端工程师能懂的语言,解释为什么「先写数据库再发消息队列」可能导致消息丢失,而「先发消息队列再写数据库」也不行。请给出业界常用的两种正确姿势(本地消息表 / 事务消息)各自适合什么场景。
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 是字符串的情况,并注释关键步骤。
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
- Pega código real y nombres de columnas reales; no digas «hay un código», pégalo directamente.
- Escribe el formato de salida en el prompt: si quieres JSON, da el esqueleto JSON; si quieres código, di «completo y ejecutable».
- 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
- ¿Cuánto cuesta la API de Grok 4.7?: tres niveles de razonamiento, precios de documentos largos y matriz de presupuesto mensual
- Grok 4.7 vs Grok 4.6: mismo precio, cuándo usar cada uno
- Guía de integración de la API de Grok 4.7: haz tu primera petición en 5 minutos
- Página del modelo Grok 4.6: uso completo del buque insignia de la generación anterior
- Página del modelo Grok 4.7: prueba en línea, parámetros y precios en tiempo real
Artículos relacionados
Ver todos los artículos →-
Guía de uso
¿Qué es GPT Image 2.6? Edición con markup y especificaciones conocidas
Toda la información de la especificación de la API de OpenAI sobre GPT Image 2.6, cómo usar el nuevo parámetro de edición markup y qué partes aún no se han anunciado.
-
Guía de uso
¿Cuánto cuesta la API de Vidu Q4 Preview? 540p por segundo $0.0515
Ambos modos tienen el mismo precio: cómo se factura en cinco resoluciones y de 3 a 16 segundos, cuántos clips salen con $10 y una comparativa de precios con otros modelos de video de la plataforma.
-
Guía de uso
Recraft V4.1 Flash 电商产品图:每张 $0.01 批量目录图
在 recraft-v4.1-flash/text-to-image 上的一次真实并行批量:商品列表图与场景图、实测背景白度、耗时以及批量脚本。