Repository: https://github.com/strands-agents/harness-sdk Stars: 6,187 | Forks: 887 | License: Apache-2.0 Languages: Python, TypeScript | Tags: SDK, Agent Framework, Agentic AI, MCP, Multi-Agent Systems Homepage: https://strandsagents.com/
1. 專案概覽 (Project Overview)
1.1 這是什麼
Strands Agents Harness SDK 是由 AWS 開源的 AI Agent (AI 代理) 開發框架,採用 model-driven (模型驅動) 的設計哲學,讓開發者只需數行程式碼就能建立功能完整的 AI Agent。這是一個 monorepo (單一程式碼倉庫),同時包含 Python SDK 與 TypeScript SDK,以及文件網站、WebAssembly bindings (WASM 綁定) 和開發者 CLI 工具。
核心套件名稱:
- Python:
strands-agents(PyPI) - TypeScript:
@strands-agents/sdk(npm)
1.2 誰做的、為什麼重要
Strands Agents 由 AWS 團隊開發並開源,屬於 strands-agents GitHub organization (組織) 下的核心專案。它的重要性在於:
- Model Agnostic (模型無關性):原生支援 Amazon Bedrock、Anthropic、OpenAI、Gemini、Ollama、LiteLLM、Mistral、LlamaCpp、SageMaker、Writer 等 12 種以上的 Model Provider (模型提供者)
- Production-Ready (生產就緒):內建 observability (可觀測性)、context management (上下文管理)、retry strategy (重試策略)、sandbox (沙箱隔離)、session management (工作階段管理)
- MCP 原生支援:內建 Model Context Protocol (MCP; 模型上下文協定) 支援
- Multi-Agent (多代理人) 架構:支援 Agent-as-Tool、A2A (Agent-to-Agent) 協定、Swarm 模式
- 雙語言 SDK:Python 與 TypeScript 共享相同的設計理念與 API 風格
1.3 Monorepo 結構
| 目錄 | 說明 |
|---|---|
strands-py/ | Python SDK:agent loop、model providers、tools |
strands-ts/ | TypeScript SDK:agent loop、model providers、tools |
strands-wasm/ | WebAssembly bindings,讓 TypeScript agent 執行 Python tools |
strands-py-wasm/ | Python host for WASM components |
strandly/ | 開發者 CLI 工具 |
site/ | strandsagents.com 文件網站 (Astro/Starlight) |
team/ | 治理文件與跨 SDK 流程文件 |
2. 核心架構 (Core Architecture)
2.1 Agent 執行迴圈
Strands Agents 的核心是一個 Event Loop (事件迴圈),它協調使用者輸入、模型推論 (inference)、工具執行 (tool execution) 三者之間的互動。這個迴圈是整個框架最關鍵的元件。
flowchart TD
A[使用者輸入
User Input] --> B[Agent.__call__]
B --> C[BeforeInvocationEvent
Hook / Intervention 攔截點]
C -->|Deny| Z[終止並回傳]
C -->|Proceed| D[Event Loop 開始]
D --> E[Conversation Manager
管理上下文視窗]
E --> F[BeforeModelCallEvent
Hook 攔截點]
F --> G[Model Provider
呼叫 LLM 推論]
G --> H[AfterModelCallEvent
Hook 攔截點]
H --> I{模型回應類型?}
I -->|end_turn| J[AfterInvocationEvent]
I -->|tool_use| K[BeforeToolCallEvent
Intervention 攔截點]
K -->|Deny| L[回傳拒絕結果給模型]
K -->|Proceed| M[Tool Executor
執行工具]
M --> N[AfterToolCallEvent
Hook 攔截點]
N --> O[工具結果加入 messages]
O --> E
J --> P[AgentResult
最終回應]
L --> E
style A fill:#e1f5fe
style P fill:#c8e6c9
style Z fill:#ffcdd2
2.2 系統分層架構
整個 SDK 的模組分層清晰,每一層都有明確的職責:
graph TB
subgraph "使用者介面層 (User Interface Layer)"
UI1[Agent 類別
主要入口點]
UI2[AgentBase 抽象基底]
UI3[A2AAgent
遠端 Agent 客戶端]
end
subgraph "編排層 (Orchestration Layer)"
OL1[Event Loop
事件迴圈引擎]
OL2[Conversation Manager
上下文視窗管理]
OL3[Session Manager
工作階段持久化]
OL4[Memory Manager
跨 session 記憶]
end
subgraph "控制層 (Control Layer)"
CL1[Hook Registry
生命週期鉤子]
CL2[Intervention Registry
Guardrail 介入處理]
CL3[Middleware Registry
中介層管線]
CL4[Plugin Registry
外掛機制]
end
subgraph "執行層 (Execution Layer)"
EL1[Tool Registry
工具註冊表]
EL2[Tool Executor
工具執行器]
EL3[Tool Caller
工具呼叫器]
EL4[Structured Output
結構化輸出]
end
subgraph "基礎設施層 (Infrastructure Layer)"
IL1[Model Providers
12+ 種模型後端]
IL2[Sandbox
Docker / SSH / POSIX]
IL3[Telemetry
OpenTelemetry 追蹤]
IL4[Streaming
串流處理]
end
UI1 --> OL1
UI1 --> OL2
UI1 --> OL3
UI1 --> OL4
OL1 --> CL1
OL1 --> CL2
OL1 --> CL3
OL1 --> EL1
OL1 --> EL2
CL4 --> CL1
CL4 --> EL1
EL1 --> IL1
EL2 --> IL2
OL1 --> IL3
OL1 --> IL4
style UI1 fill:#e3f2fd
style OL1 fill:#fff3e0
style CL1 fill:#fce4ec
style EL1 fill:#e8f5e9
style IL1 fill:#f3e5f5
2.3 核心模組說明
Model Provider (模型提供者)
SDK 內建 12 種以上的 Model Provider,每一個都實作 Model 抽象基底類別:
| Provider 類別 | 對應服務 | 特色 |
|---|---|---|
BedrockModel | Amazon Bedrock | 預設 provider,支援多種基礎模型 |
AnthropicModel | Anthropic API | 直接呼叫 Claude |
OpenAIModel | OpenAI API | GPT 系列 |
GeminiModel | Google Gemini | 原生 Gemini API |
OllamaModel | Ollama | 本地模型推論 |
LiteLLMModel | LiteLLM | 統一 API 代理 |
MistralModel | Mistral AI | Mistral 系列 |
LlamaCppModel | llama.cpp | 本地 GGUF 模型 |
SageMakerModel | AWS SageMaker | 自建端點 |
WriterModel | Writer API | Writer Palmyra 系列 |
LlamaAPIModel | Llama API | Llama 雲端 API |
OpenAIResponsesModel | OpenAI Responses API | Responses API 版 |
Conversation Manager (對話管理器)
管理上下文視窗 (context window) 大小,避免 token 超限:
SlidingWindowConversationManager:滑動視窗策略(預設)SummarizingConversationManager:自動摘要壓縮NullConversationManager:不做任何管理(用於 stateful model)"auto"模式:結合 ContextOffloader + SummarizingConversationManager
Sandbox (沙箱)
提供隔離的程式碼執行環境:
NotASandboxLocalEnvironment:預設,直接在主機執行(無隔離)PosixShellSandbox:POSIX shell 沙箱DockerSandbox:透過docker exec在容器內執行SSHSandbox:透過 SSH 在遠端機器執行
3. 安裝與設定 (Installation & Setup)
3.1 系統需求
Python SDK:
- Python 3.10 或以上
- pip、uv 或 hatch(套件管理)
TypeScript SDK:
- Node.js 20 或以上
- npm(套件管理)
3.2 Python SDK 安裝
1# 使用 pip 安裝核心 SDK
2pip install strands-agents
3
4# 安裝官方工具集(選用,但強烈建議)
5pip install strands-agents-tools
6
7# 如果使用 uv(推薦)
8uv pip install strands-agents strands-agents-tools
安裝特定 Model Provider 的額外依賴:
1# Anthropic 直接 API
2pip install strands-agents[anthropic]
3
4# OpenAI
5pip install strands-agents[openai]
6
7# Ollama(本地模型)
8pip install strands-agents[ollama]
9
10# LiteLLM(統一代理)
11pip install strands-agents[litellm]
3.3 TypeScript SDK 安裝
1npm install @strands-agents/sdk
3.4 Model Provider 設定
Amazon Bedrock(預設)
SDK 預設使用 Amazon Bedrock,需要設定 AWS credentials:
1# 方法 1:設定環境變數
2export AWS_ACCESS_KEY_ID="your-access-key"
3export AWS_SECRET_ACCESS_KEY="your-secret-key"
4export AWS_DEFAULT_REGION="us-east-1"
5
6# 方法 2:使用 AWS CLI 設定
7aws configure
8
9# 方法 3:使用 AWS SSO
10aws sso login --profile your-profile
確認已在 Bedrock console 啟用所需的基礎模型存取權限(例如 Claude Sonnet)。
Anthropic API
1export ANTHROPIC_API_KEY="sk-ant-..."
1from strands import Agent
2from strands.models.anthropic import AnthropicModel
3
4model = AnthropicModel(model_id="claude-sonnet-4-20250514")
5agent = Agent(model=model)
OpenAI API
1export OPENAI_API_KEY="sk-..."
1from strands import Agent
2from strands.models.openai import OpenAIModel
3
4model = OpenAIModel(model_id="gpt-4o")
5agent = Agent(model=model)
Ollama(本地模型)
1# 先啟動 Ollama 並拉取模型
2ollama pull llama3.1
3
4# 使用
5from strands import Agent
6from strands.models.ollama import OllamaModel
7
8model = OllamaModel(host="http://localhost:11434", model_id="llama3.1")
9agent = Agent(model=model)
4. 使用方式與程式碼範例 (Usage & Code Examples)
4.1 基本 Agent 建立與對話
最簡單的 Agent 只需要一行程式碼就能建立:
1from strands import Agent
2from strands_tools import calculator
3
4# 建立 Agent,配備計算機工具
5# Agent 預設使用 Amazon Bedrock 作為 Model Provider
6agent = Agent(tools=[calculator])
7
8# 呼叫 Agent —— 就像呼叫一個函式一樣直覺
9result = agent("1764 的平方根是多少?")
10# Agent 會自動決定是否使用 calculator 工具
11# 最終回傳 AgentResult 物件
逐行解說:
| 行 | 說明 |
|---|---|
from strands import Agent | 匯入核心 Agent 類別 |
from strands_tools import calculator | 從官方工具套件匯入計算機工具 |
Agent(tools=[calculator]) | 建立 Agent,工具清單傳入 tools 參數 |
agent("...") | 呼叫 __call__ 方法,傳入自然語言作為 prompt |
Agent 的 __call__ 方法會啟動 Event Loop,模型可能會多次迴圈(呼叫工具、取得結果、再推論)直到產生最終回應。
4.2 自訂工具 (Custom Tool) 與 @tool Decorator
Strands 提供 @tool 裝飾器 (decorator),可以將任意 Python 函式轉為 Agent 可呼叫的工具:
1from strands import Agent, tool
2
3@tool
4def get_weather(city: str, unit: str = "celsius") -> dict:
5 """取得指定城市的天氣資訊。
6
7 Args:
8 city: 城市名稱,例如 "Taipei"。
9 unit: 溫度單位,可選 "celsius" 或 "fahrenheit"(預設 celsius)。
10
11 Returns:
12 包含天氣資訊的字典。
13 """
14 # 實際應用中會呼叫天氣 API
15 weather_data = {
16 "city": city,
17 "temperature": 28,
18 "unit": unit,
19 "condition": "partly cloudy"
20 }
21 return {
22 "status": "success",
23 "content": [{"text": f"{city} 目前 {weather_data['temperature']}°C,{weather_data['condition']}"}]
24 }
25
26# 建立 Agent 並載入自訂工具
27agent = Agent(tools=[get_weather])
28result = agent("台北現在天氣如何?")
逐行解說:
| 行 | 說明 |
|---|---|
@tool | 裝飾器會自動從 docstring 提取工具描述、從 type hints 提取參數 schema |
city: str | 型別標註會被轉為 JSON Schema,讓模型知道該傳什麼參數 |
unit: str = "celsius" | 有預設值的參數在 schema 中標記為 optional |
Args: docstring 區塊 | docstring_parser 會解析每個參數的說明文字 |
回傳 {"status": ..., "content": [...]} | 標準工具回應格式,content 中的 text 會回傳給模型 |
@tool 裝飾器內部使用 FunctionToolMetadata 類別,透過 inspect.signature 和 docstring_parser 自動解析函式簽名,產生 Pydantic model 用於輸入驗證 (input validation),最後生成符合 LLM tool calling 規範的 ToolSpec。
4.3 多代理人協作 (Multi-Agent with Agent-as-Tool)
Strands 讓你可以把一個 Agent 當成另一個 Agent 的工具來使用:
1from strands import Agent
2from strands.models.anthropic import AnthropicModel
3
4# 建立專門做翻譯的子 Agent
5translator = Agent(
6 model=AnthropicModel(model_id="claude-sonnet-4-20250514"),
7 system_prompt="你是專業翻譯員。將使用者輸入翻譯成英文。只回傳翻譯結果,不加解釋。",
8 name="translator",
9 description="將中文翻譯成英文的翻譯代理人"
10)
11
12# 建立專門做摘要的子 Agent
13summarizer = Agent(
14 system_prompt="你是摘要專家。將輸入內容濃縮為 3 個重點。",
15 name="summarizer",
16 description="將長文濃縮為重點摘要的代理人"
17)
18
19# 建立指揮 Agent,將兩個子 Agent 作為工具
20# 當 Agent 物件被放入 tools 清單時,SDK 會自動呼叫 agent.as_tool()
21# 將其包裝為 _AgentAsTool,模型可透過 tool_use 呼叫它
22orchestrator = Agent(
23 system_prompt="你是協調者。根據使用者需求,分派工作給適當的助手。",
24 tools=[translator, summarizer] # Agent 直接作為 tool
25)
26
27# 指揮 Agent 會根據需求自動選擇呼叫哪個子 Agent
28result = orchestrator("請把以下中文摘要後翻譯成英文:台灣位於東亞...")
關鍵機制:當 Agent 實例被放入 tools 清單時,ToolRegistry.process_tools() 會偵測到它是 AgentBase 的子類別,自動呼叫 agent.as_tool() 將其包裝為 _AgentAsTool。這個包裝器會將子 Agent 的 name 和 description 轉為 ToolSpec,模型在推論時就能像呼叫普通工具一樣呼叫另一個 Agent。
4.4 使用 Hooks 與 Interventions 進行流程控制
Hooks (鉤子) 和 Interventions (介入) 是 Strands 最強大的控制機制,讓你在 Agent 執行的每個階段攔截、修改或終止流程:
1from strands import Agent, InterventionHandler
2from strands.hooks import BeforeToolCallEvent, AfterToolCallEvent
3from strands.interventions.actions import Proceed, Deny, Guide
4
5import logging
6
7# 方法 1:使用 Intervention Handler 做 Guardrail (護欄)
8class SafetyGuard(InterventionHandler):
9 """在工具執行前檢查安全性。"""
10
11 name = "safety-guard" # 每個 handler 必須有唯一名稱
12
13 def before_tool_call(self, event: BeforeToolCallEvent, **kwargs):
14 """在工具被呼叫前攔截,檢查是否允許執行。"""
15 tool_name = event.tool.tool_name
16
17 # 禁止使用某些危險工具
18 blocked_tools = ["shell_command", "file_delete"]
19 if tool_name in blocked_tools:
20 # Deny 會立即終止這個工具呼叫,回傳拒絕原因給模型
21 return Deny(reason=f"工具 {tool_name} 已被安全政策封鎖")
22
23 # Guide 會在不阻止執行的情況下,向模型注入額外指引
24 if tool_name == "web_search":
25 return Guide(instructions="搜尋時請避免存取內部網域")
26
27 # Proceed 表示允許繼續執行
28 return Proceed()
29
30# 方法 2:使用 Hook Callback 做日誌記錄
31def log_tool_usage(event: AfterToolCallEvent):
32 """在工具執行後記錄使用情況。"""
33 logging.info(
34 f"工具 {event.tool.tool_name} 執行完成,"
35 f"耗時 {event.duration_ms:.1f}ms"
36 )
37
38# 建立 Agent,同時註冊 intervention 和 hook
39agent = Agent(
40 interventions=[SafetyGuard()], # Intervention 按註冊順序評估
41 hooks=[log_tool_usage], # Hook 不影響控制流
42 tools=[get_weather]
43)
Hooks vs Interventions 的關鍵差異:
| 面向 | Hooks (鉤子) | Interventions (介入) |
|---|---|---|
| 用途 | 觀察、記錄、監控 | 控制、攔截、修改 |
| 回傳值 | 無(void) | Proceed / Deny / Guide / Transform / Confirm |
| 影響流程 | 不影響 | 可終止或重導流程 |
| 評估順序 | 註冊順序 | 註冊順序,Deny 會 short-circuit |
| 適用場景 | 日誌、指標、通知 | 授權、護欄、內容過濾 |
5. 進階功能 (Advanced Features)
5.1 Plugin 系統
Plugin (外掛) 是一種組合式的擴展機制,可以同時註冊 hooks 和 tools:
1from strands.plugins import Plugin, hook
2from strands.hooks import BeforeModelCallEvent
3from strands import tool
4
5class AuditPlugin(Plugin):
6 """審計外掛:記錄所有模型呼叫並提供查詢工具。"""
7
8 name = "audit-plugin"
9
10 def __init__(self):
11 super().__init__()
12 self.call_log = []
13
14 @hook
15 def on_model_call(self, event: BeforeModelCallEvent):
16 """用 @hook 裝飾的方法會自動被發現並註冊。"""
17 self.call_log.append({
18 "timestamp": "...",
19 "message_count": len(event.messages)
20 })
21
22 @tool
23 def query_audit_log(self, query: str) -> str:
24 """查詢審計記錄。
25
26 Args:
27 query: 查詢條件。
28 """
29 return f"共 {len(self.call_log)} 筆記錄"
30
31agent = Agent(plugins=[AuditPlugin()])
Plugin 內部使用 discover_hooks() 和 discover_tools() 掃描帶有 @hook 和 @tool 裝飾器的方法,在 Agent 初始化時自動註冊。
5.2 Structured Output (結構化輸出)
用 Pydantic BaseModel 定義期望的輸出結構:
1from pydantic import BaseModel
2from strands import Agent
3
4class MovieReview(BaseModel):
5 title: str
6 score: float
7 summary: str
8 pros: list[str]
9 cons: list[str]
10
11agent = Agent(structured_output_model=MovieReview)
12result = agent("評論電影《乘風破浪》")
13
14# result.output 是 MovieReview 型別的物件
15review = result.output
16print(f"評分:{review.score}")
17print(f"優點:{review.pros}")
SDK 內部會將 Pydantic model 轉換為一個隱式的 structured_output 工具,要求模型以 tool_use 的方式回傳符合 schema 的 JSON。如果模型第一次沒有使用此工具,SDK 會自動發送 follow-up prompt 要求格式化。
5.3 Session Management (工作階段管理)
提供跨對話的狀態持久化:
1from strands import Agent
2from strands.session import FileSessionManager
3
4# 使用檔案系統做 session 持久化
5session_mgr = FileSessionManager(session_dir="./sessions")
6
7agent = Agent(
8 session_manager=session_mgr,
9 agent_id="my-assistant"
10)
11
12# 第一次對話
13result = agent("我叫小明,請記住我的名字")
14
15# 之後的對話可以延續上下文
16# session_manager 會自動載入之前的 messages
17result = agent("我叫什麼名字?")
內建三種 Session Manager:
FileSessionManager:儲存到本地檔案系統S3SessionManager:儲存到 AWS S3RepositorySessionManager:自訂儲存後端
5.4 Memory Manager (跨工作階段記憶)
比 Session Manager 更進階的長期記憶系統:
1from strands import Agent
2from strands.memory import MemoryManager
3
4# MemoryManager 是一個 Plugin,可以搭配多種 MemoryStore
5memory = MemoryManager(
6 stores=[my_memory_store],
7 search_tool_config=True, # 自動註冊 search_memory 工具
8 add_tool_config=True, # 自動註冊 add_memory 工具
9 injection=True # 每次模型呼叫前自動注入相關記憶
10)
11
12agent = Agent(memory_manager=memory)
MemoryManager 透過 ExtractionCoordinator 自動從對話中萃取值得記憶的資訊,並在後續對話中透過 injection middleware (注入中介層) 將相關記憶加入模型的輸入上下文。
5.5 Sandbox (沙箱隔離)
在隔離環境中執行 Agent 的工具:
1from strands import Agent
2from strands.sandbox import DockerSandbox
3
4# 在 Docker 容器中執行
5sandbox = DockerSandbox(
6 container="my-agent-sandbox", # 容器名稱或 ID
7 working_dir="/workspace", # 工作目錄
8 user="agent" # 執行用戶
9)
10
11agent = Agent(sandbox=sandbox)
12# 現在所有 sandbox-aware 的工具都會在容器內執行
DockerSandbox 繼承自 PosixShellSandbox,透過 docker exec 將命令轉發到指定容器。它也會自動將 bash 和 file_editor 等 vended tools (內建工具) 註冊為沙箱版本。
5.6 A2A (Agent-to-Agent) 協定
支援跨網路的 Agent 間通訊:
1from strands.agent.a2a_agent import A2AAgent
2
3# 連接遠端 A2A Agent
4remote_agent = A2AAgent(
5 endpoint="https://my-agent.example.com",
6 timeout=300
7)
8
9# 像本地 Agent 一樣呼叫
10result = remote_agent("分析這份資料")
11
12# 也可以作為工具整合到其他 Agent
13orchestrator = Agent(tools=[remote_agent])
A2AAgent 實作了 AgentBase 介面,透過 HTTP 與遠端 Agent 通訊,支援串流回應和狀態追蹤。
5.7 Checkpointing (檢查點)
Agent 可以在迴圈的關鍵點暫停,讓外部系統決定是否繼續:
1agent = Agent(checkpointing=True)
2
3result = agent("執行多步驟分析")
4
5# 如果 stop_reason 是 "checkpoint",表示 Agent 在等待
6if result.stop_reason == "checkpoint":
7 # 檢視目前狀態,決定是否繼續
8 checkpoint = result.checkpoint
9 # 繼續執行
10 result = agent({"checkpointResume": {"checkpoint": checkpoint}})
5.8 Context Management 策略
context_manager="auto" 模式會自動組合兩個元件:
- ContextOffloader Plugin:當工具回應超過 1,500 tokens 時,自動將結果卸載 (offload) 到記憶體,只保留 750 tokens 的預覽 (preview)
- SummarizingConversationManager:當上下文使用率超過 85% 時,自動摘要壓縮 30% 的早期訊息
1agent = Agent(context_manager="auto")
另有 context_manager="agentic" 模式,會注入三個工具讓模型自行管理上下文:
summarize_context:摘要壓縮truncate_context:截斷早期訊息pin_context:釘選重要訊息
6. Agent 可呼叫性分析 (Agent Callability)
6.1 CLI 呼叫
SDK 本身不提供 CLI 入口,但 monorepo 中的 strandly/ 目錄包含開發者 CLI 工具,用於本地建置和 codegen。生態系中的 agent-builder repo 提供了完整的終端互動 Agent。
6.2 MCP 整合
Strands 原生支援 MCP (Model Context Protocol),可以同時作為 MCP client (消費工具) 和透過 mcp-server repo 作為 MCP server (提供工具):
1from strands import Agent
2from strands.tools.mcp import MCPClient
3
4# 連接 MCP Server 並使用其工具
5mcp = MCPClient("npx -y @strands-agents/mcp-server")
6agent = Agent(tools=[mcp])
6.3 API / SDK 呼叫
這是主要的使用方式。SDK 提供三種呼叫模式:
1# 1. 同步呼叫
2result = agent("hello")
3
4# 2. 異步串流
5async for event in agent.stream_async("hello"):
6 print(event)
7
8# 3. 結構化輸出
9result = agent.structured_output("hello", output_model=MyModel)
6.4 部署選項
文件站提供多種生產部署範本:
- AWS App Runner(容器化部署)
- AWS EC2(虛擬機部署)
- AWS Fargate(serverless 容器)
- 自訂 HTTP server
7. 與生態系的關係 (Ecosystem Relationships)
7.1 strands-agents 組織全貌
strands-agents GitHub organization 下有 13 個 repo,形成完整的 Agent 開發平台:
| Repo | 角色 | 與 harness-sdk 的關係 |
|---|---|---|
| harness-sdk | 核心 SDK (Python + TS) | 本體 |
| tools | 官方工具集 | Agent 的 tools= 參數直接載入 |
| sdk-typescript | TypeScript SDK (舊) | 已整合進 harness-sdk 的 strands-ts/ |
| samples | 範例程式碼 | 使用 SDK 建構的示範 Agent |
| agent-builder | 終端互動 Agent | 基於 SDK 建構的 CLI Agent |
| mcp-server | MCP Server | 為 AI 編輯器提供 Strands 文件 |
| shell | 安全 Shell | 為 Agent 提供隔離的 shell 環境 |
| evals | 評估框架 | 測試 Agent 品質的框架 |
| docs | 文件站原始碼 | 已整合進 harness-sdk 的 site/ |
| agent-sop | 自然語言工作流 | SOP 驅動的多步驟 Agent 行為 |
| devtools | 共用 CI/CD | GitHub Actions 與共用工具 |
| extension-template | 擴展模板 | 建立自訂擴展的起始模板 |
| .github | 組織設定 | 組織層級的 GitHub 設定 |
7.2 關鍵依賴關係
1harness-sdk (核心)
2 |
3 +-- tools (官方工具集,pip install strands-agents-tools)
4 | |
5 | +-- shell (安全 shell 工具的底層)
6 |
7 +-- mcp-server (讓 AI 編輯器理解 Strands)
8 |
9 +-- agent-builder (基於 SDK 的示範 Agent)
10 |
11 +-- samples (更多使用範例)
12 |
13 +-- evals (品質驗證框架)
14 |
15 +-- agent-sop (SOP 工作流引擎)
8. 優缺點分析 (Strengths & Limitations)
8.1 優點
| 面向 | 說明 |
|---|---|
| 極簡 API | 3 行程式碼即可建立功能完整的 Agent,學習曲線極低 |
| 真正的模型無關 | 12+ 種 Model Provider,且介面統一,切換時程式碼不需改動 |
| 生產等級的控制機制 | Hooks + Interventions + Middleware 三層控制,滿足企業級需求 |
| 完整的 TypeScript 支援 | 不只是 Python wrapper,TypeScript SDK 是獨立實作 |
| A2A 協定 | 跨網路 Agent 間通訊的標準化方案 |
| Plugin 系統 | 透過 @hook 和 @tool 裝飾器,擴展邏輯可組合、可重用 |
| Context 自動管理 | auto 模式自動處理 token 溢出,開發者不需手動管理 |
| Sandbox 隔離 | Docker / SSH / POSIX 三種沙箱,適合不同安全需求 |
| Memory Manager | 內建跨 session 記憶系統,支援自動萃取和注入 |
| OpenTelemetry 追蹤 | 內建 OTEL 支援,每次迴圈都有完整 trace |
8.2 缺點與限制
| 面向 | 說明 |
|---|---|
| Bedrock 偏好 | 預設 Model Provider 是 Bedrock,非 AWS 使用者需要額外設定 |
| 工具生態仍在建構中 | 官方工具數量尚不及 LangChain 等成熟框架 |
| WASM 仍為實驗性 | strands-wasm 跨語言工具執行尚未穩定 |
| 學習成本分佈不均 | 基本使用極簡,但 Hooks/Interventions/Middleware 的進階用法需要深入理解 |
| 文件尚在完善 | 部分進階功能(如 experimental 模組下的 bidirectional streaming)文件不足 |
| Checkpoint 機制有限 | 檢查點不包含完整對話狀態,需搭配 SessionManager 使用 |
| 記憶體儲存 | ContextOffloader 使用 in-memory storage,重啟後資料遺失 |
9. 實戰應用場景 (Real-world Use Cases)
9.1 場景一:企業知識問答系統
需求:建立一個能查詢企業內部文件的 AI 助手,需要權限控制和審計追蹤。
1from strands import Agent, tool, InterventionHandler
2from strands.interventions.actions import Proceed, Deny
3from strands.hooks import BeforeToolCallEvent
4from strands.plugins import Plugin, hook
5from strands.session import FileSessionManager
6from strands.models.anthropic import AnthropicModel
7
8# 1. 定義查詢工具
9@tool
10def search_knowledge_base(query: str, department: str = "all") -> dict:
11 """搜尋企業知識庫。
12
13 Args:
14 query: 搜尋關鍵字。
15 department: 部門篩選(all / engineering / hr / finance)。
16 """
17 # 實際會接 Elasticsearch / OpenSearch
18 results = do_search(query, department)
19 return {"status": "success", "content": [{"text": str(results)}]}
20
21# 2. 定義權限檢查 Intervention
22class DepartmentAuth(InterventionHandler):
23 name = "dept-auth"
24
25 def __init__(self, user_dept: str):
26 self.user_dept = user_dept
27
28 def before_tool_call(self, event: BeforeToolCallEvent, **kwargs):
29 if event.tool.tool_name == "search_knowledge_base":
30 dept = event.tool_use.get("input", {}).get("department", "all")
31 if dept != "all" and dept != self.user_dept:
32 return Deny(reason=f"無權限存取 {dept} 部門的資料")
33 return Proceed()
34
35# 3. 組裝
36agent = Agent(
37 model=AnthropicModel(model_id="claude-sonnet-4-20250514"),
38 tools=[search_knowledge_base],
39 interventions=[DepartmentAuth(user_dept="engineering")],
40 session_manager=FileSessionManager(session_dir="./sessions"),
41 system_prompt="你是企業知識助手。只根據搜尋結果回答,不要編造。"
42)
9.2 場景二:多 Agent 協作的研究管線
需求:建立一個研究管線,包含文獻搜尋、資料分析、報告撰寫三個專精 Agent。
1from strands import Agent
2from strands.models.anthropic import AnthropicModel
3
4model = AnthropicModel(model_id="claude-sonnet-4-20250514")
5
6# 文獻搜尋 Agent
7literature_agent = Agent(
8 model=model,
9 name="literature_searcher",
10 description="搜尋學術文獻並提供摘要。輸入研究主題,輸出相關文獻清單與摘要。",
11 system_prompt="你是學術文獻搜尋專家。搜尋相關文獻並提供結構化摘要。",
12 tools=[pubmed_search, arxiv_search] # 假設已定義
13)
14
15# 資料分析 Agent
16analysis_agent = Agent(
17 model=model,
18 name="data_analyst",
19 description="分析研究數據並產生統計結果。輸入資料集路徑,輸出分析報告。",
20 system_prompt="你是統計分析專家。使用適當的統計方法分析資料。",
21 tools=[python_executor, plot_generator] # 假設已定義
22)
23
24# 報告撰寫 Agent
25writer_agent = Agent(
26 model=model,
27 name="report_writer",
28 description="將研究成果整理成結構化報告。輸入分析結果,輸出完整報告。",
29 system_prompt="你是科學寫作專家。將研究結果整理成 IMRAD 格式的報告。"
30)
31
32# 指揮 Agent
33research_pipeline = Agent(
34 model=model,
35 system_prompt="""你是研究計畫主持人。根據使用者的研究主題:
36 1. 先用 literature_searcher 搜尋相關文獻
37 2. 用 data_analyst 分析相關數據
38 3. 用 report_writer 撰寫最終報告
39 按順序分派工作,確保每步的輸出能銜接下一步的輸入。""",
40 tools=[literature_agent, analysis_agent, writer_agent]
41)
42
43result = research_pipeline("研究 CRISPR 在腎細胞癌中的應用")
9.3 場景三:可監控的自主部署 Agent
需求:建立一個能自動部署程式碼的 Agent,但需要人類確認關鍵操作。
1from strands import Agent, InterventionHandler
2from strands.interventions.actions import Proceed, Confirm, Deny
3from strands.hooks import BeforeToolCallEvent
4from strands.sandbox import DockerSandbox
5
6class DeploymentGuard(InterventionHandler):
7 """部署護欄:關鍵操作需要人類確認。"""
8 name = "deploy-guard"
9
10 def before_tool_call(self, event: BeforeToolCallEvent, **kwargs):
11 tool_name = event.tool.tool_name
12
13 # 生產環境部署需要人類確認
14 if tool_name == "deploy_to_production":
15 return Confirm(
16 message="即將部署到生產環境,請確認是否繼續",
17 timeout=300 # 5 分鐘超時
18 )
19
20 # 刪除操作直接封鎖
21 if tool_name in ["drop_database", "delete_cluster"]:
22 return Deny(reason="破壞性操作已被安全政策禁止")
23
24 return Proceed()
25
26# 使用 Docker 沙箱隔離部署操作
27deploy_agent = Agent(
28 tools=[run_tests, build_image, deploy_to_staging, deploy_to_production],
29 interventions=[DeploymentGuard()],
30 sandbox=DockerSandbox(container="deploy-sandbox"),
31 system_prompt="你是 DevOps 助手。執行 CI/CD 管線:測試 → 建置 → staging → production。",
32 checkpointing=True # 啟用檢查點,允許外部系統控制流程
33)
附錄:快速參考
常用 Import
1from strands import Agent, tool, InterventionHandler, Plugin, Sandbox
2from strands.models.anthropic import AnthropicModel
3from strands.models.openai import OpenAIModel
4from strands.models.ollama import OllamaModel
5from strands.models.bedrock import BedrockModel
6from strands.hooks import (
7 BeforeInvocationEvent, AfterInvocationEvent,
8 BeforeModelCallEvent, AfterModelCallEvent,
9 BeforeToolCallEvent, AfterToolCallEvent,
10 MessageAddedEvent, AgentInitializedEvent
11)
12from strands.interventions.actions import Proceed, Deny, Guide, Transform, Confirm
13from strands.session import FileSessionManager, S3SessionManager
14from strands.memory import MemoryManager
15from strands.sandbox import DockerSandbox, PosixShellSandbox
16from strands.plugins import Plugin, hook
Event Loop 生命週期事件順序
1AgentInitializedEvent # Agent 建構完成
2 |
3BeforeInvocationEvent # 開始處理請求
4 |
5 +-- BeforeModelCallEvent # 呼叫模型前(每次迴圈)
6 | |
7 | AfterModelCallEvent # 模型回應後
8 | |
9 | BeforeToolCallEvent # 工具執行前(如需要)
10 | |
11 | AfterToolCallEvent # 工具執行後
12 | |
13 | MessageAddedEvent # 訊息加入對話歷史
14 | |
15 +-- (迴圈直到 end_turn)
16 |
17AfterInvocationEvent # 請求處理完成
相關連結
- 官方文件:https://strandsagents.com/
- Quick Start:https://strandsagents.com/docs/user-guide/quickstart/overview/
- Python API Reference:https://strandsagents.com/docs/api/python/strands.agent.agent/
- TypeScript API Reference:https://strandsagents.com/docs/api/typescript/
- 範例程式碼:https://github.com/strands-agents/samples
- 官方工具集:https://github.com/strands-agents/tools
- Discord 社群:https://discord.com/invite/strands
Comments