Skip to content
··阅读时间3分钟

一个 AI 参数改动让我每月多花 $54

我原以为 Cloud Run 迁移完美无缺,直到一个 AI 参数——temperature 设成 0.7 而不是 0——导致 30% API 调用首轮失败,每月浪费 $54 token 成本。

我让 Claude 帮我把系统从 AWS Lambda 迁移到 Google Cloud Run。迁移本身非常顺利——服务成功部署、工作流正常执行、用户也满意。然后我看了一眼 API 账单,差点从椅子上掉下来。

这是 DIALØGUE 工程系列第 3 篇。前两篇如果你还没看:[Part 1: DIALØGUE Introduction] 和 [Part 2: From Advertising to Engineering] 讲了基础。

这篇讲的是:当你让 AI 写生产代码,却没有明确生产约束时会发生什么。剧透一下:“能跑起来”和“可用于生产”是两种完全不同的请求。

这次迁移,顺利得有点过头

在 AWS Lambda 上折腾了几个月(冷启动、layer 限制等等)后,我决定把全部服务迁到 Google Cloud Run。作为一个务实开发者(直白点说:有点懒),我请 Claude 当我的 pair programmer。

“帮我把这些 Lambda 函数迁到 Cloud Run,”我说,“这是现有代码。”

Claude 交付得非常漂亮。干净的 Dockerfiles、合理的服务配置、可运行的 Cloud Workflows。原本我预估要几周的迁移,最后一天就完成了。我非常兴奋。

部署过程非常顺滑。服务启动快,用户也能正常创建播客。成功了,对吧?

然后我在日志里看到了点怪东西:

```
[ERROR] Segment generation failed: Unexpected token in JSON
[RETRY] Attempting segment generation again...
[SUCCESS] Segment generated successfully
```

大约 30% 的 AI 调用会在第一次失败,但重试成功。不是世界末日——我的重试逻辑是生效的!用户也没有明显感知。但这些额外 API 调用在账单上累积得非常快。

排查过程:先怪迁移?

我第一反应是迁移过程中哪里出了问题。难道新 Cloud Run 环境有差异?容器网络问题?我花了几个小时对比 AWS 与 GCP 配置。

看起来完全一致。同样的 prompts,同样的重试逻辑,同样的错误处理。那为什么现在突然会返回 malformed JSON?

然后我开始逐行比实际代码。结果如下:

AWS Lambda 版本(稳定跑了几个月):

```python
response = anthropic.messages.create(
      model="claude-3-7-sonnet-20250219",
      temperature=0,  # Deterministic for JSON
      response_format={"type": "json_object"},  # JSON mode
      system="You are a JSON generation assistant. Output only valid JSON.",
      messages=[{"role": "user", "content": prompt}]
)
```

GCP Cloud Run 版本(Claude 迁移后):

```python
response = anthropic.messages.create(
    model="claude-3-7-sonnet-20250219",
    temperature=0.7,  # <-- Wait, what?
    messages=[{"role": "user", "content": prompt}]
)
```

就是它。temperature 0.7。

“但这不是很合理的默认值吗?”你可能会说。没错。对创意写作、探索、头脑风暴来说,0.7 完全合理。但对结构化 JSON 生成来说,它就是灾难。

铁证:会“创作”的 JSON

我加了更细日志来抓 AI 原始响应,发现了真实情况。temperature 0.7 下 Claude 返回内容像这样:

```
Here's the podcast segment you requested:

{
  "title": "The Rise of AI Podcasting",
  "content": "Welcome back, listeners! Today we're diving into something really fascinating...",
  "duration": 120
}

I hope this segment captures what you were looking for!
```

问题看到了吗?Claude 在“响应格式”上开始发挥创意。有时只给 JSON,有时给“解释+JSON”,有时代码块包裹。temperature 0.7 下它像爵士乐手一样即兴,而我需要的是节拍器。

AI 结对编程的盲区

和 AI 做 pair programming 的关键现实是:它非常擅长让代码 work,但如果你不明确提出,它不会默认为生产效率做极致优化。

当我说“把这个 Lambda 迁到 Cloud Run”时,Claude 聚焦的是迁移任务本身:

- ✅ 在 Cloud Run 上运行

- ✅ 接收并输出相同功能结果

- ✅ 保持功能一致

- ❌ 面向生产效率优化

Claude 选择 0.7 是因为它是“对 AI 应用来说普遍合理”的默认值。这个判断并不荒谬。对多数场景,0.7 在创造性和一致性之间确实平衡不错。

但这次我学到的是:AI 并不知道你的生产约束,除非你明确告诉它。

我的 AWS 旧代码用 temperature 0 + JSON mode,是我之前踩坑后换来的经验:JSON 生成需要确定性输出和显式格式约束。可在迁移阶段,我没有明确强调“这是结构化数据生成”或“请保留全部 JSON 专属优化”。

于是 Claude 写出了功能正确、默认值合理的代码。问题不在 AI,在我需求描述不完整。

修复:给 AI 更具体的要求

定位问题后,我带着更明确要求回到 Claude:

“帮我修这段代码。它用于生产环境 JSON 生成。我需要 100% 可靠、0 创造性。请用 temperature 0,以及任何适用于结构化数据的优化。”

Claude 立即建议:

```python
response = anthropic.messages.create(
    model="claude-3-5-sonnet",
    temperature=0,  # Deterministic outputs
    response_format={"type": "json_object"},  # JSON mode
    system="You are a JSON generation assistant. Output only valid JSON.",
    messages=[{"role": "user", "content": prompt}]
)
```

等等,Claude 把我们原来那套 JSON mode 还删过一次!(这就是迁移时你没把每条生产要求都说清楚会发生的事!)

成功率从 70% 直接跳到 99.9%。剩余 0.1%?网络超时。这锅不能甩给 Claude。

差异点很简单:这次我明确写了生产约束。我不再只说“帮我迁移”,而是说“给我生产级、可靠性优先的实现”。

“合理默认值”的真实代价

这个“看似合理”的 temperature 设置,实际代价如下:

- 日播客生成量:约 200

- 失败率:30% 需要重试

- 每日额外 API 调用:60 次

- 月度浪费:约 1,800 次不必要调用

- Claude 3.7 Sonnet 定价:每百万 token 输入 $3 + 输出 $15

- 单次调用平均 token:输入约 2,000 + 输出约 1,500

- 每次重试成本:约 $0.03

- 月度超支:约 $54

但真正成本不止 $54/月。每次重试还额外加 3-5 秒生成时间。用户等待更久,Cloud Run 实例被更频繁拉起,配额也更快消耗。

最讽刺的是:这一切源于我让 AI 做了生产决策,却没给它生产上下文。典型“能跑”和“高效运行”混淆。

我对 AI Pair Programming 的新认知

1. 生产要求必须写清楚

“让它能跑”会得到功能代码;“在这些约束下让它高效跑在生产”才会得到优化代码。AI 擅长解决你写出来的问题,而不是你脑子里的问题。

2. AI 给你的是“合理默认值”,不是“最优配置”

temperature 0.7 对多数 AI 应用合理。但生产系统往往需要 temperature 0 + JSON mode 这种特定优化。你不说,它不会替你保留。

3. AI 代码同样需要代码审查

AI 写的并不自动等于 production-ready。我本该在 code review 阶段抓到这个,但我当时过度关注“迁移是否跑通”,没细审参数。

4. 上下文比你想象更重要

我 AWS 旧代码里 temperature 0 + JSON mode 有明确历史原因,是我踩坑换来的。迁移时之所以丢,是因为我没显式传达。现在我会记录每个参数/功能背后的“为什么”。

我现在的 AI Pair Programming 工作流

现在我让 AI 处理生产代码时,会把约束写得更具体:

之前:

“把这个 Lambda 函数迁到 Cloud Run”

现在:

“把这个 Lambda 函数迁到 Cloud Run。它用于生产环境 JSON 生成——可靠性优先于创造性。请使用 temperature 0、若可用则开启 JSON mode,并应用所有适合结构化输出的优化。”

这是 Claude 帮我整理出的生产优化配置:

```python
def get_ai_json_response(prompt: str) -> dict:
    """Production-optimized JSON generation with AI"""
    response = anthropic.messages.create(
        model="claude-sonnet-4-20250514",
        temperature=0,  # Zero creativity for structured data
        response_format={"type": "json_object"},  # Force JSON mode
        system="You are a JSON generation assistant. Output only valid JSON.",
        messages=[{
            "role": "user", 
            "content": f"{prompt}\n\nRespond with valid JSON only."
        }]
    )
    
    # Explicit error handling for production
    try:
        return json.loads(response.content[0].text)
    except json.JSONDecodeError as e:
        logger.error(f"JSON parse failed: {e}")
        logger.error(f"Raw response: {response.content[0].text}")
        raise
```

差异就在这里:我把具体场景上下文给到 AI,它才能针对该场景优化。

结果

API 成本降低 30%,生成速度提升 40%。只因一次对话里我终于把“什么叫 production-ready”说清楚了。

有趣的是,我们连“创意对话”生成现在也用 temperature 0。事实证明 deterministic 不等于无聊,它等于可靠。对话依然自然,因为变化来自 prompts 和内容研究,而不是随机温度波动。

AI 结对编程确实很强,但前提是你记得它本质仍是编程——需求越精确,结果越精确。

你有没有遇过 AI 助手做了一个“很合理”但对你场景完全错误的选择?欢迎分享你的实战故事——我猜我们都被这些“合理默认值”坑过至少一次 :)

致敬,

Chandler

想做带“稳定 JSON 输出保障”的 AI 播客?试试 DIALØGUE —— 新用户送 2 个免费 credits! :P

DIALØGUE 工程系列第 3 篇。继续学习“让它能跑”和“让它高效跑”是两种完全不同的请求。更多 AI pair programming 实战见 chandlernguyen.com

Next in series: 大约 7 天后上线 —— "From 3 Minutes to 500ms: The Signup Bug That Made No Sense"

继续阅读

我的旅程
联系
语言
偏好设置