iT邦幫忙

2026 iThome 鐵人賽

DAY 19
0
AI Engineering

從黑盒到可驗證:30 天打造 AI Agent 的 Trace、Eval 與 Guardrails 系統系列 第 19 篇

Day 19|Retry 策略:把 JSON 格式錯誤變成可復原事件

  • 分享至 

  • xImage
  •  

前言

Day 18 我們加入了 Prompt Versioning 與 Prompt A/B Testing。

現在同一組 eval dataset 可以分別用不同 prompt version 執行:

PROMPT_VERSION=baseline LLM_PROVIDER=gemini python3 -m evals.runner
PROMPT_VERSION=json_strict LLM_PROVIDER=gemini python3 -m evals.runner

這讓 prompt 改動不再只是憑感覺,而是可以透過 eval run 比較。

在目前這組 15 筆 eval cases 裡,json_strict 很可能已經讓 JSON 題全數通過。

換句話說,Day 18 的 prompt 改善對目前 dataset 是有效的。

那 Day 19 還需要做 retry 嗎?

我認為需要。

原因不是「Day 18 沒解掉 JSON 題」,而是:

Prompt improvement 可以降低第一次失敗的機率,但 retry 是失敗發生後的 recovery path。

這兩者處理的是不同層次的問題。

Day 18 做的是預防:

讓模型第一次就比較可能輸出正確格式。

Day 19 做的是復原:

如果第一次仍然輸出錯誤格式,系統要有機會自動修正。

這是 Agent reliability 裡很值得分清楚的差別。

Prompt 可以改善模型行為,但它不是硬性保證。

即使我們在 system prompt 裡寫得很清楚:

If the user asks for JSON, output only valid JSON.
Do not wrap JSON in markdown code fences.

真實 LLM 仍然可能偶爾輸出:

```json
{
  "answer": 15
}
```

這種錯誤很有趣。

模型其實知道答案是 15,也知道欄位名稱是 answer。

它不是不會做這題,而是輸出多了一層 markdown code fence,導致 json.loads() 不能直接解析。

Day 16 已經能把這類錯誤分類成:

format_error

這一篇要往下一步走:

當 evaluator 偵測到明確的格式錯誤時,把這個錯誤變成可復原事件,讓 Agent 有一次修正機會。

這就是 retry。


今天要完成什麼?

這一篇要做到的是:

在 batch evaluation runner 中加入最小 retry 策略,先針對 format_error 重試一次。

會完成幾件事:

  1. 定義 retry 的適用條件。
  2. 在 evals/runner.py 新增 should_retry()。
  3. 在 evals/runner.py 新增 build_retry_task()。
  4. 修改 run_evaluation(),讓失敗案例可以重跑一次。
  5. 在 eval result 中記錄 retry_count。
  6. 保留第一次失敗的 initial_actual 和 initial_failure_reason。
  7. 重新執行 eval,比較 retry 前後的差異。

先不做:

  • 無限 retry。
  • 對所有 failure type retry。
  • retry 多輪對話記憶。
  • 自動修 JSON 字串。
  • schema guardrail。
  • 成本與延遲統計。

範圍先收斂在一件事:

對明確可修正的格式錯誤,給 Agent 一次重新輸出的機會。


如果 Day 18 已經通過,為什麼還要做 Retry?

這裡需要先講清楚。

如果你照 Day 18 實作 json_strict prompt,然後跑:

PROMPT_VERSION=json_strict LLM_PROVIDER=gemini python3 -m evals.runner

可能會看到 3 題 JSON cases 全部通過。

這表示 prompt 改善有效。

但它不代表 JSON 輸出已經變成工程上可保證的行為。

原因有三個。

第一,目前 JSON cases 很少。

3 / 3 通過

只能說這三題通過,不能代表未來所有 JSON 任務都穩定。

第二,LLM 輸出可能會因為任務內容、上下文、模型版本或溫度設定而變動。

今天這三題通過,不代表之後更複雜的 JSON schema 也一定通過。

第三,prompt 是 soft constraint。

換句話說,它是給模型的指令,不是程式層級的保證。

Retry 補的是 recovery path:

prompt 讓第一次更容易成功
retry 讓第一次失敗時還有修正機會

所以 Day 19 不是否定 Day 18。

Day 19 是把 Day 18 的 prompt improvement 往可靠性工程再推一步。


為什麼不是所有錯誤都 retry?

Retry 聽起來很簡單:

失敗了就再跑一次。

但實務上不能這樣做。

因為不同錯誤適合不同處理方式。

例如:

failure_type 適不適合這次 retry 原因
format_error 適合 錯誤明確,模型通常有機會修正格式
instruction_error 可以,但這次先不做 可能可修正,但需要更小心設計 retry prompt
wrong_answer 不一定 可能是模型真的不知道,也可能是 evaluator 太嚴格
tool_error 不一定 可能需要 tool guardrail,不只是重問
execution_error 不適合 API key、程式錯誤、trace 資料流問題不能靠 prompt 修
unknown_failure 不適合 連原因都不清楚,先不要自動重試

這次先只 retry:

failure_type == "format_error"

而且再加一個限制:

grading_method == "json_exact"

換句話說,這版 retry 專門處理 JSON 格式輸出失敗。

這樣範圍很清楚,也比較容易驗證效果。


Retry 的基本流程

要實作的流程如下:

讀取 test case
  -> 第一次執行 Agent
  -> evaluate(actual)
  -> 如果通過,直接記錄結果
  -> 如果失敗且 failure_type 是 format_error
      -> 建立 retry task
      -> 第二次執行 Agent
      -> 再 evaluate 一次
      -> 記錄最後結果與 retry_count

換成更接近程式的形式:

result = agent.run(test_case["input"])
evaluation = evaluate(test_case, result.answer)

if should_retry(test_case, evaluation):
    retry_task = build_retry_task(test_case, result.answer, evaluation.failure_reason)
    result = agent.run(retry_task)
    evaluation = evaluate(test_case, result.answer)

這裡的 retry 不是讓 evaluator 放寬標準。

評分規則不變。

差別只是當第一次輸出不合格時,我們把錯誤原因回饋給 Agent,請它重新輸出。


今天的專案結構

這次主要修改一個檔案。

agent-testing-platform/
  evals/
    runner.py
    evaluators.py
    cases.json
  agents/
    simple_agent.py
    prompts.py
    client_factory.py
  data/
    eval_runs/
      eval_run_*.json

會修改:

檔案 修改內容
evals/runner.py 加入 retry 條件、retry task,以及 retry result metadata

不修改:

  • evals/evaluators.py
  • agents/simple_agent.py
  • agents/prompts.py
  • evals/cases.json

原因是 Day 16 已經能產生 failure_type。

Day 18 也已經能切換 prompt version。

這次要做的是在 runner 裡使用這些資訊。


先補上環境變數設定

為了方便比較 retry 前後,先用環境變數控制 retry 是否啟用。

我們會使用:

RETRY_ENABLED

執行時可以這樣關閉 retry:

RETRY_ENABLED=0 PROMPT_VERSION=baseline LLM_PROVIDER=gemini python3 -m evals.runner

也可以這樣開啟 retry:

RETRY_ENABLED=1 PROMPT_VERSION=baseline LLM_PROVIDER=gemini python3 -m evals.runner

這樣同一份程式就能跑兩種實驗:

retry disabled
retry enabled

後面就能用 Failure Dashboard 比較差異。

這裡先用 baseline prompt,是為了比較容易觸發 JSON format error,方便驗證 retry 機制。

如果要用接近產品設定的版本,也可以改成:

RETRY_ENABLED=1 PROMPT_VERSION=json_strict LLM_PROVIDER=gemini python3 -m evals.runner

只是當 json_strict 已經讓目前 JSON 題第一次就通過時,retry 不會被觸發,retry_count 會維持 0。


修改 evals/runner.py:新增 retry_enabled

先修改 evals/runner.py 的 import。

修改 evals/runner.py:

import json
import os
from datetime import datetime
from pathlib import Path
from typing import Any

如果 Day 18 已經加入 os,這裡就不需要重複改。

再新增一個 helper function。

修改 evals/runner.py,在 create_run_id() 下方新增:

def is_retry_enabled() -> bool:
    return os.getenv("RETRY_ENABLED", "0") == "1"

這裡刻意把預設值設成關閉:

RETRY_ENABLED=0

因為我們要保留 baseline。

如果預設就開 retry,後面很容易忘記某份 eval run 到底有沒有使用 retry。


定義 should_retry

接著定義 retry 條件。

修改 evals/runner.py,新增 should_retry():

def should_retry(
    test_case: dict[str, Any],
    evaluation: Any,
    retry_count: int,
    max_retries: int,
) -> bool:
    if retry_count >= max_retries:
        return False

    if evaluation.passed:
        return False

    if evaluation.failure_type != "format_error":
        return False

    if test_case["grading_method"] != "json_exact":
        return False

    return True

這個 function 會做四個檢查。

第一,確認沒有超過最大 retry 次數。

這次會設定:

max_retries = 1

第二,如果已經通過,就不需要 retry。

第三,只 retry format_error。

第四,只 retry json_exact 題目。

這樣可以避免 retry 範圍太大。

例如 wrong_answer 今天不 retry,因為它可能是 evaluator 太嚴格,也可能是模型真的答錯。


建立 retry task

接著要把第一次錯誤轉成第二次任務。

修改 evals/runner.py,新增 build_retry_task():

def build_retry_task(
    test_case: dict[str, Any],
    actual: str | None,
    failure_reason: str | None,
) -> str:
    expected_json = json.dumps(
        test_case["expected"],
        ensure_ascii=False,
    )

    return f"""
前一次輸出沒有通過 JSON 格式驗證。

原始任務:
{test_case["input"]}

預期 JSON:
{expected_json}

前一次輸出:
{actual or ""}

錯誤原因:
{failure_reason or ""}

請重新輸出結果。
只能輸出合法 JSON。
不要使用 markdown code block。
不要加入任何解釋文字。
""".strip()

這個 retry task 會提供四種資訊:

資訊 用途
原始任務 讓 Agent 知道使用者原本要什麼
預期 JSON 讓 Agent 知道格式和欄位
前一次輸出 讓 Agent 知道自己哪裡可能錯
錯誤原因 把 evaluator 的錯誤訊息回饋給 Agent

最後幾句是這版 retry 最重要的限制:

只能輸出合法 JSON。
不要使用 markdown code block。
不要加入任何解釋文字。

這些限制是針對 Day 16 看到的 format_error。


為什麼 retry task 要包含 expected?

這裡可能會有一個疑問:

把 expected JSON 放進 retry task,會不會太像洩漏答案?

在正式 benchmark 中,確實不能隨便把 expected answer 給模型。

但這裡的情境是教學用的可靠性平台,而且 retry 目標是修正格式,不是測知識能力。

我們要解決的是:

模型已經接近答對,但輸出格式不符合 evaluator。

例如:

actual: ```json
{ "answer": 15 }
```

這時把 expected JSON 結構放進 retry prompt,可以讓教學更直覺。

如果你想避免洩漏答案,可以改成只給 schema,不給 expected value。

例如:

{
  "answer": "number"
}

這個更嚴謹,但需要 Day 20 的 schema validation。

所以這次先用 expected JSON,並在文章中明確說明這是 MVP 取捨。


修改 run_evaluation:加入 retry 流程

接著修改 run_evaluation()。

Day 16 和 Day 18 後,runner 裡應該已經有:

evaluation = evaluate(test_case, result.answer)

要在第一次 evaluate 後插入 retry。

修改 evals/runner.py,在 run_evaluation() 內建立 agent 和 cases 後,加入:

retry_enabled = is_retry_enabled()
max_retries = 1 if retry_enabled else 0

接著在每一筆 case 的 try 區塊中,將原本的流程整理成:

result = agent.run(test_case["input"])
save_trace(result.trace)

evaluation = evaluate(test_case, result.answer)

retry_count = 0
initial_actual = None
initial_failure_type = None
initial_failure_reason = None
trace_session_ids = [result.trace.session_id]

if should_retry(
    test_case=test_case,
    evaluation=evaluation,
    retry_count=retry_count,
    max_retries=max_retries,
):
    initial_actual = result.answer
    initial_failure_type = evaluation.failure_type
    initial_failure_reason = evaluation.failure_reason

    retry_count += 1
    retry_task = build_retry_task(
        test_case=test_case,
        actual=result.answer,
        failure_reason=evaluation.failure_reason,
    )

    result = agent.run(retry_task)
    save_trace(result.trace)
    trace_session_ids.append(result.trace.session_id)

    evaluation = evaluate(test_case, result.answer)

這段邏輯做了幾件事。

第一,先正常跑第一次。

第二,先用 evaluator 評分。

第三,如果符合 retry 條件,才建立 retry task。

第四,第二次執行後,重新 evaluate。

第五,最後保存的是 retry 後的結果。

如果第二次修正成功,最後的 passed 會是:

true

但 eval result 仍然會記錄:

"retry_count": 1

這樣就能知道這題是靠 retry 通過的。


修改 result JSON:記錄 retry metadata

接著修改 append result 的地方。

修改 evals/runner.py,讓成功執行的 result dict 包含 retry 欄位:

results.append(
    {
        "case_id": test_case["id"],
        "input": test_case["input"],
        "expected": test_case["expected"],
        "grading_method": test_case["grading_method"],
        "task_type": test_case["task_type"],
        "status": "completed",
        "actual": result.answer,
        "passed": evaluation.passed,
        "failure_type": evaluation.failure_type,
        "failure_reason": evaluation.failure_reason,
        "retry_enabled": retry_enabled,
        "retry_count": retry_count,
        "initial_actual": initial_actual,
        "initial_failure_type": initial_failure_type,
        "initial_failure_reason": initial_failure_reason,
        "trace_session_id": result.trace.session_id,
        "trace_session_ids": trace_session_ids,
        "error": None,
    }
)

新增的欄位有:

欄位 說明
retry_enabled 這次 runner 是否啟用 retry
retry_count 這個 case 實際 retry 幾次
initial_actual 第一次失敗時的輸出
initial_failure_type 第一次失敗時的 failure type
initial_failure_reason 第一次失敗時的 failure reason
trace_session_ids 包含第一次與 retry 的 trace session id

其中 trace_session_id 保留為最後一次執行的 trace。

這樣 Day 17 的 Failure Dashboard 不需要馬上修改,也仍然能顯示一個主要 trace id。

如果要看 retry 前後兩次 trace,可以用 trace_session_ids。


exception 結果也加入 retry 欄位

如果 Agent 執行時發生 exception,還是會進入 except。

這類錯誤今天不 retry。

但為了讓 result schema 一致,except 裡也可以加入 retry 欄位。

修改 evals/runner.py 的 except 區塊:

except Exception as exc:
    results.append(
        {
            "case_id": test_case["id"],
            "input": test_case["input"],
            "expected": test_case["expected"],
            "grading_method": test_case["grading_method"],
            "task_type": test_case["task_type"],
            "status": "error",
            "actual": None,
            "passed": False,
            "failure_type": "execution_error",
            "failure_reason": "Agent execution error",
            "retry_enabled": retry_enabled,
            "retry_count": 0,
            "initial_actual": None,
            "initial_failure_type": None,
            "initial_failure_reason": None,
            "trace_session_id": None,
            "trace_session_ids": [],
            "error": str(exc),
        }
    )

這裡的重點是:

"failure_type": "execution_error"

如果是 API key、程式錯誤或 trace 資料流錯誤,retry prompt 沒有幫助。

要先修執行流程。


eval_run metadata 也記錄 retry_enabled

Day 18 已經讓 eval run 記錄:

{
  "llm_provider": "gemini",
  "prompt_version": "json_strict"
}

這次要再加入:

{
  "retry_enabled": true
}

修改 evals/runner.py,建立 eval_run 時加入:

eval_run = {
    "run_id": run_id,
    "created_at": datetime.now().isoformat(),
    "llm_provider": os.getenv("LLM_PROVIDER", "fake"),
    "prompt_version": prompt_version,
    "retry_enabled": retry_enabled,
    "total_cases": len(cases),
    "results": results,
}

這樣後面看到 eval run JSON 時,就能知道這次是否啟用了 retry。


修改 print_summary

為了讓終端機輸出更清楚,可以把 retry count 也印出來。

修改 evals/runner.py 的 print_summary():

def print_summary(eval_run: dict[str, Any]) -> None:
    total_cases = eval_run["total_cases"]
    passed_count = sum(1 for result in eval_run["results"] if result["passed"])
    failed_count = total_cases - passed_count

    print(f"Run ID: {eval_run['run_id']}")
    print(f"Provider: {eval_run.get('llm_provider', 'unknown')}")
    print(f"Prompt version: {eval_run.get('prompt_version', 'unknown')}")
    print(f"Retry enabled: {eval_run.get('retry_enabled', False)}")
    print(f"Total cases: {total_cases}")
    print(f"Passed: {passed_count}")
    print(f"Failed: {failed_count}")
    print()

    for result in eval_run["results"]:
        label = "PASS" if result["passed"] else "FAIL"
        retry_count = result.get("retry_count", 0)
        print(
            f"[{label}] {result['case_id']} - "
            f"{result['task_type']} - retry={retry_count}"
        )

        if result["failure_type"]:
            print(f"  type: {result['failure_type']}")

        if result["failure_reason"]:
            print(f"  reason: {result['failure_reason']}")

執行後可能會看到:

[PASS] case_013 - json_output - retry=1
[PASS] case_014 - json_output - retry=1
[FAIL] case_015 - json_output - retry=1
  type: format_error
  reason: Output is not valid JSON: Expecting value

這讓我們可以區分:

第一次就通過

和:

retry 後才通過

執行 retry disabled baseline

先跑一份不啟用 retry 的結果。

如果 Day 18 的 json_strict 已經讓 JSON 題全部通過,這裡可以先用 baseline prompt 觸發比較容易出現的格式錯誤。

RETRY_ENABLED=0 PROMPT_VERSION=baseline LLM_PROVIDER=gemini python3 -m evals.runner

這份結果是對照組。

輸出的 eval run JSON 會包含:

{
  "llm_provider": "gemini",
  "prompt_version": "baseline",
  "retry_enabled": false
}

這時 JSON 題如果輸出 markdown code fence,就會維持失敗。

例如:

{
  "case_id": "case_013",
  "passed": false,
  "failure_type": "format_error",
  "retry_count": 0
}

執行 retry enabled version

接著開啟 retry。

RETRY_ENABLED=1 PROMPT_VERSION=baseline LLM_PROVIDER=gemini python3 -m evals.runner

這份結果是 retry 版本。

輸出的 eval run JSON 會包含:

{
  "llm_provider": "gemini",
  "prompt_version": "baseline",
  "retry_enabled": true
}

如果 retry 成功,某筆 JSON 題可能會長這樣:

{
  "case_id": "case_013",
  "task_type": "json_output",
  "passed": true,
  "failure_type": null,
  "failure_reason": null,
  "retry_enabled": true,
  "retry_count": 1,
  "initial_actual": "```json\n{\"answer\": 15}\n```",
  "initial_failure_type": "format_error",
  "initial_failure_reason": "Output is not valid JSON: Expecting value",
  "actual": "{\"answer\": 15}"
}

這表示:

第一次失敗
retry 後通過

這是 retry 策略想要改善的情境。

如果你想用比較接近產品設定的方式測試,也可以改用 Day 18 的 improved prompt:

RETRY_ENABLED=1 PROMPT_VERSION=json_strict LLM_PROVIDER=gemini python3 -m evals.runner

只是如果 json_strict 已經讓所有 JSON 題第一次就通過,這次 run 可能會看到:

{
  "retry_enabled": true,
  "retry_count": 0
}

這也是正常結果。

它代表 retry 機制有開啟,但這次沒有被觸發。


怎麼比較 retry 是否有效?

今天先用三個指標比較。

比較時要先確認兩份 eval run 只有 RETRY_ENABLED 不同。

例如:

PROMPT_VERSION=baseline, RETRY_ENABLED=0
PROMPT_VERSION=baseline, RETRY_ENABLED=1

如果你拿 baseline + retry disabled 去比 json_strict + retry enabled,結果就會混在一起。

那樣無法分辨改善來自 prompt,還是來自 retry。

1. success rate 是否提升?

例如 retry 前:

Passed: 12 / 15
Success rate: 80.0%

retry 後:

Passed: 14 / 15
Success rate: 93.3%

這表示 retry 有提高整體通過率。

但仍然不能只看這個數字。

2. format_error 是否下降?

Retry 的目標是改善 format_error。

所以最重要的是看:

Failure Type Distribution

如果 retry 前:

failure_type count
format_error 3
wrong_answer 1

retry 後:

failure_type count
format_error 1
wrong_answer 1

這比較能說明 retry 有打到目標。

如果你用 json_strict 測試,並且 retry 前後的 format_error 都是 0,這不代表 retry 沒有價值。

它只代表:

這次 dataset 沒有觸發 retry。

這種情況下,Day 19 的驗證重點會變成:

  • retry 沒有誤觸發。
  • retry_count 都維持 0。
  • 開啟 retry 不會改變已通過 cases 的結果。

3. retry_count 是否集中在 JSON 題?

今天的 retry 條件只針對:

grading_method == json_exact
failure_type == format_error

所以如果你看到 retry_count 出現在大量非 JSON 題,就代表條件寫錯了。

可以檢查 eval run JSON:

python3 -m json.tool data/eval_runs/eval_run_你的檔名.json

確認 retry 發生在預期的 cases。


用 Failure Dashboard 看 retry 結果

Day 17 的 Failure Dashboard 目前還沒有專門的 retry 圖表。

但它仍然可以用來比較兩份 eval run。

啟動 dashboard:

streamlit run failure_dashboard_app.py

先選擇 retry disabled 那份 run,看:

  • success rate
  • failed cases
  • failure type distribution
  • task type failure rate

再選擇 retry enabled 那份 run,看同樣指標。

如果 retry 有效,通常會看到:

json_output failure_rate 下降
format_error count 下降
success rate 上升

但今天 dashboard 還不會直接顯示 retry_count。

如果想先看 retry count,可以直接查 JSON。

後面 Day 24 做 Reliability Dashboard 時,再把 retry count、latency 和 cost 一起放進去。


Retry 的限制

Retry 很有用,但不能濫用。

今天先記住幾個限制。

1. Retry 會增加成本

每 retry 一次,就是多一次 LLM call。

如果有 15 題,其中 3 題 retry,總呼叫次數就從:

15

變成:

18

目前我們還沒有記錄 token usage 和 cost。

Day 23 會補這件事。

2. Retry 會增加延遲

如果單次 LLM call 需要 2 秒,retry 一次可能讓該 case 多花 2 秒。

在 batch evaluation 中還好。

但如果是即時產品,retry 會直接影響使用者等待時間。

所以 retry 不應該無限制開啟。

3. Retry 可能讓結果更不穩定

有時候第二次輸出可能修好了格式,但改壞內容。

例如第一次:

{
  "answer": 15
}

外面多了 code fence。

第二次可能變成:

{
  "answer": "15"
}

格式是合法 JSON,但值的型別或內容可能不符合 expected。

所以 retry 後仍然要跑 evaluator。

4. Retry 不能修平台錯誤

如果錯誤是:

GEMINI_API_KEY is not set

或:

'NoneType' object has no attribute 'session_id'

retry 沒有幫助。

這些是 execution error,要修設定或程式。


這次真正驗證的是什麼?

如果 Day 18 的 json_strict 已經讓 JSON 題全數通過,那今天不一定會看到大量成功率提升。

這是正常的。

Day 19 真正要驗證的是平台是否具備這個能力:

當可偵測、可修正的格式錯誤發生時,
runner 可以自動產生修正任務,
讓 Agent retry 一次,
並把 retry 前後的結果記錄下來。

換句話說,這次建立的是可靠性機制,不只是為了修目前這三題 JSON cases。

如果目前 dataset 沒有觸發 retry,可以用兩種方式驗證。

第一,用 baseline prompt 跑。

RETRY_ENABLED=1 PROMPT_VERSION=baseline LLM_PROVIDER=gemini python3 -m evals.runner

這比較容易看到 JSON 題第一次失敗、retry 後修正的案例。

第二,之後加入更複雜的 JSON cases。

例如:

請用 JSON 回傳一個包含 status、items、total_count 的物件。
items 必須是陣列,每個 item 包含 name 和 score。

這類題目比目前三題更容易暴露格式不穩定。

到那時候,Day 19 的 retry 機制就能直接派上用場。


重點整理

這次在 batch evaluation runner 中加入第一版 retry 策略。

完成內容包含:

  • 用 RETRY_ENABLED 控制是否啟用 retry。
  • 新增 is_retry_enabled()。
  • 新增 should_retry()。
  • 新增 build_retry_task()。
  • 只針對 format_error 和 json_exact 重試。
  • 每個 case 最多 retry 一次。
  • 在 result 中記錄 retry_count。
  • 保留 initial_actual、initial_failure_type、initial_failure_reason。
  • 在 eval run metadata 中記錄 retry_enabled。

做完後,eval pipeline 從:

Agent answer
  -> evaluate
  -> save result

變成:

Agent answer
  -> evaluate
  -> if format_error: retry once
  -> evaluate again
  -> save result with retry metadata

這表示平台不只會發現錯誤,也開始有第一個自動改善策略。


下一步

Day 20 會把 JSON validation 往 Guardrail 的方向推進。

這次 retry 的判斷依賴 evaluator 的錯誤訊息。

下一篇會更明確地定義:

什麼叫符合 schema?
哪些欄位是 required?
欄位型別是否正確?
不符合時要怎麼阻擋?

也就是把 JSON 格式驗證從單純的 evaluator,提升成 Agent 輸出進入後續流程前的 guardrail。


上一篇
Day 18|Prompt Versioning 與 Prompt A/B Testing
下一篇
Day 20|Schema Validation 作為 Guardrail
系列文
從黑盒到可驗證:30 天打造 AI Agent 的 Trace、Eval 與 Guardrails 系統 共 24 篇
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言