Strands harness は、AWSが公開する Strands Agents に入っている「組み上がった状態で渡されるエージェントハーネス」だ。公式ドキュメントの説明はこう書かれている——「ツール・文脈管理・セッション・メモリ・フックのベンチマーク済み既定値と、調整済みのシステムプロンプトが付いてくるので、ハーネスを一つずつ組み立てる代わりに最適化されたエージェントから始められる」。使い方は create_harness() の1行。ただし「完成品」を受け取るということは、自分が選んでいない既定値を全部引き受けるということでもある。そこで strands-harness 0.1.2 を実際に導入し、create_harness() が何を入れて何トークン消費するのかを1つずつ数えた。
- ・`pip install strands-harness` して `create_harness()` を呼ぶだけで、ツール入りのエージェントが返る
- ・既定の初期コストは約3,513トークン(システムプロンプト416+ツール12本3,097)
- ・システムプロンプトの実体は1,665字の振る舞い契約。Acting・Tools・Safety・Context management の4節
- ・既定モデルは `bedrock/global.anthropic.claude-opus-5`。セッション・メモリ・スキル・キャッシュはすべて既定でON
- ・一番トークンを食うツールは実作業用ではなく、文脈を退避・復元する `retrieve_offloaded_content`(654)
- ・`web_search` は既定モデルにネイティブ検索が無いため警告つきで外れる。使うなら Exa(第三者)を明示する
エージェント基盤そのものの選び方はAIエージェントフレームワーク比較2026|LangGraph・CrewAI・Dify等9種をStar数・実コードで検証にまとめてある。本記事はその一歩内側、ハーネスの既定値を数える話だ。
Strands harnessとは:組み立てずに受け取るハーネス
Strands Agents は AWS が公開するエージェント開発SDKで、GitHubのAboutは “Build an agent harness and control it end-to-end”——ハーネスを組んで端から端まで制御する、と名乗っている。star 8.5k、fork 1.3k、Apache-2.0。リポジトリは strands-py strands-ts strands-cli strands-mcp に加えて harness-py と harness-ts を持つモノレポで、harness は独立したパッケージとして切り出されている。
「ハーネス」という言葉はこの1年で定着したが、指すものは実装によってまちまちだ。Strands の定義は harness-py/src/strands_harness/ を見れば分かる。21本のPythonファイルがあり、内訳はこうなっている。
| 領域 | ファイル |
|---|---|
| 中核 | agent.py(30KB)・config.py(24KB)・options.py・defaults.py |
| 振る舞い | prompt.py(システムプロンプト)・interventions.py(介入) |
| 状態 | memory.py・セッション・スキル |
| ツール | tools/ に file_tools・web_fetch・web_search・subagent・programmatic_tool_caller |
| プラグイン | plugins/ に todos・environment |
| 計測 | telemetry.py |
ファイル・Web・サブエージェント・TODO——コーディングエージェントが持っている道具立てがそのまま部品として並んでいる。手で組むならこれを全部自分で選ぶことになる。Strands harness はそこを既定値で埋めて渡す、という立場だ。
導入は軽い。空の仮想環境で測った。
python3 -m venv /tmp/sh-venv
/tmp/sh-venv/bin/pip install strands-harness
du -sm /tmp/sh-venv # 168
/tmp/sh-venv/bin/pip list --format=freeze | wc -l # 61
168MB・61パッケージ。機械学習の重量級ライブラリは入らず、依存の中心は strands-agents[otel](1.56.0以上)と pydantic 系だ。同じ手順で測った他のエージェント基盤が数GBになることを考えると、ハーネスとしてはかなり軽い部類になる。
create_harness() が入れるものを数える
引数を1つも渡さずに構築して、中身を取り出した。
import strands_harness as H
agent = H.create_harness()
cfg = agent.tool_registry.get_all_tools_config()
print(len(cfg), sorted(cfg))
# 12 ['edit', 'programmatic_tool_caller', 'read', 'retrieve_context',
# 'retrieve_offloaded_content', 'search_memory', 'shell',
# 'strands_manage_background_task', 'subagent', 'todo_write',
# 'web_fetch', 'write']
print(len(agent.system_prompt)) # 1665
ツールは12本。BUILTIN_TOOL_NAMES に並ぶ既定の組み込みは shell read write edit web_fetch web_search programmatic_tool_caller subagent の8本だが、実際に登録されたものと突き合わせると違いが2つある。
ひとつは web_search が落ちていること。構築時にこう警告が出た——「モデル bedrock/global.anthropic.claude-opus-5 にはネイティブのweb searchが無い。Exa(第三者)経由で検索するなら builtin_tools={'web_search': 'exa'} を渡すか、web_search を外せ」。既定のままでは検索できないエージェントが出来上がるので、ここは最初に気づいておきたい。
もうひとつは、組み込み以外に5本が足されていること。todo_write(todosプラグイン)、search_memory(メモリ)、retrieve_context と retrieve_offloaded_content(文脈管理)、strands_manage_background_task。既定でONになっている土台が、それぞれツールを持ち込む構造になっている。
DEFAULT_HARNESS_AGENT_CONFIG をそのまま読むと、caching: true・session: true・skills: true・memory: true・contextManager: "auto"・builtinPlugins: ["todos", "environment"]。defaults.py 側には DEFAULT_SESSION_DIR = "./.agent/sessions"、DEFAULT_SKILLS_DIR = "./.agent/skills"、DEFAULT_MEMORY_DIR = "./.agent/memory"、DEFAULT_SUBAGENT_MAX_DEPTH = 2 が並ぶ。カレントディレクトリの直下に .agent/ を作って状態を書くので、リポジトリに入れるなら .gitignore を先に用意することになる。
既定モデルが bedrock/global.anthropic.claude-opus-5(Bedrockのグローバル推論プロファイル表記)である点も、動かす前に確認しておきたい。AWSの認証情報が無い環境では構築はできても実行はできない。
初期コストの内訳:416+3,097=3,513トークン
ハーネスを受け取るということは、毎回の会話の先頭にその分の文脈が載るということだ。構築したエージェントからシステムプロンプトとツール定義を取り出し、同じ物差しで数えた。
| 対象 | サイズ | 概算トークン |
|---|---|---|
| システムプロンプト(HARNESS_CONTRACT) | 1,665字 | 416 |
| ツール12本のスキーマ合計 | 12,401バイト | 3,097 |
| 合計(初期状態の常駐分) | — | 約3,513 |
トークナイザは tools/token_audit.py の heuristic 近似(CJK 1字=1・ASCII 4字=1)で、tiktoken の cl100k_base は当環境からBPE辞書を取得できないため使っていない。
per-toolの数字は、構築したエージェントからそのまま取り出せる。
import json
cfg = agent.tool_registry.get_all_tools_config()
for name, spec in cfg.items():
print(name, len(json.dumps(spec, separators=(',', ':'))))
# retrieve_offloaded_content 2616 / subagent 1618 / programmatic_tool_caller 1575
# retrieve_context 1347 / todo_write 1156 / web_fetch 784 / read 639 ...
内訳を見ると、この設計の性格がよく出ている。最も重いのは retrieve_offloaded_content(654トークン)——文脈から退避した内容を取り出すためのツールだ。retrieve_context(336)と合わせると、文脈管理だけで990トークン。対して実作業の shell は128、edit は106、write は89しかない。
つまり「長い会話でも破綻しないようにする仕組み」が、実際に手を動かすツールより高くついている。文脈が溢れたときの退避と復元を自動でやるなら当然のコストだが、短いタスクしか回さないなら払い損になる。contextManager は既定 auto なので、用途によっては切る判断もありうる。
比較の目安として、当サイトで同じ物差しで測ったMCPサーバーを並べると、39ツールのエージェント記憶基盤が約16,603トークン、31ツールのナレッジ基盤が約1,535トークンだった。Strands harness の3,513トークンは、12本という本数のわりに中位という位置になる。ツール1本あたりの説明が厚い、という読み方もできる。記憶をMCPで足す構成についてはHindsightとは|学習するAIエージェント記憶OSSをMCP 39ツールと6.8GBの実測で解説で測った数字が参考になる。
ツール定義の厚みは、そのままエージェントの初動の速さに効く。12本なら「どれを使うか」の判断は軽いが、3,513トークンは毎リクエストの先頭に載り続ける。長く走らせるエージェントほど、この固定費と文脈管理の恩恵が釣り合うかを見ておきたい。逆に1往復で終わる用途なら、contextManager と memory を切って最小構成にするほうが素直だ。既定値が全部読める形で置いてあるので、その判断は導入前にできる。
検証環境:Linux 6.18.44/Python 3.11/2026-09-29。PyPI の strands-harness 0.1.2(2026-09-22公開)を新規venvへ導入し、create_harness() を引数なしで構築して tool_registry.get_all_tools_config() と system_prompt を取り出した。ソースは strands-agents/sdk-python の main 535f2ec(2026-09-28)を git clone --depth 1。トークン量は tools/token_audit.py の heuristic 近似トークナイザで計測。未検証:エージェントを一度も実行していない。AWSの認証情報を持たないため、実際の推論、ツールの動作、文脈退避の挙動、メモリやスキルの読み込み、サブエージェントの分岐はいずれも未確認。公式ドキュメントが言う「ベンチマーク済みの既定値」のベンチマーク自体も追試していない。ドキュメントサイト(strandsagents.com)は当環境から到達できず、リポジトリ内の site/src/content/docs/user-guide/harness/ のソースを一次情報として使った。star 8.5k・fork 1.3k はリポジトリページの表示値。
416トークンの振る舞い契約に何が書いてあるか
このハーネスで一番読む価値があるのは、prompt.py に置かれた HARNESS_CONTRACT だと思う。ファイルの docstring はこう説明している——「モデル中立な振る舞いの契約であり、能力のあるモデルから規律あるエージェント的振る舞いを引き出す。行動できる材料が揃ったら動く、変える前に調べる、不可逆な操作の前に確認する、完了と言う前に検証する。アイデンティティやドメインは主張しない。それは利用者の instructions に属する」。
実物は19行・4節しかない。# Acting(行動)、# Tools(道具)、# Safety(安全)、# Context management(文脈管理)。中身を要約すると、行動の節は「行動できる材料が揃ったら動け。自分で検証できる手順の確認を人に求めるな。既に確定した事実を再導出するな」「何かを変える前に周辺の文脈と作法を理解しろ」「もっともらしく見える段階ではなく、検証できた段階で完了と呼べ。検証できないならそう言え」。
道具の節には実務的な指示が並ぶ。「汎用のツールで間に合わせるより、その仕事専用のツールを使え」「独立したツール呼び出しは1ターンでまとめて出し、直列ではなく並列に走らせろ」「拒否・失敗したツール呼び出しは情報だ。そのまま再試行せず approach を変えろ」。安全の節は「不可逆、またはローカル環境の外に届く操作は、明示的に進めと言われていない限り先に確認を取れ。ある文脈での承認は次には引き継がれない」「結果は正直に報告しろ。失敗したなら出力とともにそう言い、手順を飛ばしたならそう言い、終わって検証できたなら曖昧にせずそう言え」。
416トークンでここまで書けるのか、という密度だ。エージェントの振る舞いを長大なプロンプトで縛るのではなく、判断の分かれ目になる場面だけを名指ししている。ハーネスを自分で組む人にとっては、このファイル単体が参照する価値のある成果物だと思う。ドキュメントが prompt.py を「first-class artifact(一級の成果物)として提供する」と書いているのも納得がいく。
416トークン・4節"] A --> C["組み込みツール8本の宣言"] A --> D["既定でONの土台"] C --> E{"モデルが対応しているか"} E -- "非対応" --> F["web_search は警告して除外"] E -- "対応" --> G["登録"] D --> H["todos → todo_write"] D --> I["memory → search_memory"] D --> J["context manager → retrieve_context
retrieve_offloaded_content"] G --> K["ツール12本
3,097トークン"] H --> K I --> K J --> K B --> L["初期コスト 約3,513トークン"] K --> L
エージェントに渡す道具の総量をどう抑えるかという論点は、同日に測ったCloudflare cf CLIとは|2,936コマンドをエージェントに渡さない設計を実測で確かめると正反対のアプローチで面白い。あちらは2,936コマンドを検索窓口1つに畳んだ。こちらは12本に絞って全部見せる。規模が違えば最適な渡し方も違う、という当たり前の結論に落ち着くが、どちらも「何トークン払うか」で判断している点は同じだ。
導入前に押さえる点
・まだ0.1.2:PyPIの公開は4リリース(0.0.0・0.1.0・0.1.1 が2026-09-21、0.1.2 が2026-09-22)。requires_python は3.10以上、ライセンスは Apache-2.0
・既定モデルはBedrock前提:bedrock/global.anthropic.claude-opus-5。別のモデルを使うなら明示的に渡す必要があり、その場合は web_search の扱いも変わる
・.agent/ がカレントに作られる:セッション・スキル・メモリの保存先が既定でプロジェクト直下。リポジトリに混ぜるなら .gitignore を先に
・TypeScript版も同格:harness-ts と @strands-agents/harness が対で用意されていて、ドキュメントもPython/TypeScriptのタブ併記になっている。片方だけの機能、という作りではない
・telemetry.py がある:ハーネス自体に計測の口が用意されている。既定の送信有無までは本記事では確認していない
・「ベンチマーク済み既定値」は未追試:ドキュメントの表現であり、当サイトでその妥当性を検証したわけではない
総括。 Strands harness の価値は「1行で動く」ことより、既定値が全部読める形で置いてあることにあると思う。defaults.py を開けばモデルもディレクトリも深さ上限も分かるし、prompt.py を開けば振る舞いの契約が19行で読める。ツールの本数と1本あたりのトークンも構築すれば数えられる——実際、この記事の数字は全部そうやって出した。
完成品を使うか自分で組むかは、結局「既定値に納得できるか」で決まる。3,513トークンのうち約1,000が文脈管理に消えていること、web_search が既定では落ちること、状態がカレント直下に書かれること——このあたりを知ったうえで受け取るなら、組み立ての手間を省く選択は十分に合理的だ。知らずに受け取ると、後から「なぜ検索しないのか」で時間を溶かすことになる。
参照ソース
・strands-agents/sdk-python(公式リポジトリ) — harness-py/src/strands_harness/・site/src/content/docs/user-guide/harness/・LICENSE を 2026-09-29 に確認(main の 535f2ec)
・strands-harness(PyPI JSON API) — 実際に導入した 0.1.2 の配布メタデータ
・Strands Agents 公式ドキュメント — 今回の出発点(当記事の環境からは到達できず、リポジトリ内のソースを参照した)