最新资讯
bloomberg.com Nvidia 加强东南亚芯片追踪以打击走私 thestack.technology 模型路由需求升温,Agent Router 推出开源替代方案 unite.ai Cashfree 为 AI Agent 的托管结账加入 WebMCP 工具 dev.to 我们在 DolphinBench 上测试记忆检索:纯关键词搜索暴露了自身回归 dev.to 别再把 Agent 写成 while 循环,把它建模为状态机 analyticsindiamag.com 小语言模型可能重塑企业 AI 部署方式 bloomberg.com Rightmove 与 Scout24 借 AI 产品应对低迷房市并上调展望 stackoverflow.blog 欢迎来到芯片时代:半导体制造、AI 数据中心与芯片设计的未来 www.youtube.com AI Agent 总犯同样的错:CentralAgent AI 将记忆重构为经验系统 pub.towardsai.net Netflix 科学家建议重采样 LLM 评判:5 次仅将误差棒缩小 13% pub.towardsai.net Jev 作为 LLM 前的静默层:构建提示感知的模型路由器 reddit.com OpenAI 称 Astra 仅满足 10% 安全任务标准
多元动态
登录 注册
AI编码 dev.to · @Sam Yang

免费额度不等于预算:拆解 AI 编程循环的真实成本

原文 我的收藏

文章以一次 PR 中同一解析器被提交三种修复为例,说明免费 token 额度只限制单步输入,而真实成本来自循环迭代、返工与环境漂移;作者提出应先建立测量循环成本的测试框架,再讨论套餐价格。

AI推荐理由 指出免费 token 额度只覆盖单步输入,真实成本累积在循环迭代、返工与环境漂移中,并给出一个测量循环而非价格的测试框架;与同批另一篇 token 计量文章主题相近,存在一定重复。

64

正文

A reviewer once sent back a pull request with three different fixes for the same flaky parser, all of them green in CI. The agent had been free to run, so nobody had counted anything, and the repo quietly paid the difference in review time. That mismatch between what the meter shows and what the work costs is the subject of this article. It is also the myth most developers repeat without checking: that a free token allowance makes AI-assisted coding free. The corrected mental model is narrower and more useful. A token allowance caps one input to one step, while real cost accumulates across loop iterations, rework, and environment drift that no dashboard displays by default. If you want to argue about tiers, you first need a harness that measures the loop rather than the price tag. What follows is that harness, five claims checked against it, and the situations where the whole approach is the wrong tool. Start with a measurement, not an opinion The harness runs the same task against the same pinned commit several times and records what actually happened, including failures, which are usually the interesting rows. It talks to any OpenAI-compatible endpoint, so the tier you are evaluating stays a configuration detail rather than an assumption baked into the script. Platforms that offer free model access, including MonkeyCode, just become another base URL you can point it at. Disclosure: This article was prepared as part of MonkeyCode's product outreach. Create a scratch copy of the repository and export three variables before running anything. The model identifier is deliberately left as a placeholder, because the right value depends on what your provider currently serves and you should read that from their own documentation. git clone sandbox && cd sandbox export LLM_BASE_URL="https:///v1" # any OpenAI-compatible endpoint export LLM_API_KEY="" export LLM_MODEL="" python3 run_matrix.py \ --repo ./sandbox \ --commit "$(git -C sandbox rev-parse HEAD)" \ --prompt prompts/fix-flaky-parser.md \ --test "pytest -q tests/test_parser.py" \ --repeats 5 Enter fullscreen mode Exit fullscreen mode The script below resets the worktree, asks the model once, tries to apply the returned patch, and records the diff shape alongside the exit code of your test command. Keeping temperature at zero reduces one source of noise, though it does not eliminate provider-side nondeterminism. #!/usr/bin/env python3 """run_matrix.py: run one task N times and record what the loop really cost.""" import argparse, csv, json, os, re, statistics, subprocess, time, urllib.request def ask(prompt: str): body = json.dumps({ "model": os.environ["LLM_MODEL"], "messages": [{"role": "user", "content": prompt}], "temperature": 0, }).encode() req = urllib.request.Request( os.environ["LLM_BASE_URL"].rstrip("/") + "/chat/completions", data=body, headers={"Authorization": f"Bearer {os.environ['LLM_API_KEY']}", "Content-Type": "application/json"}, ) started = time.monotonic() with urllib.request.urlopen(req, timeout=600) as resp: payload = json.load(resp) usage = payload.get("usage", {}) or {} usage["seconds"] = round(time.monotonic() - started, 2) return payload["choices"][0]["message"]["content"], usage def apply_patch(repo: str, text: str) -> int: blocks = re.findall(r"``` (?:diff|patch)\n(.*?) ```", text, re.S) if not blocks: return -1 # the model answered with prose instead of a patch done = subprocess.run(["git", "-C", repo, "apply", "--whitespace=nowarn", "-"], input=blocks[-1], text=True, capture_output=True) return 0 if done.returncode == 0 else -2 def main() -> None: ap = argparse.ArgumentParser() ap.add_argument("--repo", required=True) ap.add_argument("--commit", required=True) ap.add_argument("--prompt", required=True) ap.add_argument("--test", required=True) ap.add_argument("--repeats", type=int, default=3) ap.add_argument("--out", default="loop-cost.csv") args = ap.parse_args() prompt = open(args.prompt).read() rows = [] for run in range(1, args.repeats + 1): subprocess.run(["git", "-C", args.repo, "checkout", "--force", args.commit], check=True) subprocess.run(["git", "-C", args.repo, "clean", "-fdx"], check=True) text, usage = ask(prompt) applied = apply_patch(args.repo, text) diff = subprocess.run(["git", "-C", args.repo, "diff", "--numstat"], text=True, capture_output=True).stdout tests = subprocess.run(args.test, cwd=args.repo, shell=True, capture_output=True) rows.append({ "run": run, "seconds": usage.get("seconds"), "prompt_tokens": usage.get("prompt_tokens"), "completion_tokens": usage.get("completion_tokens"), "apply_code": applied, "files_touched": len([line for line in diff.splitlines() if line.strip()]), "lines_changed": sum(int(n) for n in re.findall(r"^(\d+)\t", diff, re.M)), "test_exit": tests.returncode, }) with open(args.out, "w", newline="") as fh: writer = csv.DictWriter(fh, fieldnames=list(rows[0])) writer.writeheader() writer.writerows(rows) print(open(args.out).read()) if __name__ == "__main__": main() Enter fullscreen mode Exit fullscreen mode The CSV header alone tells you which questions become answerable: run,seconds,prompt_tokens,completion_tokens,apply_code,files_touched,lines_changed,test_exit. Treat the values you collect as yours and nobody else's, because they describe one repository, one prompt, and one test command. A quick summary keeps the discussion grounded in medians rather than a single lucky run. python3 - <<'PY' import csv, statistics as st rows = list(csv.DictReader(open("loop-cost.csv"))) print("runs:", len(rows)) print("pass rate:", sum(r["test_exit"] == "0" for r in rows) / len(rows)) print("median seconds:", st.median(float(r["seconds"]) for r in rows)) print("median lines changed:", st.median(float(r["lines_changed"]) for r in rows)) PY Enter fullscreen mode Exit fullscreen mode Five claims, checked against the harness Claim one: a token allowance is a spending cap. An allowance bounds one dimension of one request, and agent loops multiply that dimension by the number of attempts plus every retry your wrapper adds. The corrected model is that tokens behave like a mileage limit on a single trip while your costs live in the number of trips. If you add automatic retries, log them, because two retries are three requests and the meter will not tell you that. Claim two: cheaper tokens mean cheaper work. Loop count and human review dominate the bill long before per-token price does. A slow run that produces a two-line patch often costs less attention than a fast run that rewrites four files, even though both passed the test command. This is why the harness records files_touched and lines_changed next to timing, and why the pair is more informative than either number alone. Claim three: one successful run proves the tier can do the task. A single green run is a coin flip with good marketing, and the interesting signal is variance across repeats. Five runs that pass with wildly different patch shapes tell you the task is underspecified, not that the model is unreliable. Fix the prompt before blaming the endpoint, since the harness resets the worktree and cannot reset an ambiguous instruction. Claim four: if tests pass, the patch is done. Test outcomes are necessary evidence and never sufficient evidence, because your suite only measures what someone already thought to assert. The harness surfaces this cheaply: when apply_code is -1, the model answered with prose, which is a prompt problem, and when test_exit is zero on a large diff you should read the patch before celebrating. Claim five: the run on a hosted server equals the run on my laptop. Environment identity is part of the experiment, and a container with a different toolchain version can change both the patch and the result. Record the kernel, language runtime, and lockfile hash with each batch, or your comparison measures two variables at once. Recent debates about whether agent wrappers amount to conditionals miss this point, since the interesting difference is rarely the wrapper. Where the free options actually fit A harness is only persuasive when you can afford repetitions, and repetitions are exactly what per-request pricing discourages during exploration. Free model access plus a free server option, as offered by MonkeyCode, is one way to run five or ten repeats of a throwaway task without turning a measurement into a purchase decision. Verify the current terms yourself, including what the allowance covers and how long a server persists, because capacity and conditions change and this article cannot promise them. The honest framing is that these options lower the cost of finding out, not the cost of shipping. Situation Free model access sufficient? Free server sufficient? Reason One-off refactor on a side repo Often yes Usually unnecessary Few iterations, low review stakes Nightly regression harness Often yes Yes if jobs fit the session limits Volume matters more than latency Agent on every pull request Depends on review policy Only with artifact retention A lost log makes a failed run unfalsifiable Code under residency or contract rules Usually no Usually no Sending the diff offsite may be prohibited Multi-hour interactive session Depends on interruption limits Rarely State loss mid-task defeats the exercise Limitations, and who should skip this The harness measures one task shape against one test command, so it is not a benchmark and should never be quoted as one. Token fields come from the provider's usage block, and endpoints that omit it will leave those columns empty rather than wrong. A five-run sample cannot separate model quality from prompt quality, and comparing runs across different days quietly mixes in version changes you did not record. Skip this approach if your work is subject to data-residency or contractual constraints that forbid sending source code to a third-party endpoint, because no amount of measurement fixes a policy violation. Skip it as well if you need deterministic, bit-identical reproducibility for compliance evidence, since hosted inference does not offer that guarantee. If you are optimizing interactive latency rather than loop cost, a batch harness answers the wrong question entirely. If you already have a repository and a test command, the cheapest next step is to run five repeats before arguing about tiers again, then read the median row rather than the best one.

来源报道 · 1 篇 · 以下链接均前往原始媒体

← 返回精选动态 原文

更多内容