datawhalechina/hello-agents · error · RuntimeError

已达到四次模型调用上限

Error message

已达到四次模型调用上限

What it means

A RuntimeError raised by CallBudget.run when the agent has already consumed its maximum (default 4) LLM calls. The budget object exists to hard-cap model invocations in the notebook pipeline (draft → review → repair loop), so exceeding it is by design a stop, not a crash: remaining = maximum - used, and any run() with remaining <= 0 raises before invoking the agent.

Source

Thrown at Co-creation-projects/Henry2513-MeetingActionAgent/main.ipynb:302

   "id": "d3d42947",
   "metadata": {},
   "outputs": [],
   "source": [
    "class CallBudget:\n",
    "    # 初始化模型调用次数上限。\n",
    "    def __init__(self, maximum: int = 4) -> None:\n",
    "        self.maximum = maximum\n",
    "        self.used = 0\n",
    "\n",
    "    # 计算剩余的模型调用次数。\n",
    "    @property\n",
    "    def remaining(self) -> int:\n",
    "        return self.maximum - self.used\n",
    "\n",
    "    # 在次数限制内执行一次 Agent 调用。\n",
    "    def run(self, agent, prompt: str) -> str:\n",
    "        if self.remaining <= 0:\n",
    "            raise RuntimeError(\"已达到四次模型调用上限\")\n",
    "        self.used += 1\n",
    "        return agent.run(prompt)\n",
    "\n",
    "\n",
    "# 调用 Agent 并将响应解析为指定的数据模型。\n",
    "def run_structured(\n",
    "    agent,\n",
    "    prompt: str,\n",
    "    model_type: type[BaseModel],\n",
    "    budget: CallBudget,\n",
    ") -> BaseModel:\n",
    "    schema = json.dumps(model_type.model_json_schema(), ensure_ascii=False)\n",
    "    full_prompt = f\"{prompt}\\n\\n必须遵循以下 JSON Schema:\\n{schema}\"\n",
    "    raw_response = budget.run(agent, full_prompt)\n",
    "    try:\n",
    "        return parse_model_response(raw_response, model_type)\n",
    "    except ValueError as error:\n",
    "        if budget.remaining <= 0:\n",

View on GitHub (pinned to 606a07d341)

Solutions

  1. Inspect where calls go: every budget.run invocation (initial drafts, reviews, repairs) counts against the same maximum — reduce repair-triggering failures by strengthening the prompt's JSON instruction (include the schema, demand raw JSON only).
  2. Raise the cap if the pipeline legitimately needs more stages: CallBudget(maximum=6).
  3. Give each pipeline stage its own CallBudget instead of sharing one, so one stage's repairs cannot starve another.
  4. Switch to a model/provider JSON mode to cut repair calls to near zero.

Example fix

# before
budget = CallBudget()  # maximum=4, exhausted by repairs

# after
budget = CallBudget(maximum=6)
minutes_budget = CallBudget(maximum=4)
review_budget = CallBudget(maximum=2)
Defensive patterns

Strategy: validation

Validate before calling

if budget.remaining <= 0:
    raise RuntimeError("no LLM calls left; raise CallBudget.maximum or add a stage budget")

Type guard

def can_run(budget: "CallBudget") -> bool:
    return budget.remaining > 0

Try / catch

try:
    out = budget.run(agent, prompt)
except RuntimeError as e:
    if "上限" in str(e):
        budget.maximum += 2  # or re-plan pipeline
        out = budget.run(agent, prompt)
    else: raise

Prevention

When it happens

Trigger: More than 4 budget.run(...) calls in one pipeline execution: e.g. minutes drafting consumes calls, the review agent consumes more, and JSON-repair retries consume the rest — the 5th call raises. Composing multiple run_structured steps against one shared CallBudget is the classic way to exhaust it.

Common situations: Frequent JSON validation failures forcing repeated repair prompts (each costs one call); low-quality model output causing a repair loop; adding a new agent stage to the pipeline without raising the budget; shared budget across minutes + review agents in a refactor.

Related errors


AI-assisted analysis of datawhalechina/hello-agents@606a07d341 (2026-08-14). Data as JSON: /api/errors/9a2abdb75c0eb749. Report an issue: GitHub.