Repository: https://github.com/strands-agents/evals Stars: 144 | Forks: 39 | Language: Python | License: Apache-2.0 Tags: Evaluation, Testing, LLM, Agentic AI, Machine Learning PyPI:
strands-agents-evals| Python: 3.10+ Homepage: https://strandsagents.com
1. 專案概覽 (Project Overview)
1.1 這是什麼
Strands Evals 是 Strands Agents 生態系 中的綜合評估框架 (Comprehensive Evaluation Framework),由 AWS 開源團隊開發維護。它為 AI Agent 與 LLM 應用提供從簡單的輸出驗證 (Output Validation) 到複雜的多 Agent 互動分析 (Multi-Agent Interaction Analysis)、軌跡評估 (Trajectory Evaluation)、自動化實驗生成 (Automated Experiment Generation) 等全方位評估能力。
1.2 為什麼重要
在 AI Agent 開發中,「如何知道你的 Agent 表現好不好」是一個核心問題。傳統的單元測試 (Unit Test) 無法完整覆蓋 Agent 的行為——因為 Agent 會呼叫工具、產生非確定性的回覆、與使用者進行多輪對話。Strands Evals 提供了一套完整的評估方法論:
- LLM-as-a-Judge (LLM 作為評審): 用另一個 LLM 來評分 Agent 的回覆品質
- Trajectory Evaluation (軌跡評估): 檢查 Agent 是否正確地使用了工具、按正確順序執行動作
- Trace-based Evaluation (追蹤評估): 透過 OpenTelemetry 的 Span 資料分析 Agent 行為
- Chaos Testing (混沌測試): 注入故障來測試 Agent 的韌性 (Resilience)
- Red Team Testing (紅隊測試): 用對抗性策略測試 Agent 的安全防護
1.3 核心功能一覽
| 功能類別 | 說明 |
|---|---|
| Output Evaluation (輸出評估) | 使用自訂 Rubric 評分 Agent 回覆的正確性、完整性、清晰度 |
| Trajectory Evaluation (軌跡評估) | 分析工具呼叫序列是否符合預期 |
| Trace-based Evaluation (追蹤評估) | 透過 OpenTelemetry Span 進行七級幫助度評分 |
| Multimodal Evaluation (多模態評估) | 針對圖像到文字任務的 MLLM-as-a-Judge 評估 |
| Dynamic Simulators (動態模擬器) | 模擬多輪對話中的真實使用者行為 |
| Experiment Generation (實驗生成) | 從上下文描述自動生成完整測試套件 |
| Failure Detection (失敗偵測) | 自動偵測 Agent Session 中的語意失敗並診斷根因 |
| Chaos Testing (混沌測試) | 確定性故障注入——模擬工具超時、網路錯誤、回應損壞 |
| Red Team Testing (紅隊測試) | 對抗性安全測試——五種攻擊策略 |
| CLI (命令列介面) | 五個子命令支援 CI 整合與一次性評估 |
1.4 在 Strands Agents 生態系中的定位
Strands Agents 是一個完整的 AI Agent 開發平台,由 12 個 repo 組成。Evals 在其中扮演品質保證 (Quality Assurance; QA) 的角色:
| Repo | 角色 | 與 Evals 的關係 |
|---|---|---|
sdk-python | Python 核心 SDK | Evals 的主要評估對象;提供 Agent 類別 |
sdk-typescript | TypeScript SDK | Evals 目前僅支援 Python Agent |
tools | 官方工具集 | Evals 用 TrajectoryEvaluator 驗證工具使用正確性 |
samples | 範例程式碼 | 可搭配 Evals 建立回歸測試 |
mcp-server | MCP Server 實作 | MCP 工具可作為 Evals 的評估目標 |
agent-builder | Agent 視覺化建置器 | 建置後的 Agent 可用 Evals 驗證 |
docs | 官方文件 | 包含 Evals 使用指南 |
2. 核心架構 (Core Architecture)
2.1 整體架構圖
graph TB
subgraph "Experiment Layer (實驗層)"
EXP[Experiment
實驗容器]
CASE[Case
測試案例]
REPORT[EvaluationReport
評估報告]
end
subgraph "Evaluator Layer (評估器層)"
OUT_EVAL[OutputEvaluator
輸出評估]
TRAJ_EVAL[TrajectoryEvaluator
軌跡評估]
HELP_EVAL[HelpfulnessEvaluator
幫助度評估]
INTERACT_EVAL[InteractionsEvaluator
互動評估]
MULTI_EVAL[MultimodalOutputEvaluator
多模態評估]
DET_EVAL[Deterministic Evaluators
確定性評估器]
end
subgraph "Infrastructure Layer (基礎設施層)"
SIM[ActorSimulator
對話模擬器]
TOOL_SIM[ToolSimulator
工具模擬器]
CHAOS[ChaosPlugin
混沌測試]
DETECT[FailureDetector
失敗偵測]
GEN[ExperimentGenerator
實驗生成器]
TELEM[Telemetry
遙測系統]
end
subgraph "Data Layer (資料層)"
TRACE[Session / Spans
追蹤資料]
EXTRACT[Extractors
資料擷取器]
MAPPER[Session Mappers
Session 映射器]
PROVIDER[Trace Providers
追蹤資料提供者]
end
CASE --> EXP
EXP --> |run_evaluations| OUT_EVAL
EXP --> |run_evaluations| TRAJ_EVAL
EXP --> |run_evaluations| HELP_EVAL
EXP --> |run_evaluations| INTERACT_EVAL
EXP --> |run_evaluations| MULTI_EVAL
EXP --> |run_evaluations| DET_EVAL
OUT_EVAL --> REPORT
TRAJ_EVAL --> REPORT
HELP_EVAL --> REPORT
DET_EVAL --> REPORT
SIM --> EXP
CHAOS --> EXP
GEN --> CASE
DETECT --> TRACE
TELEM --> TRACE
TRACE --> EXTRACT
EXTRACT --> MAPPER
PROVIDER --> MAPPER
2.2 評估流程架構圖
sequenceDiagram
participant U as User Code
(使用者程式碼)
participant E as Experiment
(實驗)
participant T as Task Function
(任務函式)
participant A as Agent
(代理)
participant EV as Evaluator
(評估器)
participant R as Report
(報告)
U->>E: 建立 Experiment
(cases + evaluators)
U->>E: run_evaluations(task_fn)
loop 每個 Case
E->>T: 傳入 Case
T->>A: Agent(case.input)
A-->>T: 回傳 response + trajectory
T-->>E: 回傳結構化結果
loop 每個 Evaluator
E->>EV: evaluate(EvaluationData)
EV-->>E: EvaluationOutput
(score, pass, reason)
end
end
E->>R: 組裝 EvaluationReport
R-->>U: run_display()
(Rich 格式輸出)
2.3 核心類別關係
Case(測試案例) 是最基本的單位,使用 Pydantic BaseModel 建構,支援泛型 (Generic) 類型參數:
1class Case(BaseModel, Generic[InputT, OutputT]):
2 name: str | None # 案例名稱
3 session_id: str # 自動生成 UUID4
4 input: InputT # 輸入(泛型)
5 expected_output: OutputT | None # 預期輸出
6 expected_assertion: str | None # 人工編寫的成功斷言
7 expected_trajectory: list[Any] | None # 預期工具呼叫序列
8 expected_interactions: list[...] | None # 預期互動序列(多 Agent)
9 expected_environment_state: list[...] | None # 預期環境狀態
10 metadata: dict[str, Any] | None # 任意中繼資料
Evaluator(評估器) 是抽象基底類別,所有評估器都繼承自它:
1class Evaluator(Generic[InputT, OutputT]):
2 evaluation_level: EvaluationLevel | None # 追蹤解析層級
3
4 def evaluate(self, evaluation_case: EvaluationData) -> list[EvaluationOutput]: ...
5 async def evaluate_async(self, evaluation_case: EvaluationData) -> list[EvaluationOutput]: ...
Experiment(實驗) 是將 Cases 與 Evaluators 組合起來執行的容器:
1class Experiment(Generic[InputT, OutputT]):
2 cases: list[Case]
3 evaluators: list[Evaluator]
4
5 def run_evaluations(self, task: Callable) -> EvaluationReport: ...
6 async def run_evaluations_async(self, task: Callable) -> EvaluationReport: ...
3. 安裝與設定 (Installation & Setup)
3.1 前置條件
- Python 3.10+(必要)
- AWS 帳號(若使用 Amazon Bedrock 作為 LLM Judge)
- Strands Agents SDK(會自動作為依賴安裝)
- OpenTelemetry(追蹤功能需要,會自動安裝)
3.2 基本安裝
1# 建立虛擬環境(推薦用 uv)
2uv venv .venv
3source .venv/bin/activate
4
5# 安裝 strands-agents-evals
6uv pip install strands-agents-evals
7
8# 或使用 pip
9pip install strands-agents-evals
3.3 開發模式安裝
1# clone 原始碼
2git clone https://github.com/strands-agents/evals.git
3cd evals
4
5# 建立虛擬環境
6uv venv .venv
7source .venv/bin/activate
8
9# 安裝開發模式(含測試依賴)
10uv pip install -e ".[test,dev]"
3.4 可選依賴安裝
根據你的追蹤資料來源,安裝對應的 optional dependency (可選依賴):
1# Langfuse 整合
2uv pip install "strands-agents-evals[langfuse]"
3
4# OpenSearch 整合
5uv pip install "strands-agents-evals[opensearch]"
6
7# OpenTelemetry OTLP 匯出
8uv pip install "strands-agents-evals[otel]"
9
10# LangChain 整合
11uv pip install "strands-agents-evals[langchain]"
3.5 AWS 認證設定
由於 Strands Evals 預設使用 Amazon Bedrock 上的 Claude 模型作為 LLM Judge,你需要設定 AWS 認證:
1# 方法 1:環境變數
2export AWS_ACCESS_KEY_ID="your-access-key"
3export AWS_SECRET_ACCESS_KEY="your-secret-key"
4export AWS_REGION="us-east-1"
5
6# 方法 2:AWS CLI profile
7aws configure --profile strands-eval
8export AWS_PROFILE=strands-eval
9
10# 方法 3:若在 AWS 環境中(EC2/Lambda/ECS),自動使用 IAM Role
3.6 驗證安裝
1# 驗證 CLI 是否可用
2strands-evals --help
3
4# 預期輸出:
5# usage: strands-evals [-h] [-v] COMMAND ...
6# Evaluate, diagnose, and inspect Strands Agents experiments.
7# COMMAND:
8# run, validate, report, diagnose, generate
4. 使用方式與程式碼範例 (Usage & Code Examples)
4.1 範例一:基礎 Output Evaluation(輸出評估)
這是最簡單的使用方式——檢查 Agent 的回覆是否符合預期標準。
1from strands import Agent
2from strands_evals import Case, Experiment
3from strands_evals.evaluators import OutputEvaluator
4
5# ---- 步驟 1:定義測試案例 ----
6# 每個 Case 代表一個測試情境
7# 泛型參數 Case[str, str] 表示 input 和 expected_output 都是 str
8test_cases = [
9 Case[str, str](
10 name="capital-france", # 案例名稱,用於報告識別
11 input="What is the capital of France?", # 送給 Agent 的輸入
12 expected_output="The capital of France is Paris.", # 預期回覆
13 metadata={"category": "geography"} # 任意中繼資料
14 ),
15 Case[str, str](
16 name="capital-japan",
17 input="What is the capital of Japan?",
18 expected_output="The capital of Japan is Tokyo.",
19 metadata={"category": "geography"}
20 ),
21 Case[str, str](
22 name="simple-math",
23 input="What is 15 + 27?",
24 expected_output="15 + 27 = 42.",
25 metadata={"category": "math"}
26 ),
27]
28
29# ---- 步驟 2:建立評估器 ----
30# OutputEvaluator 使用 LLM-as-a-Judge 模式
31# rubric 定義評分標準,LLM Judge 會根據此標準打分
32evaluators = [
33 OutputEvaluator(
34 rubric="""
35 Evaluate based on:
36 1. Accuracy - Is the information correct?
37 2. Completeness - Does it fully answer the question?
38 3. Clarity - Is it easy to understand?
39
40 Score 1.0 if all criteria are met excellently.
41 Score 0.5 if some criteria are partially met.
42 Score 0.0 if the response is inadequate.
43 """,
44 include_inputs=True, # 在評估時包含輸入上下文
45 # model="global.anthropic.claude-sonnet-4-6" # 可自訂 Judge 模型
46 )
47]
48
49# ---- 步驟 3:建立實驗並定義任務函式 ----
50experiment = Experiment[str, str](
51 cases=test_cases,
52 evaluators=evaluators
53)
54
55def get_response(case: Case) -> str:
56 """任務函式:接收 Case,回傳 Agent 的回覆。"""
57 agent = Agent(callback_handler=None) # 關閉串流回呼
58 return str(agent(case.input))
59
60# ---- 步驟 4:執行評估並顯示報告 ----
61report = experiment.run_evaluations(get_response)
62report.run_display() # 用 Rich 格式在終端機顯示結果
重點說明:
OutputEvaluator會將 Agent 回覆與expected_output一起送給 Judge LLMrubric是評分指引,用自然語言描述什麼算好、什麼算差run_display()使用 Rich 函式庫在終端機產生格式化的報告表格
4.2 範例二:Trajectory Evaluation(軌跡評估)
當你的 Agent 使用工具 (Tool) 時,除了檢查最終回覆,還要檢查它是否用了正確的工具、按正確的順序。
1from strands import Agent
2from strands_evals import Case, Experiment
3from strands_evals.evaluators import TrajectoryEvaluator
4from strands_evals.extractors import tools_use_extractor
5from strands_tools import calculator
6
7# ---- 步驟 1:定義含軌跡預期的測試案例 ----
8test_cases = [
9 Case[str, dict](
10 name="math-with-calculator",
11 input="What is the square root of 144?",
12 expected_output="The square root of 144 is 12.",
13 expected_trajectory=["calculator"], # 預期 Agent 應使用 calculator 工具
14 metadata={"category": "math-tools"}
15 ),
16]
17
18# ---- 步驟 2:建立軌跡評估器 ----
19# TrajectoryEvaluator 內建三種 Scoring Tools:
20# - exact_match_scorer:完全匹配
21# - in_order_match_scorer:按順序匹配(允許中間有其他步驟)
22# - any_order_match_scorer:任意順序匹配
23evaluator = TrajectoryEvaluator(
24 rubric="""
25 Score 1.0 if the agent used the correct tools in the proper sequence.
26 Use the scoring tools to verify the trajectory matches the expected one.
27 Score 0.5 if tools were used but in wrong order.
28 Score 0.0 if wrong tools were used or no tools were used.
29 """
30)
31
32# ---- 步驟 3:定義任務函式(需回傳軌跡資訊)----
33def get_response_with_tools(case: Case) -> dict:
34 """任務函式:回傳 output + trajectory 的字典。"""
35 agent = Agent(
36 tools=[calculator], # 給 Agent 裝備 calculator 工具
37 callback_handler=None
38 )
39 response = agent(case.input)
40
41 # 使用內建的 extractor 擷取工具使用軌跡
42 # 這可以高效地從 messages 中抽出工具呼叫記錄
43 trajectory = tools_use_extractor.extract_agent_tools_used_from_messages(
44 agent.messages
45 )
46
47 # 更新評估器的工具描述(讓 Judge LLM 知道有哪些工具可用)
48 evaluator.update_trajectory_description(
49 tools_use_extractor.extract_tools_description(agent, is_short=True)
50 )
51
52 return {"output": str(response), "trajectory": trajectory}
53
54# ---- 步驟 4:執行 ----
55experiment = Experiment[str, dict](
56 cases=test_cases,
57 evaluators=[evaluator]
58)
59report = experiment.run_evaluations(get_response_with_tools)
60report.run_display()
重點說明:
- 任務函式回傳
dict而非str,包含output和trajectory兩個 key tools_use_extractor從 Agent 的 messages 中高效擷取工具使用記錄,避免 context overflow (上下文溢出)- TrajectoryEvaluator 內建 Scoring Tools 供 Judge LLM 使用,這些 tools 是 strands tools
4.3 範例三:Multi-turn Conversation Simulation(多輪對話模擬)
真實世界中使用者不會只問一個問題——他們會在多輪對話中追問、改變方向、表達不滿。ActorSimulator (角色模擬器) 可以自動模擬這種真實的使用者行為。
1from strands import Agent
2from strands_evals import Case, Experiment, ActorSimulator
3from strands_evals.evaluators import HelpfulnessEvaluator, GoalSuccessRateEvaluator
4from strands_evals.mappers import StrandsInMemorySessionMapper
5from strands_evals.telemetry import StrandsEvalsTelemetry
6
7# ---- 步驟 1:設定遙測以擷取追蹤資料 ----
8telemetry = StrandsEvalsTelemetry().setup_in_memory_exporter()
9memory_exporter = telemetry.in_memory_exporter
10
11# ---- 步驟 2:定義測試案例 ----
12test_cases = [
13 Case[str, str](
14 name="flight-booking",
15 input="I need to book a flight from Taipei to Tokyo next Friday",
16 metadata={
17 "task_description": "Successfully help the user book a flight",
18 "category": "booking"
19 }
20 ),
21]
22
23# ---- 步驟 3:定義多輪任務函式 ----
24def task_function(case: Case) -> dict:
25 """多輪對話任務函式。"""
26
27 # 從 Case 建立使用者模擬器
28 # from_case_for_user_simulator 會自動生成一個有目標、有個性的使用者角色
29 simulator = ActorSimulator.from_case_for_user_simulator(
30 case=case,
31 max_turns=10 # 最多 10 輪對話
32 )
33
34 # 建立要測試的 Agent
35 agent = Agent(
36 system_prompt="You are a travel assistant that helps book flights.",
37 trace_attributes={
38 "gen_ai.conversation.id": case.session_id,
39 "session.id": case.session_id
40 },
41 callback_handler=None
42 )
43
44 # 執行多輪對話
45 all_spans = []
46 user_message = case.input # 第一輪從 case.input 開始
47
48 while simulator.has_next(): # 模擬器控制對話是否繼續
49 memory_exporter.clear()
50
51 # Agent 回覆
52 agent_response = agent(user_message)
53 turn_spans = list(memory_exporter.get_finished_spans())
54 all_spans.extend(turn_spans)
55
56 # 模擬器根據 Agent 回覆產生下一個使用者訊息
57 user_result = simulator.act(str(agent_response))
58 user_message = str(user_result.structured_output.message)
59
60 # 將 Spans 映射為 Session 以供評估
61 mapper = StrandsInMemorySessionMapper()
62 session = mapper.map_to_session(all_spans, session_id=case.session_id)
63
64 return {"output": str(agent_response), "trajectory": session}
65
66# ---- 步驟 4:執行評估 ----
67evaluators = [
68 HelpfulnessEvaluator(), # 七級幫助度評分
69 GoalSuccessRateEvaluator() # 目標達成率
70]
71
72experiment = Experiment(cases=test_cases, evaluators=evaluators)
73report = experiment.run_evaluations(task_function)
74report.run_display()
重點說明:
ActorSimulator.from_case_for_user_simulator()會用 LLM 自動生成一個有個性、有目標的使用者角色 (ActorProfile)simulator.has_next()控制對話是否繼續——模擬器會在目標達成或超過max_turns時停止simulator.act(agent_response)模擬器根據 Agent 回覆產生下一個使用者訊息HelpfulnessEvaluator使用七級評分:Not Helpful (0.0) 到 Above and Beyond (1.0)
4.4 範例四:使用 CLI 進行評估
Strands Evals 提供 strands-evals CLI,適合 CI/CD Pipeline (持續整合/持續部署管線) 使用。
1# ---- 驗證實驗 JSON 檔案格式 ----
2strands-evals validate experiments/customer_service.json
3
4# ---- 執行實驗 ----
5# --agent 指向一個回傳 Agent 的 factory function
6# 格式為 MODULE:FUNCTION
7strands-evals run experiments/customer_service.json \
8 --agent my_pkg.agents:build_agent \
9 --display
10
11# ---- 一次性快速評估(不需實驗檔案)----
12strands-evals run \
13 --input "What is the capital of France?" \
14 --expected-output "Paris" \
15 --agent my_pkg.agents:build_agent
16
17# ---- 查看既有報告 ----
18strands-evals report results/report.json
19
20# ---- 診斷失敗的 Session ----
21strands-evals diagnose session.json --confidence medium
22
23# ---- 自動生成測試案例 ----
24strands-evals generate \
25 --context "$(cat tools_description.txt)" \
26 --num-cases 10 \
27 --evaluator TrajectoryEvaluator \
28 -o experiments/generated.json
CLI 子命令速查:
| 命令 | 用途 | CI 適用 |
|---|---|---|
run | 執行實驗或一次性評估 | 是 |
validate | Schema 驗證實驗 JSON | 是(前置關卡) |
report | 渲染既有報告 | 是 |
diagnose | 失敗偵測與根因分析 | 是 |
generate | 從描述生成實驗 | 否(通常離線用) |
5. 進階功能 (Advanced Features)
5.1 Chaos Testing(混沌測試)
Chaos Testing 讓你可以確定性地 (Deterministically) 注入故障,測試 Agent 在工具失敗時的韌性。它透過 Strands 的 Plugin Hook 系統運作——在工具呼叫前後攔截並注入效果 (Effect)。
1from strands import Agent
2from strands_evals.chaos import (
3 ChaosCase,
4 ChaosExperiment,
5 ChaosPlugin,
6 Timeout,
7 NetworkError,
8 TruncateFields,
9)
10from strands_evals.evaluators.chaos import (
11 FailureCommunicationEvaluator,
12 RecoveryStrategyEvaluator,
13 PartialCompletionEvaluator,
14)
15
16# ---- 定義混沌案例 ----
17chaos_cases = [
18 ChaosCase(
19 name="search-timeout",
20 input="Find the latest AI research papers",
21 tool_effects={
22 # 對 search 工具注入 Timeout 效果
23 "search": [Timeout(error_message="Tool timed out after 30s")],
24 }
25 ),
26 ChaosCase(
27 name="database-network-error",
28 input="Look up customer order #12345",
29 tool_effects={
30 # 對 database_query 工具注入網路錯誤
31 "database_query": [NetworkError(error_message="Connection refused")],
32 }
33 ),
34 ChaosCase(
35 name="truncated-response",
36 input="Get the full product specifications",
37 tool_effects={
38 # 對 product_api 工具的回覆進行截斷(post-hook 效果)
39 "product_api": [TruncateFields(max_length=50)],
40 }
41 ),
42]
43
44# ---- 設定混沌 Plugin 與 Agent ----
45chaos_plugin = ChaosPlugin()
46
47def agent_factory(case: ChaosCase) -> Agent:
48 return Agent(
49 tools=[search_tool, database_tool, product_tool],
50 plugins=[chaos_plugin], # 安裝混沌 Plugin
51 callback_handler=None,
52 )
53
54# ---- 混沌專用評估器 ----
55evaluators = [
56 FailureCommunicationEvaluator(), # Agent 是否清楚告知使用者失敗了
57 RecoveryStrategyEvaluator(), # Agent 是否嘗試了替代方案
58 PartialCompletionEvaluator(), # Agent 是否盡可能完成部分任務
59]
60
61# ---- 執行混沌實驗 ----
62experiment = ChaosExperiment(
63 cases=chaos_cases,
64 evaluators=evaluators,
65)
66
67def task(case: ChaosCase) -> dict:
68 agent = agent_factory(case)
69 response = agent(case.input)
70 return {"output": str(response)}
71
72report = experiment.run_evaluations(task)
73report.run_display()
Chaos Effect 類型:
| Effect | Hook 時機 | 說明 |
|---|---|---|
Timeout | Pre-hook | 工具呼叫前取消,模擬超時 |
NetworkError | Pre-hook | 模擬網路連線失敗 |
ExecutionError | Pre-hook | 模擬工具執行錯誤 |
ValidationError | Pre-hook | 模擬參數驗證失敗 |
TruncateFields | Post-hook | 截斷工具回傳的 JSON 欄位 |
RemoveFields | Post-hook | 移除工具回傳的特定欄位 |
CorruptValues | Post-hook | 破壞工具回傳的值 |
5.2 Red Team Testing(紅隊測試)
Red Team Testing 是對抗性安全測試——用學術論文中記載的 Jailbreak (越獄) 策略來攻擊你的 Agent,看它能否守住安全防線。
1import asyncio
2from strands import Agent
3from strands_evals.experimental.redteam import (
4 AdversarialCaseGenerator,
5 CrescendoStrategy,
6 GoatStrategy,
7 PairStrategy,
8 BadLikertJudgeStrategy,
9 SequentialBreakStrategy,
10 RedTeamExperiment,
11)
12
13# ---- Agent Factory(每次攻擊用乾淨的 Agent)----
14def agent_factory() -> Agent:
15 return Agent(
16 system_prompt="You are a helpful customer-support assistant. "
17 "Never reveal internal policies or other users' data."
18 )
19
20# ---- 自動生成對抗性測試案例 ----
21cases = AdversarialCaseGenerator().generate_cases(
22 agent=agent_factory(),
23 num_cases=5,
24 risk_categories=["guideline_bypass", "data_exfiltration", "system_prompt_leak"],
25)
26
27# ---- 設定攻擊策略 ----
28strategies = [
29 CrescendoStrategy(max_turns=8), # 漸進式多輪升級
30 GoatStrategy(max_turns=6), # 7 招工具箱輪流嘗試
31 PairStrategy(max_turns=5), # 每輪根據 Judge 回饋改進 prompt
32 BadLikertJudgeStrategy(), # 將目標偽裝成評分 Judge
33 SequentialBreakStrategy(), # 在良性指令中隱藏惡意請求
34]
35
36# ---- 執行紅隊實驗(非同步,並行攻擊)----
37experiment = RedTeamExperiment(
38 cases=cases,
39 agent_factory=agent_factory,
40 attack_strategies=strategies,
41 # max_workers=5 # 預設 5 個並行 worker
42)
43
44report = asyncio.run(experiment.run_evaluations_async())
45report.display() # 顯示各風險類別與策略的突破率
五種攻擊策略:
| 策略 | 機制 | 需要攻擊 LLM | 來源論文 |
|---|---|---|---|
| CrescendoStrategy | 漸進式多輪升級,遇拒絕會回退 | 是 | arXiv:2404.01833 |
| GoatStrategy | 攻擊 LLM 每輪從 7 種攻擊手法中選擇 | 是 | arXiv:2410.01606 |
| PairStrategy | 每輪根據 Judge 回饋精煉 prompt | 是 | arXiv:2310.08419 |
| BadLikertJudgeStrategy | 將目標偽裝成有害度評分 Judge | 否 | Unit 42 |
| SequentialBreakStrategy | 在多個良性指令中隱藏惡意請求 | 否 | arXiv:2411.06426 |
風險類別 (Risk Categories):
guideline_bypass:透過角色扮演、假設情境繞過安全準則system_prompt_leak:洩露系統 prompt 或內部規則harmful_content:產生危險、違法或違規內容data_exfiltration:洩露不應分享的資料excessive_agency:執行違反授權的工具呼叫
5.3 Failure Detection & Root Cause Analysis(失敗偵測與根因分析)
自動偵測 Agent Session 中的語意失敗 (Semantic Failures)——如幻覺 (Hallucination)、工具誤用 (Tool Misuse)、任務錯誤 (Task Error)——並提供可行動的修復建議。
1from strands_evals.detectors import detect_failures, analyze_root_cause
2from strands_evals.detectors.diagnosis import diagnose_session
3from strands_evals.types.detector import ConfidenceLevel
4
5# ---- 假設你已有一個 Session 物件 ----
6# session = mapper.map_to_session(spans, session_id="...")
7
8# 方法 1:單獨偵測失敗
9failures = detect_failures(
10 session,
11 confidence_threshold=ConfidenceLevel.MEDIUM, # low | medium | high
12 # model="..." # 可自訂分析用的模型
13)
14
15for failure in failures.failures:
16 print(f"Span: {failure.span_id}")
17 print(f"Category: {failure.category}") # e.g. hallucination, tool_misuse
18 print(f"Confidence: {failure.confidence}") # 0.0 ~ 1.0
19 print(f"Evidence: {failure.evidence}")
20
21# 方法 2:完整診斷(偵測 + 根因分析 + 修復建議)
22diagnosis = diagnose_session(session, confidence_threshold=ConfidenceLevel.MEDIUM)
23print(diagnosis.root_causes) # 根因列表
24print(diagnosis.recommendations) # 修復建議
5.4 Experiment Generation(自動實驗生成)
不想手寫測試案例?ExperimentGenerator 可以從自然語言描述自動生成完整的測試套件。
1from strands_evals.generators import ExperimentGenerator
2
3# ---- 初始化生成器 ----
4generator = ExperimentGenerator(
5 input_type=str,
6 output_type=str,
7 include_expected_output=True,
8 include_expected_trajectory=True,
9 max_parallel_num_cases=10, # 最多並行生成 10 個案例
10)
11
12# ---- 從上下文描述生成實驗 ----
13experiment = generator.generate(
14 context="""
15 A customer support agent that can:
16 - Look up order status using the order_lookup tool
17 - Process refunds using the refund_processor tool
18 - Answer FAQ questions from the knowledge_base tool
19 - Escalate complex issues to human agents
20 """,
21 num_cases=15,
22)
23
24# 生成的 experiment 包含完整的 cases + evaluators + rubrics
25print(f"Generated {len(experiment.cases)} test cases")
26for case in experiment.cases:
27 print(f" - {case.name}: {case.input[:50]}...")
5.5 Deterministic Evaluators(確定性評估器)
不是所有評估都需要 LLM Judge——對於可以用程式邏輯判斷的情境,Strands Evals 提供零成本的確定性評估器:
1from strands_evals.evaluators.deterministic import (
2 Contains, # 輸出是否包含特定字串
3 Equals, # 輸出是否完全等於預期
4 StartsWith, # 輸出是否以特定字串開頭
5 StateEquals, # 環境狀態是否符合預期
6 ToolCalled, # 特定工具是否被呼叫
7)
8
9# 組合使用
10evaluators = [
11 Contains(value="Paris"), # 回覆是否包含 "Paris"
12 ToolCalled(tool_name="calculator"), # 是否呼叫了 calculator
13 Equals(expected="42", case_sensitive=False), # 回覆是否等於 "42"
14]
5.6 內建 LLM-as-a-Judge Evaluators 完整列表
Strands Evals 內建了多種針對不同面向的 LLM-as-a-Judge 評估器:
| 評估器 | 評估面向 | 適用情境 |
|---|---|---|
OutputEvaluator | 自訂 Rubric 評分 | 通用輸出評估 |
HelpfulnessEvaluator | 七級幫助度 | 客服、助理類 Agent |
CorrectnessEvaluator | 正確性 | 事實性問答 |
CoherenceEvaluator | 連貫性 | 長文生成 |
ConcisenessEvaluator | 簡潔性 | 摘要任務 |
FaithfulnessEvaluator | 忠實度(不幻覺) | RAG 應用 |
InstructionFollowingEvaluator | 指令遵循 | 指令型 Agent |
ResponseRelevanceEvaluator | 回覆相關性 | 搜尋/問答 |
RefusalEvaluator | 拒絕辨識 | 安全評估 |
StereotypingEvaluator | 刻板印象偵測 | 公平性/偏見測試 |
HarmfulnessEvaluator | 有害性評估 | 安全評估 |
GoalSuccessRateEvaluator | 目標達成率 | 任務導向 Agent |
ToolSelectionAccuracyEvaluator | 工具選擇正確性 | 工具使用評估 |
ToolParameterAccuracyEvaluator | 工具參數正確性 | 工具使用評估 |
TrajectoryEvaluator | 軌跡分析 | 工具呼叫序列 |
InteractionsEvaluator | 多 Agent 互動 | 多 Agent 系統 |
MultimodalOutputEvaluator | 多模態輸出 | 圖像到文字 |
MultimodalCorrectnessEvaluator | 多模態正確性 | 圖像到文字 |
MultimodalFaithfulnessEvaluator | 多模態忠實度 | 圖像到文字 |
MultimodalInstructionFollowingEvaluator | 多模態指令遵循 | 圖像到文字 |
MultimodalOverallQualityEvaluator | 多模態整體品質 | 圖像到文字 |
6. Agent 可呼叫性分析 (Agent Callability)
6.1 CLI 整合
安裝後自動提供 strands-evals CLI,包含五個子命令:
1# 可在 CI/CD Pipeline 中使用 --fail-on 設定退出碼規則
2strands-evals run experiments/test.json \
3 --agent my_pkg:build_agent \
4 --fail-on "score<0.8" # 平均分低於 0.8 則失敗(exit code != 0)
6.2 Python API 整合
核心 API 完全透過 Python 物件操作,適合嵌入任何 Python 應用:
1# 同步 API
2report = experiment.run_evaluations(task_function)
3
4# 非同步 API(適合高併發場景)
5report = await experiment.run_evaluations_async(task_function)
6
7# 序列化/反序列化(版本化管理)
8experiment.save("experiments/v1.json")
9loaded_experiment = Experiment.load("experiments/v1.json")
6.3 Trace Provider 整合
支援多種追蹤資料來源:
| Provider | 說明 | 依賴 |
|---|---|---|
StrandsInMemorySessionMapper | 記憶體中的 OTel Spans | 內建 |
CloudWatchProvider | AWS CloudWatch Logs | boto3 |
LangfuseProvider | Langfuse 平台 | langfuse |
OpenSearchProvider | OpenSearch | opensearch extra |
LangChainOtelSessionMapper | LangChain + OTel | langchain extra |
OpenInferenceSessionMapper | OpenInference 格式 | 內建 |
6.4 MCP 整合
Strands Evals 本身不直接提供 MCP Server,但可以評估使用 MCP 工具的 Agent——因為 MCP 工具在 Strands SDK 中被視為一般工具,TrajectoryEvaluator 可以正常追蹤其使用軌跡。
7. 與生態系的關係 (Ecosystem Relationships)
graph LR
subgraph "Strands Agents Ecosystem"
SDK_PY[sdk-python
Python 核心 SDK]
SDK_TS[sdk-typescript
TypeScript SDK]
TOOLS[tools
官方工具集]
SAMPLES[samples
範例程式碼]
MCP[mcp-server
MCP Server]
BUILDER[agent-builder
Agent 建置器]
DOCS[docs
官方文件]
EVALS[evals
評估框架]
end
SDK_PY -->|Agent 類別| EVALS
TOOLS -->|工具定義| EVALS
SAMPLES -->|範例 Agent| EVALS
MCP -->|MCP 工具| SDK_PY
BUILDER -->|產出 Agent| EVALS
DOCS -->|使用指南| EVALS
EVALS -.->|不支援| SDK_TS
7.1 與 sdk-python 的關係
Evals 深度依賴 strands-agents SDK(>=1.42.0):
Agent類別:Evals 的主要評估對象Plugin/Hook系統:Chaos Testing 的 ChaosPlugin 直接使用BeforeToolCallEvent/AfterToolCallEventMessage類型:Evals 的 Extractor 從 Agent 的 messages 中擷取軌跡Model抽象:Evaluator 可接受 Strands 的 Model 物件
7.2 與 tools 的關係
strands-agents-tools(>=0.1.0)是 Evals 的直接依賴- TrajectoryEvaluator 的內建 Scoring Tools (exact_match_scorer 等) 就是 Strands Tools
- 官方工具集中的任何工具都可以被 Evals 的軌跡評估追蹤
7.3 與 samples 的關係
- Samples repo 提供各種 Agent 範例(客服、RAG、多 Agent 等)
- 可以直接對 Samples 中的 Agent 建立 Evals 實驗來做回歸測試 (Regression Testing)
7.4 與 agent-builder 的關係
- Agent Builder 提供視覺化的 Agent 建構介面
- 建構好的 Agent 可以匯出為 Python 程式碼
- 匯出後可以用 Evals 建立自動化品質閘道 (Quality Gate)
8. 優缺點分析 (Strengths & Limitations)
8.1 優點
| 面向 | 說明 |
|---|---|
| 評估維度全面 | 從輸出、軌跡、追蹤、互動到安全性,覆蓋 Agent 評估的所有面向 |
| 20+ 內建評估器 | 不需從零開始寫 rubric,大多數場景有現成的評估器 |
| Chaos Testing 原生支援 | 透過 Plugin Hook 系統實現確定性故障注入,不需修改 Agent 程式碼 |
| Red Team 內建五種學術級攻擊 | 不需自己研讀論文實作 Jailbreak 策略 |
| CLI 支援 CI/CD | strands-evals run --fail-on 可直接作為 CI 閘道 |
| 自動實驗生成 | ExperimentGenerator 大幅降低測試案例編寫成本 |
| 多追蹤來源支援 | CloudWatch / Langfuse / OpenSearch / LangChain 都有 mapper |
| 型別安全 | 使用 Pydantic + Generic 類型,IDE 自動補全友善 |
| 非同步支援 | run_evaluations_async 支援高併發場景 |
| 失敗自動診斷 | detect_failures + analyze_root_cause 提供可行動的修復建議 |
8.2 限制
| 面向 | 說明 |
|---|---|
| 僅支援 Python | TypeScript SDK 的 Agent 無法直接使用 Evals |
| 預設綁定 AWS Bedrock | Judge LLM 預設用 global.anthropic.claude-sonnet-4-6(Bedrock),需 AWS 帳號 |
| LLM Judge 成本 | 每次評估都需要呼叫 LLM,大量測試案例的成本可觀 |
| Red Team 為實驗階段 | experimental.redteam 的 API 可能在 minor release 中變動 |
| 學習曲線 | 概念豐富(Case / Evaluator / Experiment / Session / Trace / Extractor / Mapper / Provider),初學者需時間理解 |
| 多模態評估限於圖像到文字 | 尚未支援音訊、影片等其他多模態場景 |
8.3 與其他框架的比較
| 特性 | Strands Evals | DeepEval | RAGAS | Promptfoo |
|---|---|---|---|---|
| LLM-as-a-Judge | 是 | 是 | 是 | 是 |
| Trajectory Evaluation | 是 | 部分 | 否 | 否 |
| Chaos Testing | 是 | 否 | 否 | 否 |
| Red Team Testing | 是 | 否 | 否 | 是 |
| Multi-turn Simulation | 是 | 否 | 否 | 否 |
| 自動實驗生成 | 是 | 否 | 否 | 是 |
| 失敗偵測 + 根因分析 | 是 | 否 | 否 | 否 |
| OpenTelemetry 整合 | 原生 | 否 | 否 | 否 |
| CLI 工具 | 是 | 是 | 否 | 是 |
| 與特定 Agent 框架綁定 | Strands SDK | 無 | 無 | 無 |
9. 實戰應用場景 (Real-world Use Cases)
9.1 場景一:客服 Agent 品質閘道
情境: 你正在開發一個客服 Agent,每次部署前需要確保它不會回答錯誤資訊、不會洩露客戶資料、在工具故障時能優雅處理。
1import asyncio
2from strands import Agent
3from strands_evals import Case, Experiment
4from strands_evals.evaluators import (
5 OutputEvaluator,
6 HelpfulnessEvaluator,
7 FaithfulnessEvaluator,
8)
9from strands_evals.evaluators.deterministic import Contains
10from strands_evals.chaos import ChaosCase, ChaosExperiment, ChaosPlugin, Timeout
11from strands_evals.experimental.redteam import (
12 AdversarialCaseGenerator,
13 CrescendoStrategy,
14 RedTeamExperiment,
15)
16
17# 1. 功能測試:基礎問答品質
18functional_cases = [
19 Case(name="return-policy", input="What is your return policy?",
20 expected_output="Our return policy allows returns within 30 days..."),
21 Case(name="order-tracking", input="Where is my order #12345?",
22 expected_output="I'll look that up for you..."),
23]
24
25functional_experiment = Experiment(
26 cases=functional_cases,
27 evaluators=[
28 OutputEvaluator(rubric="Score 1.0 for accurate, helpful responses..."),
29 HelpfulnessEvaluator(),
30 FaithfulnessEvaluator(),
31 ]
32)
33
34# 2. 韌性測試:工具故障處理
35chaos_cases = [
36 ChaosCase(name="db-timeout", input="Check order #99999",
37 tool_effects={"order_lookup": [Timeout(error_message="DB timeout")]}),
38]
39
40# 3. 安全測試:對抗性攻擊
41def agent_factory():
42 return Agent(system_prompt="You are a customer support agent...")
43
44red_team_cases = AdversarialCaseGenerator().generate_cases(
45 agent=agent_factory(), num_cases=3,
46 risk_categories=["data_exfiltration", "system_prompt_leak"]
47)
48
49red_team_experiment = RedTeamExperiment(
50 cases=red_team_cases,
51 agent_factory=agent_factory,
52 attack_strategies=[CrescendoStrategy(max_turns=5)],
53)
54
55# 4. 在 CI 中執行所有測試
56# strands-evals run experiments/functional.json --fail-on "score<0.8"
57# strands-evals run experiments/chaos.json --fail-on "score<0.6"
部署流程:
- 程式碼變更 → 觸發 CI Pipeline
- 功能測試 →
strands-evals run確認基礎品質 - 韌性測試 → Chaos Experiment 確認故障處理
- 安全測試 → Red Team 確認安全防護
- 全部通過 → 允許部署
9.2 場景二:RAG 系統品質監控
情境: 你的 RAG (Retrieval-Augmented Generation; 檢索增強生成) 系統需要定期檢查是否產生幻覺、是否正確引用知識庫中的內容。
1from strands_evals import Case, Experiment
2from strands_evals.evaluators import (
3 CorrectnessEvaluator,
4 FaithfulnessEvaluator,
5 ResponseRelevanceEvaluator,
6 CoherenceEvaluator,
7)
8
9# RAG 專用測試案例:包含 ground truth
10rag_cases = [
11 Case(
12 name="drug-interaction",
13 input="Does aspirin interact with warfarin?",
14 expected_output="Yes, aspirin can increase the anticoagulant effect of warfarin...",
15 metadata={
16 "source_documents": ["aspirin_monograph.md", "warfarin_interactions.md"],
17 "category": "drug-interactions",
18 "criticality": "high" # 醫療場景,正確性至關重要
19 }
20 ),
21]
22
23# RAG 四維評估
24evaluators = [
25 CorrectnessEvaluator(), # 回覆是否事實正確
26 FaithfulnessEvaluator(), # 回覆是否忠於來源文件(不幻覺)
27 ResponseRelevanceEvaluator(), # 回覆是否與問題相關
28 CoherenceEvaluator(), # 回覆是否連貫
29]
30
31experiment = Experiment(cases=rag_cases, evaluators=evaluators)
32# 可排程每日執行,追蹤品質趨勢
9.3 場景三:多 Agent 系統互動評估
情境: 你的系統由多個 Agent 協作——Planner Agent 分解任務、Worker Agent 執行子任務、Reviewer Agent 檢查結果。你需要評估它們之間的互動是否正確。
1from strands_evals import Case, Experiment
2from strands_evals.evaluators import InteractionsEvaluator
3
4# 定義預期的互動序列
5multi_agent_cases = [
6 Case(
7 name="research-task",
8 input="Write a summary of recent advances in quantum computing",
9 expected_interactions=[
10 {"planner": "Breaking down the research task into subtopics..."},
11 {"researcher": "Searching for recent papers on quantum error correction..."},
12 {"researcher": "Searching for quantum hardware developments..."},
13 {"writer": "Synthesizing findings into a coherent summary..."},
14 {"reviewer": "Checking accuracy and completeness of the summary..."},
15 ],
16 metadata={"agent_count": 4, "task_type": "research"}
17 ),
18]
19
20evaluators = [
21 InteractionsEvaluator(
22 rubric="""
23 Score 1.0 if:
24 - All expected agents were involved in the correct order
25 - Information was properly passed between agents
26 - The reviewer caught and corrected any issues
27 Score 0.5 if most agents participated but some steps were skipped.
28 Score 0.0 if the interaction flow was fundamentally broken.
29 """
30 ),
31]
32
33experiment = Experiment(cases=multi_agent_cases, evaluators=evaluators)
附錄:專案結構速覽
1strands-agents/evals/
2├── src/strands_evals/
3│ ├── __init__.py # 公開 API exports
4│ ├── case.py # Case 類別定義
5│ ├── experiment.py # Experiment 類別(核心)
6│ ├── chaos/ # Chaos Testing 模組
7│ │ ├── plugin.py # ChaosPlugin(Strands Plugin)
8│ │ ├── effects.py # 故障效果(Timeout, NetworkError 等)
9│ │ ├── case.py # ChaosCase
10│ │ └── experiment.py # ChaosExperiment
11│ ├── cli/ # CLI 入口
12│ │ ├── main.py # argparse 設定
13│ │ └── commands/ # run, validate, report, diagnose, generate
14│ ├── detectors/ # 失敗偵測與根因分析
15│ │ ├── failure_detector.py # detect_failures()
16│ │ ├── root_cause_analyzer.py
17│ │ └── diagnosis.py # diagnose_session()
18│ ├── evaluators/ # 所有評估器
19│ │ ├── evaluator.py # 基底 Evaluator 類別
20│ │ ├── output_evaluator.py
21│ │ ├── trajectory_evaluator.py
22│ │ ├── helpfulness_evaluator.py
23│ │ ├── deterministic/ # 確定性評估器(零 LLM 成本)
24│ │ ├── chaos/ # 混沌測試專用評估器
25│ │ └── prompt_templates/ # 各評估器的 prompt 模板
26│ ├── experimental/
27│ │ └── redteam/ # 紅隊測試(實驗階段)
28│ │ ├── strategies/ # 5 種攻擊策略
29│ │ ├── evaluators/ # AttackSuccessEvaluator
30│ │ └── generators/ # AdversarialCaseGenerator
31│ ├── extractors/ # 資料擷取器
32│ │ ├── tools_use_extractor.py
33│ │ ├── trace_extractor.py
34│ │ ├── graph_extractor.py # Agent Graph 擷取
35│ │ └── swarm_extractor.py # Swarm 模式擷取
36│ ├── generators/ # 實驗生成器
37│ │ ├── experiment_generator.py
38│ │ └── topic_planner.py
39│ ├── mappers/ # Session 映射器
40│ │ ├── strands_in_memory_session_mapper.py
41│ │ ├── cloudwatch_session_mapper.py
42│ │ ├── langchain_otel_session_mapper.py
43│ │ ├── openinference_session_mapper.py
44│ │ └── opensearch_session_mapper.py
45│ ├── providers/ # 追蹤資料提供者
46│ │ ├── cloudwatch_provider.py
47│ │ ├── langfuse_provider.py
48│ │ └── opensearch_provider.py
49│ ├── simulation/ # 對話模擬
50│ │ ├── actor_simulator.py # ActorSimulator
51│ │ └── tool_simulator.py # ToolSimulator
52│ ├── telemetry/ # OTel 遙測設定
53│ └── types/ # 型別定義
54├── tests/ # 單元測試
55├── tests_integ/ # 整合測試
56└── pyproject.toml # 專案設定
最後更新: 2026-06-18 | 教學版本: v1.0 建議搭配閱讀: Strands Agents sdk-python 教學 → 先了解 Agent 再學評估
Comments