正在学习

12.5 使用指标和日志监控使用情况

12.6 示例:优化昂贵的构建流水线

即便一个结构良好的 CI 流水线,在容器构建、依赖安装、冗长的测试套件以及由 Claude 驱动的文档/生成步骤层层叠加后,也会变得缓慢且成本高昂。本示例展示如何将一条迟缓且昂贵的流水线转变为快速、预算可控的工作流。你将实现确定性缓存、基于变更的执行、Claude 任务的 token 成本门控,以及并行化测试。最终得到的流水线将以更短的挂钟时间和更低的 AI 支出交付同等质量的制品。

概念阐述

CI 中的性能与成本取决于四个杠杆。第一,避免冗余工作,方法是复用缓存并在没有相关变更时跳过作业。第二,使昂贵的步骤(容器构建、依赖安装)具备增量和确定性,这样缓存才能真正命中。第三,限制 AI 成本:在调用 Claude 之前估算 token,并在预算将被超支时短路切换到更便宜的模型或本地回退方案。第四,并行运行剩余工作并尽量减少协调开销,然后合并制品。

我们将通过一个小型 FastAPI 项目和一个 GitHub Actions 工作流来应用这些杠杆。构建过程将缓存 Python wheels 和 Docker 层,仅运行受最近变更影响的测试,在调用 Claude 前使用 token 估算器进行预检,并在所有门控通过后推送制品。

动手实践

创建以下最小化的项目结构:

app/

  app.py

  requirements.txt

tests/

  test_app.py

scripts/

  estimate_tokens.py

  changed_paths.py

  selective_tests.py

  build_image.sh

.github/

  workflows/

    ci.yml

app/requirements.txt

fastapi==0.114.0
uvicorn==0.30.5

app/app.py

from fastapi import FastAPI

app = FastAPI(title="Optimized Pipeline Demo")

@app.get("/health")
def health():
    return {"status": "ok"}

tests/test_app.py

from fastapi.testclient import TestClient
from app.app import app

def test_health():
    c = TestClient(app)
    r = c.get("/health")
    assert r.status_code == 200
    assert r.json()["status"] == "ok"

scripts/estimate_tokens.py

import math
import json
import os
import sys

PRICING = {
    "claude-3.5-haiku": {"in": 0.0008, "out": 0.004},
    "claude-3.5-sonnet": {"in": 0.003, "out": 0.015},
    "claude-3-opus": {"in": 0.010, "out": 0.050},
}

def approx_tokens(text: str) -> int:
    # ~4 chars per token heuristic
    return math.ceil(len(text) / 4)

def main():
    model = os.getenv("CLAUDE_MODEL", "claude-3.5-sonnet")
    budget = float(os.getenv("CLAUDE_BUDGET_USD", "0.05"))
    expected_output_tokens = int(os.getenv("EXPECTED_OUTPUT_TOKENS", "1500"))
    prompt_path = sys.argv[1] if len(sys.argv) > 1 else "-"
    prompt = sys.stdin.read() if prompt_path == "-" else open(prompt_path, "r", encoding="utf-8").read()

    tin = approx_tokens(prompt)
    tout = expected_output_tokens
    rate_in = PRICING[model]["in"]
    rate_out = PRICING[model]["out"]
    cost = (tin/1000)*rate_in + (tout/1000)*rate_out
    decision = "allow" if cost <= budget else "switch"

    print(json.dumps({
        "model": model,
        "input_tokens": tin,
        "output_tokens": tout,
        "estimated_cost": round(cost, 4),
        "budget": budget,
        "decision": decision
    }, indent=2))

    # Exit code communicates gating to CI
    if decision == "allow":
        sys.exit(0)
    else:
        sys.exit(42)

if __name__ == "__main__":
    main()

scripts/changed_paths.py

import subprocess
import sys
import json

# Determine changed files against the base ref (default: origin/main)
base = sys.argv[1] if len(sys.argv) > 1 else "origin/main"
cmd = ["git", "diff", "--name-only", f"{base}...HEAD"]
out = subprocess.check_output(cmd, text=True)
files = [f.strip() for f in out.splitlines() if f.strip()]
print(json.dumps({"changed": files}, indent=2))

scripts/selective_tests.py

import json
import sys
from pathlib import Path

练习题

下列哪一项不属于 CI 流水线中性能和成本优化的四个杠杆之一?

A. 通过复用缓存并在没有相关更改时跳过作业来避免冗余工作
B. 使昂贵的步骤具有增量性和确定性,从而使缓存真正命中
C. 为所有 CI 作业使用更快的硬件以减少执行时间
D. 通过在调用 Claude 之前估算 token,并在预算将超出时短路切换到更便宜的模型来限制 AI 成本

scripts/estimate_tokens.py 中的 approx_tokens 函数的目的是什么?

A. 使用复杂算法计算文本中的确切标记数
B. 使用每个标记约 4 个字符的启发式方法估计文本中的标记数
C. 计算文本中的单词数
D. 根据标记数计算调用 Claude 的成本

以下哪些是 scripts/estimate_tokens.pyPRICING 常量的有效模型名称?(选择所有适用的)

A. claude-3.5-haiku
B. claude-3.5-sonnet
C. claude-3-opus
D. claude-2-sonnet

下列哪些是示例的最小项目结构的一部分?(选择所有适用的)

A. app/app.py
B. app/requirements.txt
C. tests/test_app.py
D. scripts/build_image.sh
E. .github/workflows/ci.yml

scripts/changed_paths.py 脚本使用 git diff --name-only 来确定当前分支与 origin/main 之间已更改的文件。

scripts/estimate_tokens.py 脚本在调用 Claude 的估算成本在预算范围内时退出码为 0,在成本超过预算时退出码为 42。

scripts/estimate_tokens.py 脚本中,用于近似估算文本中 token 数量的启发式方法是每个 token ___ 个字符。

scripts/estimate_tokens.py 脚本中,EXPECTED_OUTPUT_TOKENS 的默认值是 ___。

CI 流水线中 scripts/changed_paths.py 脚本的用途是什么?

scripts/estimate_tokens.py 脚本是如何帮助在 CI 流水线中限制 AI 成本的?

以下哪项是通过结构化指标和日志监控 Claude Code 使用情况的好处?

A. 它有助于管理者跟踪每位开发人员的整体令牌消耗和成本
B. 它通过识别趋势和瓶颈实现主动优化
C. 它确保了跨团队的透明度和问责制
D. 以上皆是

以下哪些是监控 Claude Code 使用情况的指标类别?(选择所有适用的)

A. 使用指标
B. 性能指标
C. 审计日志
D. 成本指标

在一个频繁调用 Claude 生成文档的 CI 流水线中,哪种策略组合能最好地同时优化性能和成本?

A. 对重复的 Claude 提示使用缓存并实施 token 成本门控
B. 增加并行 CI 作业的数量并使用最强大的 Claude 模型
C. 禁用缓存并始终为 Claude 使用最大输出 token 限制
D. 顺序运行所有测试,并且仅将 Claude 用于错误报告

在 CI 流水线中实施 token 估算脚本 (estimate_tokens.py) 时,哪些指标最值得监控?

A. 每个请求的 token 数
B. 响应延迟
C. 每个用户的请求数
D. 每次会话的成本
E. 提示-响应比率

通过与 selective_tests.py 脚本集成,可以增强 changed_paths.py 脚本的功能,使其能够跳过对未更改文件的测试运行,从而提升 CI 流水线中的性能并降低成本。

为了实现来自kp_12_6_001的"约束AI成本"杠杆,estimate_tokens.py脚本应使用公式计算成本,其中是___,是___,是___,是___。

你会如何修改 test_app.py 脚本来帮助减少 Claude 在根据测试结果生成文档时的 token 使用量?

登录后解锁笔记、知识点解析、AI 问答

立即登录