TL;DR:5 个场景,全部用 grok-4.7 在 HiAPI 生产环境实跑过,输出原文照贴。单条成本 $0.007–0.021,跑完 5 条约 $0.06。每条提示词下面的链接点了会自动把同一条提示词填进模型页,发送即可复现。Grok 4.7 已在 HiAPI 上线,打开模型页直接试玩,新用户注册送 200 积分。
场景 1:排查并发卡死
根本原因是响应对象没有被释放,连接一直占着 connector 池里的槽位。
session.get()返回的ClientResponse只有在release()/close()(或异步上下文管理器退出)时,才会把连接还回TCPConnector。当前写法既没有async with,也没有显式release()。读完 body 并不会归还连接;响应和 connection 之间还有循环引用,只能等循环 GC 的__del__才释放。默认每个
ClientSession的连接上限是 100。20 个 worker 各持有一个 session、串行发请求,每个 worker 大约跑 250 个 URL。连接不归还时:
- 已占用的连接被服务端空闲超时或连接数限制 RST,aiohttp 在协议层打出
ConnectionResetError(不一定从你的await抛出,所以except拦不住、也清理不了)。- 槽位仍被占着。满 100 之后,下一次
session.get()卡在connector.acquire()上,而且这次等待往往不受 timeout 约束。- 全部 worker 都堵在 acquire 里,不再
queue.get(),也不再task_done()。事件循环上没有新的分配,循环 GC 也不再跑,__del__无法回收连接,形成死锁。queue.join()也永远等不到。
except Exception: pass只能吞掉用户协程里的异常,释放不了连接,所以「报错」和「卡死」会一起出现。最小改动:
async def fetch(url, session): async with session.get(url) as r: return await r.json()
async with在正常返回和异常两条路径都会走__aexit__→release():
- 连接立刻还回池子,槽位不会堆到 100,
session.get()不会再永久堵在 acquire 上,worker 能继续消费队列。这解决卡死。- 连接不再长期占着等服务端 RST,协议层的
ConnectionResetError也随之消失;即便读 body 时真发生断连,上下文管理器仍会归还/关闭这条连接,一次失败不会把池子抠死。这解决报错,并保证报错之后队列还能往下走。
完整提示词:
下面这段 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,默认 high 推理档,max_tokens 封顶 6000,实跑 107.7s,输入 3,572 / 输出 7,301 tokens,约 $0.021。
把症状、代码和「必须同时解释两个问题」的约束一次给全,模型才会定位到连接池这层根因,而不是停在表面改 try-catch。
场景 2:代码审查出 JSON
{"issues":[{"severity":"high","line":8,"problem":"余额检查与扣款分离,存在TOCTOU竞态:并发请求可同时通过余额判断后重复扣款,导致透支或双花","fix":"改为单条条件更新(如balance>=amount时才$inc)或在事务内用行锁/乐观锁原子完成检查与扣款"},{"severity":"high","line":9,"problem":"扣款与入账是两次独立写操作,无事务;第一步成功、第二步失败时资金从from消失且无法回滚","fix":"将两次更新放入同一数据库事务,任一失败则整体回滚,并确认to账户存在后再提交"}
,"summary":"该转账接口缺少原子事务、鉴权与入参校验,并发下会双花或丢钱,异常路径还会挂起请求。"}
(节选:原输出为单行 JSON,保留前两条 high 问题与 summary,其余省略)
完整提示词:
请审查下面的 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,默认 high 推理档,max_tokens 封顶 4000,实跑 40.1s,输入 3,576 / 输出 2,734 tokens,约 $0.010。
在提示词里直接写出想要的 JSON 骨架(字段名、排序规则),grok-4.7 会严格照格式输出,拿到就能进流水线。
场景 3:技术方案对比
推荐用「活动心跳 + Redis TTL + 按需短轮询」,不要上 WebSocket/SSE 做全量在线推送。5 分钟变灰不需要秒级推送,100k DAU 下轮询完全扛得住,也更贴合 Next.js。
方案对比
轮询 SSE WebSocket 方向 客户端拉 服务端单向推 双向 与「5 分钟无活动变灰」的匹配 高。30–60s 刷新对绿点足够 中。推送更快,但超时变灰仍要自己算 低到中。连接在线 ≠ 用户活跃 Next.js 适配 最好。普通 Route Handler 差。长连接和 Serverless/多实例不友好 最差。需要独立 WS 进程、粘性会话或第三方 连接成本 无长连接 每个在线用户 1 条 每个在线用户 1 条,还要心跳保活 扩展 无状态,水平扩展简单 要管断线、重连、多实例扇出 同上,且更重 失败模式 某次请求失败,下次再拉 断线后状态停更,要补拉 同左,网关复杂 100k DAU 是否值得 值得,作为默认方案 只有已有推送通道时才值得 只有已有聊天/协作网关时才值得 粗算峰值:日活 10 万,同时在线按 5%–15% 估,大约 0.5 万–1.5 万。心跳 45 秒一次约 100–300 写/秒;每人每 30 秒拉一批可见用户状态,读也在 Redis 的舒适区。瓶颈不会在「绿点」。
推荐与理由
用 Redis 做在线真相,PostgreSQL 只做冷的
last_seen,客户端只轮询当前屏幕上的用户。
- 产品语义是「5 分钟无活动」,不是「TCP 还连着」。页面挂着不动应变灰,所以即使用 WS,仍要单独的活动心跳。连接本身解决不了需求。
- 绿点允许几十秒误差。轮询间隔 30–60 秒,相对 5 分钟窗口足够。
- Next.js(尤其 Vercel / Serverless)不适合扛长连接。WS/SSE 会把你拖进独立实时服务、粘性路由和断线补偿,收益却很小。
- 谁该看到谁的状态通常是局部的(好友、会话列表、当前页头像),不是全站广播。按 id 批量查 Redis,比维护订阅关系简单一个数量级。
- Redis key 过期天然表达「超时下线」,不必靠 keyspace notification 或扫全表。
用户级存在即在线(推荐主方案):
```text
presence:u:{userId} STRING 值 = 服务端 unix 毫秒
TTL = 300 秒
心跳时 SET key value EX 300
在线 = key 存在
```
不要用客户端时间。TTL 略大于心跳间隔的 2–3 倍没有必要,这里心跳 45–60 秒、TTL 300 秒,丢两三次心跳仍算在线,符合「5 分钟无活动」。
(节选:推荐结论与前 5 条理由、Redis 键设计中的用户级主方案)
完整提示词:
我要给一个日活 10 万的 Web 应用加「实时在线状态」功能(用户头像旁显示绿点,5 分钟无活动变灰)。技术栈是 Next.js + PostgreSQL + Redis。请先给出方案对比(WebSocket / SSE / 轮询),说明你推荐哪一个以及理由,再列出实现步骤和 Redis 键设计。不要写完整代码,关键片段可以贴。
grok-4.7,默认 high 推理档,max_tokens 封顶 6000,实跑 69.8s,输入 3,429 / 输出 4,247 tokens,约 $0.014。
先限定技术栈和业务量级,再要求「先对比后推荐」,输出就是能拿去评审的方案,而不是中立科普。
场景 4:概念讲解
先把场景说清楚。假设你在做下单:必须把订单写进数据库,同时还要往消息队列丢一条消息,让库存、积分、通知这些下游去干活。这两个动作不在同一个“事务”里,中间任何一步失败,系统就会出现“一边成功、一边没发生”的裂缝。
先写数据库,再发消息,为什么会丢消息
数据库提交成功了,订单已经落库。紧接着进程要发消息,这时候可能:
- 网络抖了一下,发不出去;
- 消息队列暂时不可用;
- 更常见的是,进程在数据库提交之后、发消息之前直接崩了(机器重启、OOM、部署滚动)。
订单在库里,消息却永远没发出去。下游完全不知道有这笔单,库存不扣、通知不发。你事后重试也没用——崩溃的那个进程已经没了,除非你另外做了可靠的补偿,否则这条消息就丢了。对一个只写过单体的人来说,这就像:你先在账本上记了一笔“已收款”,然后去邮局寄通知信,信在半路丢了,账本却已经改了,两边对不上。
(节选:「先写库再发消息」的丢消息机制与核心比喻)
完整提示词:
用一位有 3 年经验但完全没接触过分布式系统的后端工程师能懂的语言,解释为什么「先写数据库再发消息队列」可能导致消息丢失,而「先发消息队列再写数据库」也不行。请给出业界常用的两种正确姿势(本地消息表 / 事务消息)各自适合什么场景。
grok-4.7,默认 high 推理档,max_tokens 封顶 4000,实跑 41.3s,输入 3,410 / 输出 2,478 tokens,约 $0.009。
用「给具体画像的人讲」代替「讲清楚点」,模型会自己选对粒度:账本和邮局的比喻就是这么来的。
场景 5:数据分析脚本
```python
import pandas as pd
import numpy as np
# 示例数据(可替换为你的真实 df)
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), # 模拟字符串日期
"status": np.random.choice(["paid", "paid", "paid", "cancelled"], n),
})
# ---------- 0. 日期处理:字符串转 datetime ----------
df["created_at"] = pd.to_datetime(df["created_at"], errors="coerce")
df = df.dropna(subset=["created_at", "amount", "user_id"])
# 可选:只统计有效订单(按实际业务调整 status 取值)
df_valid = df[df["status"] == "paid"].copy()
# ---------- 1. 每个月的 GMV 和订单数 ----------
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 与订单数 ===")
print(monthly)
```
(节选:代码前半(日期处理 + 每月 GMV),后半的用户排名与首单趋势省略)
完整提示词:
我用 pandas 分析一份电商订单数据,数据框 df 有列:order_id, user_id, amount, created_at, status。请给我一段完整可运行的 Python 代码,算出:1) 每个月的 GMV 和订单数;2) 每个用户的累计消费排名(只要前 20);3) 新用户首单平均金额按月的趋势。要求处理 created_at 是字符串的情况,并注释关键步骤。
grok-4.7,默认 high 推理档,max_tokens 封顶 5000,实跑 18.5s,输入 3,440 / 输出 1,427 tokens,约 $0.007。
把列名、要算的指标、边界情况(created_at 是字符串)逐条列出来,生成代码可以直接跑,不用返工。
提示词怎么写
- 贴真实代码、真实列名,不要描述「有一段代码」,直接贴上来。
- 输出格式写进提示词:要 JSON 就给出 JSON 骨架,要代码就说「完整可运行」。
- 约束越具体越好:排序规则、只要前 20、不要完整代码只贴关键片段。
常见问题
这些提示词可以直接拿去用吗? 可以。5 条全部是我们在 HiAPI 上实跑过的原创提示词,输出就是跑出来的真实结果。点每条下面的「用这个提示词生成」,模型页会自动预填,换成你自己的代码或数据就能直接用。
grok-4.7 写代码能力怎么样? xAI 给它的定位就是编码和知识工作,官方自报的 Terminal-Bench 4.0 从 grok-4.6 的 20.3% 提到 38.0%(官方口径)。上面场景 1 的根因定位和场景 2 的审查清单都是我们实跑出来的,可以自行判断。
一次调用大概多少钱? 按 HiAPI 平台价(输入 $0.84 / 输出 $2.52 每 1M tokens)算,这 5 条合计约 $0.06。最便宜的场景 5 只要约 $0.007,最贵的场景 1 约 $0.021。
500K 上下文怎么用得上? 可以把整个中型仓库的文件或几百页日志贴进一次请求做审查、排障或改造,不需要自己切分。日常短提示词用不满也不会多收钱,按实际 token 计费。
继续阅读
- Grok 4.7 API 多少钱?——三档推理、长文档计价和按月预算矩阵
- Grok 4.7 vs Grok 4.6——同价位,什么时候用哪个
- Grok 4.7 API 接入指南——5 分钟跑通第一个请求
- Grok 4.6 模型页——上一代旗舰的完整用法
- Grok 4.7 模型页——在线试玩、参数和实时价格




