ChainWeaver について
ChainWeaverは、レビュー済みの反復的なエージェントツール経路を決定論的なフローにするPythonツールキットです。各ステップ間でLLMを呼び出さずに実行でき、ガバナンスとドリフト検出にも対応します。
主な機能
- 01ツール入出力の型・スキーマ検証
- 02決定論的な複数ステップ実行
- 03YAMLで保存できるフロー定義
- 04構造化された実行トレース
- 05スキーマドリフト検出
- 06承認境界の維持
活用シーン
- 01中間LLM呼び出しなしでレビュー済みのツール列を実行
- 02フローの各ステップでデータを検証
- 03構造化トレースによるフロー実行の監査
MCP 対応
オプションの `mcp` インストール拡張に言及がありますが、MCP上の動作はREADMEに記載されていません。
設定
ローカルサーバーの設定はどのクライアントでも共通です。コピーしてクライアントの MCP 設定ファイルに貼り付けてください。
ツール
ローカルサーバーのツールはマシン上で起動して初めて取得できます。メンテナーはまだツール一覧を提供していません。
詳細
ChainWeaver
エージェントが推論する必要のなくなった箇所を見つけます。根拠を確認します。承認された経路を、ガバナンスの効いた決定論的な機能に変換します。
検証中の製品仮説 — 観察 → 証明 → レビュー → コンパイル。 ChainWeaver は、繰り返されるツールの動作を調査し、候補を提示し、レビュー済みの決定論的な経路を型付きコントラクトで実行できます。決定論的な実行だけでは、競争優位にはなりません。ワークフローがすでに明確であれば、通常の Python 関数、LangGraph ノード、またはプロバイダー標準のツールのほうがシンプルな場合があります。検証中の仮説は、トレースから得られる根拠、有効な却下、ガバナンスに基づく昇格、セキュリティ境界の維持、ドリフトの検出によって、ChainWeaver を採用する価値が生まれるというものです。製品の検証と採用ゲートおよび#553をご覧ください。
**推論の境界は取り除いても、セキュリティ境界は決して取り除かないでください。**複数のツール呼び出しを一つの機能にコンパイルしても、権限を暗黙のうちに集約したり、子要素に必要な承認要件をなくしたりしてはなりません。この不変条件は#554で明示的に追跡されています。
**決定論的なツール経路のガバナンス。**各ステップの型付き I/O、ファイルにシリアライズ可能なフロー、スキーマドリフトの検出、決定論性の証明、プロパティファジング、構造化された監査トレースによって、決定論的な昇格に値すると実証された経路のための、規律ある実行基盤を提供します。
ベンチマークが示すのは実行エンジンについての根拠であり、プロダクトマーケットフィットの証明ではありません。 リポジトリのベンチマークレポートは再現可能です。
python benchmarks/report.pyを実行すれば、ご自身で再生成できます。このレポートは、合成比較において決定論的なコアがモデルを介した遷移を回避することを示しています。ただし、繰り返されるすべての経路をコンパイルすべきであることや、ChainWeaver が単純な Python 実装より優れていることを証明するものではありません。独立した検証プログラムでは、この手動のベースラインを明示的に求めています。
from chainweaver import Tool, Flow, FlowStep, FlowRegistry, FlowExecutor
# (NumberInput, ValueOutput, double_fn defined in full example below)
# 1. Wrap any function as a schema-validated Tool
double = Tool(name="double", description="Doubles a number.",
input_schema=NumberInput, output_schema=ValueOutput, fn=double_fn)
# 2. Wire tools into a Flow
flow = Flow(name="calc", description="Double a number.",
steps=[FlowStep(tool_name="double", input_mapping={"number": "number"})])
# 3. Register and execute — zero LLM calls
registry = FlowRegistry()
registry.register_flow(flow)
executor = FlowExecutor(registry=registry)
executor.register_tool(double)
result = executor.execute_flow("calc", {"number": 5})
# result.final_output → {"number": 5, "value": 10}
以下の完全な例をご覧になるか、
python examples/simple_linear_flow.pyを実行してください。
インストール · ChainWeaver を選ぶ理由 · 対象となるユーザー · 製品の検証 · クイックスタート · アーキテクチャ · ドキュメントサイト · ロードマップ
30秒で確認
決定論的なエグゼキューターは、シンプルな問題を解決します。中間の推論が不要だと示された経路では、実行のたびに同じ処理手順をモデルに再判断させるのをやめます。
Before — モデルを介した経路:
turn 1 ─► LLM("plan") ─► search(query) ─► 12 results
turn 2 ─► LLM("next?") ─► extract(results) ─► 8 facts
turn 3 ─► LLM("next?") ─► validate(facts) ─► 7 facts
turn 4 ─► LLM("next?") ─► format(facts) ─► answer
レビュー後 — 承認された経路は決定論的に実行できます:
turn 1 ─► LLM("plan") ─► search_summarize_flow(query)
└─ search ─► extract ─► validate ─► format
エージェントは、どの機能を呼び出すかを引き続き判断します。その機能内の決定論的なステップは、厳格な Pydantic 検証を通じて、LLM を介さずに実行されます。
より難しいプロダクト上の問いは、この図の前にあります。この経路はそもそもコンパイルすべきでしょうか?有用な ChainWeaver 分析には、候補が繰り返し発生し、構造的に安全である理由を示すと同時に、意味的な判断、副作用、認可、承認の境界が依然として重要な経路を却下する能力が必要です。この主張は現在、#553 の独立したトレースで検証中です。
コピー&ペーストで実行できるエグゼキューターの経路:
pip install 'chainweaver[yaml]'
python examples/simple_linear_flow.py
以下の要約は、スクリプトが生成する実際の ExecutionResult を簡潔にまとめたものです。
flow=double_add_format success=True
final_output={'number': 5, 'value': 20, 'result': 'Final value: 20'}
step 0 double {'value': 10}
step 1 add_ten {'value': 20}
step 2 format_result {'result': 'Final value: 20'}
ChainWeaver を選ぶ理由
Python 関数を書くだけではだめですか?
多くの場合、それが適切です。
ワークフローが固定されているとチームがすでに把握しているなら、通常の関数や、既存のフレームワークのワークフロー用プリミティブが、たいてい最も複雑さの少ない選択肢です。ライフサイクルに意味のある価値がある場合に限り、ChainWeaver を新たな依存関係として加える価値があります。たとえば、次のような場合です。
- 実際のトレースから、わかりにくい繰り返し発生するモデル媒介の経路を発見する。
- 繰り返し発生すること、データフローとの互換性、反例を示す証拠を提示する。
- 意味的な判断が依然として必要な、魅力的に見える経路を却下する。
- 昇格時に承認と認可の制約を維持する。
- 再現可能なレビュー用証拠とアーティファクトの識別情報を生成する。
- 昇格後のスキーマ/安全性/ポリシーのドリフトを検出する。
- モデル呼び出しが少ないほど自動的に正確性が高まるかのように装うことなく、承認された機能をエクスポートまたは実行する。
これらの利点が実際のチームにとって十分に大きいかどうかは、README における前提ではなく、反証可能なプロダクト仮説です。docs/product-validation.md を参照してください。
LLM を活用したエージェントがツールを連携させる場合(fetch_data → transform → store など)、よくあるパターンは、次に何をするかモデルが判断できるよう、ステップ間に LLM 呼び出しを挿入することです。完全に決定論的であると実証され、レビュー済みの経路では、こうした中間呼び出しは有用な判断を加えることなく、レイテンシ、コスト、ばらつきを増やす可能性があります。
ChainWeaver のエグゼキューターは、承認済みの決定論的な経路を、ステップ間で LLM を介さずに実行できます。
User request
│
▼
FlowExecutor ──► Tool A ──► Tool B ──► Tool C
│
▼
Response
| 基準 | モデルを介した経路 | ChainWeaver の決定論的な経路 |
|---|---|---|
| 決定論的なステップ間の LLM 呼び出し | 1回以上の可能性あり | 0回 |
| 再現性 | モデルの判断に依存 | 決定論的な経路 |
| スキーマ検証 | フレームワーク/アプリケーションに依存 | Pydantic による強制 |
| 可観測性 | フレームワーク/アプリケーションに依存 | 構造化されたステップログ |
| 再利用性 | アプリケーションに依存 | 登録済みのバージョン管理されたフロー |
LangChain/LangGraph/Prefect/Dagster/Temporal との違いは何ですか?
これらのフレームワークでも、決定論的なコードを実行できます。他の場所では決定論的な実行が不可能だからという理由で、ChainWeaver を選ぶべきではありません。現在のプロダクト仮説は、より対象を絞っています。観測されたエージェント/ツールの動作を出発点に、どの領域で推論が不要になったかを明らかにし、証拠と却下理由をレビュー可能にしたうえで、承認済みの経路をガバナンスの効いた決定論的な機能へ昇格させます。
実行基盤は意図的に小さく保たれ、ステップ間で LLM を使用しません。ただし、このプロジェクトでは、単に別のワークフローランタイムが存在することではなく、証拠/ガバナンスのライフサイクルにユーザーが価値を見いだすかどうかを検証しています。
詳細なバージョン管理済みの比較については docs/comparisons.md を、製品の位置付けを反証できる基準については docs/product-validation.md を参照してください。
これは自分に合っていますか?
ChainWeaver は、特定の種類の問題に対応するために構築されています。 適合するケース/しないケースの詳細ページで 詳しく説明しています。概要は次のとおりです。
次の場合は ChainWeaver をお使いください
- 実際のエージェント/ツールのトレースがあり、処理経路の一部が有用なモデルの判断ではなく、繰り返される定型処理ではないかと考えている。
- すでに把握しているワークフローの実行環境だけでなく、どの処理経路を決定的な実行に移すべきかについて、根拠とレビューを求めている。
- 処理経路を決定的な実行に移した後、決定性、厳密なスキーマ、監査可能性、ドリフト検出が重要になる。
- マクロツールの呼び出しを子処理への包括的な認可として扱わず、セキュリティと承認の境界を明確に保つ準備ができている。
次の場合は ChainWeaver を使わないでください
- すでにワークフローが把握できており、通常の Python 関数や既存のフレームワークで十分明確に表現できる。
- 次のステップを選ぶために、すべてのステップで自由形式の推論が必要になる(エージェントフレームワークをお使いください:LangGraph、OpenAI/Anthropic SDK のツール使用ループ)。
- 時間をまたいでスケジュール実行する、または永続化するジョブ向けの汎用ワークフローエンジンが必要になる(Prefect、Dagster、Temporal をお使いください)。
- 実行エンジンが LLM を呼び出すことを想定している。ChainWeaver は意図的に LLM を呼び出しません。
- コンパイル中に、副作用のある処理経路の認可/承認のセマンティクスを維持できない。
プロダクトの基本方針、検証プロトコル、撤退/方向転換の基準は docs/product-validation.mdで公開されています。
決定的実行の設計における正しさの根拠については、 docs/data-integrity.mdをご覧ください。
Weaver Stack の一部
ChainWeaver は、
Weaver Stackの決定的な複数ステップのツール実行レイヤーです。これは、weaver-spec の SelectableItem ルーティング契約を共有する、小規模で組み合わせ可能な SDK 群です。リクエストの処理経路では、ルーターが呼び出す機能を選択し、ChainWeaver がその背後で決定的なツール処理経路を実行し、後続レイヤーが呼び出しを制御して保護します。
flowchart LR
req([Request]) --> ctx[contextweaver<br/>context assembly]
ctx --> cw[<b>ChainWeaver</b><br/>deterministic flow execution]
cw --> ak[agent-kernel<br/>capability gating]
ak --> af[agentfence<br/>runtime guardrails]
subgraph adjacent [Adjacent · use any subset]
vg[vibeguard]
lw[lessonweaver]
se[skdr-eval]
end
単独でも組み合わせても使えます。 各レイヤーは単独で機能します。ChainWeaver の基本インストールには兄弟プロジェクトへの必須の依存関係がなく、単独で完全に動作します。実際の相互運用は chainweaver[weaver-stack] エクストラを通じて行われ、公開済みの weaver-contracts パッケージにバージョンが固定されます。ChainWeaver はその SelectableItem/RoutingDecision/CapabilityToken 型を直接使用するため、ルーターからルーティング判断を resolve_flow_from_routing_decision() にそのまま渡して、決定的に実行できます。実行可能な
Weaver Stack のゴールデンパスをご覧ください(issue #234)。
| レイヤー | 担当する内容 | 兄弟プロジェクト |
|---|---|---|
| ルーティング/機能選択 | 「このリクエストを処理する名前付きオペレーションはどれか?」 | weaver-spec(#91 — SelectableItem 契約) |
| コンテキスト構築 | 「どの事実とツールの説明をプロンプトに含めるか?」 | contextweaver(#106) |
| エージェントカーネル | モデルを介したツール使用ループそのもの | agent-kernel(#89) |
| 決定的なフロー実行 | 「LLM をステップ間に挟まず、厳密なスキーマで、このツールの一連の処理をそのまま実行する」 | ChainWeaver — このリポジトリ |
| 学びと評価 | トレースをレビュー済みの運用ガイダンスに変換する(ChainWeaver がこれにどう役立つか) | lessonweaver(#210) |
ChainWeaver はエージェントフレームワークを置き換えるものではありません。エージェントフレームワークから呼び出すことを想定しています。標準的な統合パターンについては、LangGraph のレシピ(issue #205)とOpenAI Agents SDK のレシピ(issue #206)をご覧ください。
ホスト側に求められること(呼び出すタイミング、トレースの保存方法、副作用のあるツール、MCP との同等性)については、 ランタイムの責務をご覧ください。
インストール
pip install chainweaver # base install — no extras
pip install 'chainweaver[yaml]' # most common — needed for .flow.yaml files
pip install 'chainweaver[yaml,otel,mcp]' # combine extras with commas
基本のインストールで取得されるランタイム依存関係は 5 つ(deepdiff、
packaging、pydantic、tenacity、typer)のみで、LLM
SDK の推移的依存関係は固定されません。実際に使用するインテグレーションに合わせて、追加機能を選択してください。
| 追加機能 | 使用する場面 | 追加でインストールされるもの |
|---|---|---|
chainweaver[yaml] | .flow.yaml フローファイルの読み書き(CLI の run、validate、check、doctor コマンドで必要です) | pyyaml |
chainweaver[otel] | すべてのフロー実行で OpenTelemetry スパンを出力する | opentelemetry-api |
chainweaver[mcp] | chainweaver.mcp アダプターを介して MCP 経由でフローを公開する | mcp |
chainweaver[contrib] | 厳選された標準ツールライブラリをインポートする(標準ツールライブラリを参照) | (現在、追加の依存関係はありません) |
chainweaver[langchain] | ChainWeaver と LangChain の BaseTool 間の双方向アダプター | langchain-core |
chainweaver[llamaindex] | ChainWeaver と LlamaIndex の FunctionTool 間の双方向アダプター | llama-index-core |
chainweaver[test] | 独自のフロー向けの Hypothesis ベースのプロパティテスト | hypothesis、hypothesis-jsonschema |
chainweaver[docs] | mkdocs でドキュメントサイトをローカルにビルドする | mkdocs、mkdocs-material、mkdocstrings |
chainweaver[weaver-stack] | Weaver Stack との実際の相互運用 — 共有ルーティング/ケイパビリティ契約を利用する(weaver-spec #91、contextweaver #106、agent-kernel #89、#233) | weaver-contracts |
chainweaver[integrations] | 上記のインテグレーション向け追加機能をすべて一度にインストールする — コンポジション CI で使用 | 上記のインテグレーション関連行の統合 |
メンテナー向けツール(pytest、ruff、mypy、nbmake など)は、公開されている
追加機能ではありません。PEP 735 の依存関係グループに含まれており、
pip install -e ".[integrations]" --group dev でインストールします(#550)。[dev] 追加機能は
廃止されました。
パッケージメタデータ(pyproject.toml)には、
ドキュメント、
ソース、
変更履歴、
課題トラッカーへの URL が登録されているため、pip show chainweaver と PyPI のサイドバーから、ユーザーを適切な場所へ案内できます。
クイックスタート
ツールを定義し、フローを構築して実行する
from pydantic import BaseModel
from chainweaver import Tool, Flow, FlowStep, FlowRegistry, FlowExecutor
# --- 1. Declare schemas ---
class NumberInput(BaseModel):
number: int
class ValueOutput(BaseModel):
value: int
class ValueInput(BaseModel):
value: int
class FormattedOutput(BaseModel):
result: str
# --- 2. Implement tool functions ---
def double_fn(inp: NumberInput) -> dict:
return {"value": inp.number * 2}
def add_ten_fn(inp: ValueInput) -> dict:
return {"value": inp.value + 10}
def format_result_fn(inp: ValueInput) -> dict:
return {"result": f"Final value: {inp.value}"}
# --- 3. Wrap as Tool objects ---
double_tool = Tool(
name="double",
description="Takes a number and returns its double.",
input_schema=NumberInput,
output_schema=ValueOutput,
fn=double_fn,
)
add_ten_tool = Tool(
name="add_ten",
description="Takes a value and returns value + 10.",
input_schema=ValueInput,
output_schema=ValueOutput,
fn=add_ten_fn,
)
format_tool = Tool(
name="format_result",
description="Formats a numeric value into a human-readable string.",
input_schema=ValueInput,
output_schema=FormattedOutput,
fn=format_result_fn,
)
# --- 4. Define the flow ---
flow = Flow(
name="double_add_format",
description="Doubles a number, adds 10, and formats the result.",
steps=[
FlowStep(tool_name="double", input_mapping={"number": "number"}),
FlowStep(tool_name="add_ten", input_mapping={"value": "value"}),
FlowStep(tool_name="format_result", input_mapping={"value": "value"}),
],
)
# --- 5. Execute ---
registry = FlowRegistry()
registry.register_flow(flow)
executor = FlowExecutor(registry=registry)
executor.register_tool(double_tool)
executor.register_tool(add_ten_tool)
executor.register_tool(format_tool)
result = executor.execute_flow("double_add_format", {"number": 5})
print(result.success) # True
print(result.final_output) # {'number': 5, 'value': 20, 'result': 'Final value: 20'}
for record in result.execution_log:
print(record.step_index, record.tool_name, record.outputs)
# 0 double {'value': 10}
# 1 add_ten {'value': 20}
# 2 format_result {'result': 'Final value: 20'}
同梱のサンプルを直接実行することもできます。
python examples/simple_linear_flow.py # simple arithmetic flow
python examples/etl_flow.py # ETL flow: fetch → validate → normalize → enrich → store
python examples/mcp_search_flow.py # MCP-style search → extract → format flow
python examples/naive_vs_compiled.py # timing comparison: naive LLM calls vs ChainWeaver flow
python examples/coding_agent_pr_review.py # deterministic PR-review checklist
python examples/coding_agent_changelog.py # changelog generation workflow template
python examples/coding_agent_debug_log.py # debug-log triage workflow template
python examples/mcp_style_before_after_demo.py # before/after MCP-style flow demo
python examples/release_readiness_flow/release_readiness.py # deterministic release-readiness gate
python examples/skdr_policy_eval_flow.py # offline policy-evaluation workflow template
python examples/integrations/langgraph_node.py # call a flow from a LangGraph node (needs chainweaver[langgraph])
python examples/integrations/openai_agents_tool.py # expose a flow as an OpenAI Agents SDK tool (needs chainweaver[openai-agents])
ホストされているドキュメントには、examples/cookbook/ に対応する
スクリプトが用意されたクックブックのほか、
フレームワークのレシピやワークフローテンプレート(LangGraph、OpenAI Agents SDK、リリース準備状況、ポリシー評価)も含まれています。
@tool デコレーターを使う
@tool デコレーターは、型ヒントを調べて入力スキーマを自動生成することで、
定型コードをなくします。
from pydantic import BaseModel
from chainweaver import tool, Flow, FlowStep, FlowRegistry, FlowExecutor
class ValueOutput(BaseModel):
value: int
class FormattedOutput(BaseModel):
result: str
@tool(description="Doubles a number.")
def double(number: int) -> ValueOutput:
return {"value": number * 2}
@tool(description="Adds ten.")
def add_ten(value: int) -> ValueOutput:
return {"value": value + 10}
@tool(description="Formats the result.")
def format_result(value: int) -> FormattedOutput:
return {"result": f"Final value: {value}"}
flow = Flow(
name="double_add_format",
description="Doubles a number, adds 10, and formats.",
steps=[
FlowStep(tool_name="double", input_mapping={"number": "number"}),
FlowStep(tool_name="add_ten", input_mapping={"value": "value"}),
FlowStep(tool_name="format_result", input_mapping={"value": "value"}),
],
)
registry = FlowRegistry()
registry.register_flow(flow)
executor = FlowExecutor(registry=registry)
executor.register_tool(double)
executor.register_tool(add_ten)
executor.register_tool(format_result)
result = executor.execute_flow("double_add_format", {"number": 5})
print(result.final_output) # {'number': 5, 'value': 20, 'result': 'Final value: 20'}
デコレートしたツールは、直接呼び出すこともできます。
print(double(number=5)) # {'value': 10}
実行可能な、デコレーターの適用前後を比較する例については、examples/decorator_tool.py を参照してください。
FlowBuilder を使う
FlowBuilder は、Flow オブジェクトを直接構築するよりも Pythonic な方法として、
流れるように連結できる API を提供します。生成される Flow は同一です。
これは構文糖衣であり、置き換えではありません。
from chainweaver import FlowBuilder
flow = (
FlowBuilder("double_add_format", "Doubles a number, adds 10, and formats.")
.step("double", number="number")
.step("add_ten", value="value")
.step("format_result", value="value")
.build()
)
.step(tool_name, **mapping)— ステップを追加します。文字列の値はコンテキストキーの参照、文字列以外の値はリテラル定数として扱われます。キーワード引数を指定しない場合は、コンテキスト全体がそのまま渡されます。.step_from(flow_step)— 相互運用のために、構築済みのFlowStepを追加します。.with_input_schema(Model)/.with_output_schema(Model)— 任意のフローレベルの Pydantic スキーマ宣言です。.with_trigger(conditions)— 任意の自由形式のトリガーメタデータです。.build()— 検証済みのFlowを返します。nameまたはdescriptionがない場合は、FlowBuilderErrorが発生します。
インタラクティブなプレイグラウンド
ローカルに何もインストールせずにChainWeaverを試してみませんか?playground/ディレクトリには、事前に読み込まれたフローを選択し、JSON入力を編集して実行し、ステップごとのLLMを使わない実行トレースをMermaid図とともに確認できるStreamlitアプリが用意されています。ライブラリに付属するものと同じFlowExecutorを使用します。
pip install -r playground/requirements.txt
streamlit run playground/app.py
算術、データフロー、MCP形式の検索という3つのサンプルフローが用意されています。実行内容をURL経由でやり取りできる共有可能な?share=<token>リンクを生成し、状態を保持しないため、バックエンドなしでStreamlit Community Cloudにデプロイできます。ローカルでの実行方法とデプロイ手順については、playground/README.mdを参照してください。
アーキテクチャ
chainweaver/
├── __init__.py # Public API
├── builder.py # FlowBuilder — fluent API for flow construction
├── compat.py # schema_fingerprint, check_flow_compatibility
├── compiler.py # compile_flow — static schema flow validation
├── decorators.py # @tool decorator for zero-boilerplate tool definition
├── tools.py # Tool — named callable with Pydantic schemas
├── flow.py # FlowStep + Flow + FlowStatus — ordered step definitions
├── registry.py # FlowRegistry — multi-version flow catalogue
├── executor.py # FlowExecutor — deterministic, LLM-free runner
├── exceptions.py # Typed exceptions with traceable context
└── log_utils.py # Structured per-step logging
コアとなる抽象化
Tool
Tool(
name="my_tool",
description="...",
input_schema=MyInputModel, # Pydantic BaseModel
output_schema=MyOutputModel, # Pydantic BaseModel
fn=my_callable,
)
ツールは、通常のPython呼び出し可能オブジェクトと、厳密な入出力検証を行うPydanticモデルをまとめたものです。
FlowStep
FlowStep(
tool_name="my_tool",
input_mapping={
"key_for_tool": "key_from_context", # flat top-level lookup
"city": "/user/address/city", # RFC-6901 pointer into nested context
"limit": 10, # non-string -> literal constant
},
output_mapping={"renamed": "value"}, # rename/prune outputs before merge
)
input_mappingは、蓄積された実行コンテキストのキーをツールの入力スキーマにマッピングします。文字列値はコンテキスト内で検索されます。通常のキーはトップレベルの検索に使われ、/で始まる文字列はネストされたコンテキスト内のRFC-6901 JSONポインターとして扱われます(#387)。文字列以外の値はリテラル定数として扱われます。
output_mapping(#386)は任意で、コンテキストにマージする前にツールの出力を名前変更し、不要な出力を除外します。{context_key: output_key}を指定すると、列挙された出力キーだけが保持され、それぞれ名前が変更されます。省略すると、すべての出力キーがそのままマージされます。
モデルから見えるスキーマに決して含めてはならないリクエストごとのシークレット(認証トークン、アカウント番号など)を渡すには、initial_inputではなく実行時に指定してください。
result = executor.execute_flow(
"account_overview",
{"query": "what's my balance?"}, # LLM-visible
dynamic_params={"billingAccountNumber": "1.60007029"}, # hidden, injected (#316)
)
Flow
Flow(
name="my_flow",
version="0.1.0", # SemVer string; defaults to "0.1.0" if omitted
description="...",
steps=[step_a, step_b, step_c],
deterministic=True, # metadata annotation; executor is always LLM-free
trigger_conditions={"intent": "process data"}, # optional metadata
)
ステップの順序付きシーケンスです。フィールドの全一覧(status、tool_schema_hashes、および解決後のプロパティアクセサーを持つinput_schema_ref/output_schema_ref文字列フィールド)については、AGENTS.md §5を参照してください。
FlowStepが実行するのは、ツール(tool_name)または登録済みのサブフロー(flow_name)のどちらか一方です。両方を指定することはできません。サブフローを参照すると、再利用可能なフローを組み合わせられます(issue #75)。
fetch_validate = Flow(
name="fetch_validate",
description="Fetch and validate.",
steps=[
FlowStep(tool_name="fetch", input_mapping={"url": "url"}),
FlowStep(tool_name="validate", input_mapping={"data": "data"}),
],
)
fetch_then_transform = Flow(
name="fetch_then_transform",
description="Reuse fetch_validate, then transform.",
steps=[
FlowStep(flow_name="fetch_validate", input_mapping={"url": "url"}), # sub-flow
FlowStep(tool_name="transform", input_mapping={"data": "data"}),
],
)
エグゼキューターは、ステップの解決済み入力を使ってサブフローを実行し、その出力を親コンテキストにマージして、サブフローのExecutionResultを親のStepRecord.sub_resultに設定します。サブフローの参照については、実行前に循環参照と設定可能な最大ネスト深度(FlowExecutor(max_composition_depth=...)、デフォルトは10)を検査し、違反があればFlowCompositionErrorを発生させます。
execute_flowに渡されたdeadlineまたはCancellationTokenは、組み合わせられたサブフローにも引き継がれます。そのため、キャンセルと実時間の予算はサブフロー内のステップ境界でも適用されます。長時間かかるサブフローは、親側の境界だけでなく、サブフロー自身のステップ間で停止します。コストレポートのsteps_executedは、組み合わせられたステップが実際に実行したツール呼び出し数を再帰的にカウントするため、llm_calls_avoidedには組み合わせ全体で実行されたすべてのツールが反映されます。
FlowRegistry
registry = FlowRegistry()
registry.register_flow(flow)
registry.get_flow("my_flow")
registry.list_flows()
registry.match_flow_by_intent("process data") # basic substring match
フローを格納するインメモリカタログです。
FlowExecutor
executor = FlowExecutor(registry=registry)
executor.register_tool(tool_a)
result = executor.execute_flow("my_flow", {"key": "value"})
# Version-targeted execution: run an exact registered version instead of the
# latest. Omitting `version` keeps the default (latest) behaviour. The version
# that actually ran is always recorded on `result.flow_version`, so routing,
# audit, and replay can correlate a result with the precise flow definition.
result = executor.execute_flow("my_flow", {"key": "value"}, version="1.2.0")
assert result.flow_version == "1.2.0"
スキーマを完全に検証し、構造化ログを記録しながら、フローをステップごとに実行します。いかなる時点でもLLM呼び出しは行われません。
ChainAnalyzer
from chainweaver import ChainAnalyzer, ToolChain
analyzer = ChainAnalyzer(tools=[tool_a, tool_b, tool_c])
# All schema-compatible pairs
matrix: dict[str, list[str]] = analyzer.compatibility_matrix()
# All valid tool sequences up to length 3
chains: list[ToolChain] = analyzer.find_chains(max_depth=3)
# Filter by start or end tool
chains = analyzer.find_chains(max_depth=3, start="tool_a", end="tool_c")
# Promote chains to ready-to-register Flow objects
flows = analyzer.suggest_flows(max_depth=3, min_depth=2)
フローの登録や実行より前に、オフラインでスキーマ互換性のあるツールの組み合わせを検出します。compatibility_matrix()は、コンシューマーツールの必須入力フィールドがすべて、型の一致するプロデューサーの出力に含まれているかを確認します。suggest_flows()は名前の一致に基づいてinput_mappingを自動設定し、FlowRegistry.register_flow()に登録できるFlowオブジェクトを返します。
データフロー
initial_input (dict)
│
▼
┌─────────────────────────────────────────────┐
│ Execution context (cumulative dict) │
│ │
│ Step 0: resolve inputs → run tool → merge │
│ Step 1: resolve inputs → run tool → merge │
│ Step N: resolve inputs → run tool → merge │
└─────────────────────────────────────────────┘
│
▼
ExecutionResult.final_output (merged context)
MCP 統合のコンセプト
ChainWeaver は、エージェント/ツールの観測と決定論的な実行の間に位置できます。
Agent / tool traces
│ (observe repeated paths)
▼
Candidate analysis + human review
│ (prove/reject; preserve security boundaries)
▼
Governed deterministic capability
│ (FlowExecutor and/or supported export)
▼
MCP / host-framework invocation
MCP は相互運用のための窓口であり、製品カテゴリーではありません。現在のランタイムでは、レビュー済みのフローを MCP ツールとして公開できます。一方、#555 では、ChainWeaver がランタイムを所有しなくても、ポータブルな出力によって同じ承認済み機能を他のホスト上で実行できるようにするべきかを検討しています。
ChainWeaver は埋め込んで使うライブラリであり、トレースストア、ID システム、エンタープライズ認可コントロールプレーンを所有するランタイムではありません。ホストの作成者は docs/runtime-responsibilities.md をお読みください。
統合
ChainWeaver は MCP エコシステムや主要なエージェントフレームワークと連携します。既存の統合は引き続きサポートされます。新しいアダプターの拡充は、独立した製品検証よりも意図的に優先度を低くしています。
| 統合 | 機能 | エントリーポイント |
|---|---|---|
| MCP サーバー(アウトバウンド) | フローを MCP ツールとして公開します。エージェントは、コンパイル済みフロー全体を 1 つの決定論的なツールとして呼び出します | chainweaver serve · ガイド · FlowServer |
| MCP アダプター(インバウンド) | MCP サーバーが公開するツールを ChainWeaver の Tool としてラップします | chainweaver.mcp.MCPToolAdapter |
| LangGraph | LangGraph ノードからフローを呼び出します | レシピ · examples/integrations/langgraph_node.py |
| OpenAI Agents SDK | フローを Agents SDK の FunctionTool として公開します | レシピ · examples/integrations/openai_agents_tool.py |
| LangChain / LlamaIndex | 双方向のツールブリッジ | chainweaver.integrations.{langchain,llamaindex}(以下を参照) |
| OpenCode | ツール実行を観測し、マクロフローを抽出して、レビュー済みのフローを MCP ツールとして再び公開します | レシピ · chainweaver opencode |
| Claude Code | PostToolUse フックのトレースを取得し、マクロフローを抽出して、レビュー済みのフローを MCP ツールとして再び公開します | レシピ · chainweaver claude |
| VS Code / Copilot | MCP ツールのトレース(Copilot OTel)を取得し、.vscode/mcp.json を通じてレビュー済みのフローを公開します | レシピ · chainweaver vscode |
| GitHub Action | CI で .flow.yaml / .flow.json ファイルを検証し、PR にインライン注釈を付けます | .github/actions/chainweaver · ガイド |
必要な追加パッケージをインストールしてください:pip install 'chainweaver[mcp]'(または langgraph、openai-agents、langchain、llamaindex)。追加パッケージなしで統合機能をインポートすると、内容が明確な ImportError が発生します。
ChainWeaver を MCP レジストリ/awesome リスト/フレームワークディレクトリに公開または掲載したい場合は、docs/distribution.md をご覧ください。幅広い配布は、名称の決定(#556)と検証エビデンス(#553)が整うまで意図的に保留されています。
エラー処理
すべてのエラーは型付けされており、追跡可能です。
| 例外 | 発生条件 |
|---|---|
ToolNotFoundError | ステップが未登録のツールを参照した場合 |
FlowNotFoundError | 要求されたフローが登録されていない場合 |
FlowAlreadyExistsError | すでに存在するフローを登録しようとした場合(overwrite=True の指定がない場合) |
FlowStatusError | ステータスが ACTIVE でないフローを実行しようとした場合(force=True の指定がない場合) |
FlowCancelledError | ステップの境界で deadline を超過した場合、または CancellationToken がキャンセルされた場合(一部の結果を保持します) |
InvalidFlowVersionError | 有効な PEP 440 のバージョン文字列ではない値を指定してフローを登録した場合 |
FlowSerializationError | フローファイル(YAML/JSON)の形式が不正な場合、識別子が不明な場合、または解決できないクラスを参照している場合 |
SchemaValidationError | 入力または出力が Pydantic の検証に失敗した場合 |
InputMappingError | マッピングキーがコンテキストに存在しない場合 |
FlowExecutionError | ツールの呼び出し可能オブジェクトが予期しない例外を発生させた場合 |
ApprovalDeniedError | 実行時の承認コールバックがステップを拒否した、例外を発生させた、または無効な値を返した場合、あるいは strict_safety=True で承認が必要なステップにコールバックが設定されていない場合 |
SafetyCeilingError | ステップの ToolSafetyContract.side_effects が、エグゼキューターに設定された max_side_effect_level を超えている場合 |
GuardrailViolationError | 登録済みの guardrail_callback が入力段階でステップをブロックした場合(コンテンツ安全性/インジェクションチェック) |
ToolDefinitionError | @tool デコレーターが関数からツールを構築できない場合 |
DAGDefinitionError | DAGFlow に循環、重複した step_id、または不明な依存関係がある場合 |
FlowCompositionError | 合成されたフローにサブフローの循環がある、max_composition_depth を超える、または未登録のサブフローを参照している場合 |
ToolTimeoutError | timeout_seconds が設定された Tool が、設定済みの実時間上限を超えた場合 |
ToolOutputSizeError | max_output_size が設定された Tool が、設定済みの上限を超える出力を返した場合 |
FlowBuilderError | 名前または説明を指定せずに FlowBuilder.build() を呼び出した場合 |
AttestationInputError | アテステーション入力ジェネレーターが、スキーマフィールドの値を合成できない場合 |
PluginDiscoveryError | 厳密モードのプラグイン検出(discover_tools(strict=True) / discover_flows(strict=True))で、問題のあるエントリーポイントローダーに遭遇した場合 |
ContribError | chainweaver.contrib.tools のツールが契約違反を検出した場合(JSON ポインターキーの欠落、述語の形式違い、アサーションの不一致) |
FixtureStaleError | record_then_replay の再生呼び出しに一致する記録が見つからない場合(フィクスチャの欠落/古さ) |
FuzzConfigError | プロパティベースのファジング実行の設定が不正な場合(プロパティがない、runs < 1、input_schema も基本入力もないフロー、またはサポートされていない入力フィールド型) |
CostProfileError | 管理対象の PROVIDER_PRICES テーブルに存在しない (provider, model) の組み合わせについてコストを見積もろうとした場合 |
MCPMetadataError | サーバーが提供する MCP ツール名がアダプターの MetadataPolicy に違反し、on_invalid_name="error" が設定されている場合 |
MCPSchemaDriftError | MCPToolAdapter(on_drift="error") で固定された MCP ツールの生スキーマが変更された場合 |
FlowAuthenticationError | ネットワークに公開された FlowServer の認証器が None を返すか例外を発生させた場合。呼び出しはディスパッチ前に拒否されます |
RateLimitExceededError | FlowServer のレートリミッターが呼び出しを拒否した場合 |
FlowAuthorizationError | FlowServer の認可コールバックが呼び出しを拒否した場合(クライアントに安全に公開できる reason_code のみを保持します) |
CheckpointVersionError | 再開されたスナップショットの snapshot_version が、実行中のライブラリと互換性のない MAJOR バージョンである場合 |
すべての例外は ChainWeaverError を継承し、安定した診断用 code(例:CW-E006)を持ちます。CLI はエラー出力にこのコードを付加し、失敗した StepRecord では error_code として公開します。コードの一覧は
docs/reference/error-table.md を参照してください。
標準ツールライブラリ
chainweaver.contrib.tools には、厳選された決定論的なユーティリティツールが含まれています。これにより、新しいユーザーは Tool のボイラープレートを書くことなく、初日の午後から意味のあるフローを組み立てられます。
from chainweaver.contrib.tools import (
assert_equal,
filter_list,
json_pluck,
json_set,
map_list,
passthrough,
)
| ツール | 目的 |
|---|---|
passthrough | 恒等処理 — コンテキストを変更せずに返します。 |
json_pluck | RFC-6901 JSON ポインターを使って値を 1 つ抽出します。 |
json_set | RFC-6901 JSON ポインターを使って値を 1 つ設定し、新しい dict を返します。 |
assert_equal | 2 つのコンテキストキーが異なる場合に ContribError を発生させます。 |
map_list | 登録済みのサブフローをリストの各要素に適用します。 |
filter_list | 判定サブフローが偽を返す要素を除外します。 |
このライブラリは決定論的な処理のみを対象としています。HTTP、ファイル I/O、データベースアクセス、乱数生成、時計は使用しません。状態を持つ処理はユーザーコードに記述してください。pip install 'chainweaver[contrib]' でインストールできます。
実行可能な例:examples/contrib_pluck_and_set.py、
examples/contrib_map_filter.py。
回避コストのレポート
素朴なエージェントが LLM に委ねるステップ間の遷移は、すべて ChainWeaver が排除するルーティング呼び出しです。CostProfile / CostReport はそのコストをドル単位で見積もります。また、保守されている PROVIDER_PRICES テーブル(ライブ HTTP 照会は行わない、日付付きスナップショット)を使って、実際のモデルに基づく料金を算出できます。
from chainweaver.cost import compute_cost_report
# Build a profile straight from the maintained price table.
report = compute_cost_report(
steps_executed=6, # a six-tool flow
actual_execution_ms=4.2,
provider="anthropic",
model="claude-opus-4-7",
)
print(report)
Cost Avoided Report (estimate)
──────────────────────────────
Steps executed: 6
LLM calls avoided: 5
Est. latency saved: 1500.0ms
Est. cost saved: $0.1688
Actual execution time: 4.2ms
Priced against: anthropic/claude-opus-4-7 (as of 2026-05-01)
このテーブルから作成されたすべてのレポートにはスナップショットの as_of 日付が含まれるため、古い料金を確認できます。不明な (provider, model) の組み合わせでは推測せず、CostProfileError を発生させます。呼び出しごとのより正確な数値がある場合は、明示的に profile=CostProfile(...) を渡してください。または、FlowExecutor に cost_profile= を設定すると、すべての ExecutionResult にレポートを付加できます。料金はメンテナーのレビューを経た PR(.github/workflows/update-prices.yml)で更新され、自動マージされることはありません。
これらのレポートは、入力が観測されたトレース測定値に基づいていない限り、推定値です。候補をコンパイルすべきだという根拠として提示してはなりません。#377 では、想定値と実測値に基づくモデル仲介の較正を追跡しています。
エクスポートアダプター
コンパイル済みのフローを chainweaver.export 経由で外部のエージェントフレームワークに渡せます。
from chainweaver.export import (
flow_to_anthropic_tool,
flow_to_callable,
flow_to_openai_function,
)
openai_spec = flow_to_openai_function(flow, executor)
anthropic_spec = flow_to_anthropic_tool(flow, executor)
run = flow_to_callable(flow, executor) # plain dict → dict callable
flow_to_openai_function は、OpenAI の chat / responses API が想定する {"type": "function", "function": {…}} 形式を出力します。flow_to_anthropic_tool は、Anthropic の tool_use 形式を出力します。flow_to_callable はフローを Callable[[dict], dict] としてラップするため、任意の Python 呼び出し可能オブジェクトを受け入れるフレームワークで使用できます。
これらのアダプターはいずれも openai や anthropic をインポートせず、dict と呼び出し可能オブジェクトのみを出力します。これらのクライアントとのランタイム統合は、呼び出し側が行います。
実行可能な例:examples/export_openai_anthropic.py。
エコシステムブリッジ(LangChain、LlamaIndex)
chainweaver.integrations.langchain と
chainweaver.integrations.llamaindex には、既存の LangChain BaseTool / LlamaIndex FunctionTool インスタンスを ChainWeaver に取り込み、ChainWeaver の Tool インスタンスを外部に渡すための、薄い双方向アダプターが含まれています。
from chainweaver.integrations.langchain import (
from_langchain_tool,
to_langchain_tool,
)
cw_tool = from_langchain_tool(my_langchain_tool)
lc_tool = to_langchain_tool(my_cw_tool)
pip install 'chainweaver[langchain]' /
'chainweaver[llamaindex]' でインストールできます。対応する追加パッケージなしでどちらかのモジュールをインポートすると、明確な ImportError が発生します。
プラグインの検出
chainweaver-aws、chainweaver-stripe などのサードパーティーパッケージに対して、ChainWeaver は pytest、Sphinx、MkDocs などで使用されているものと同じエントリーポイントの規約に従います。
公開側(pyproject.toml):
[project.entry-points."chainweaver.tools"]
aws = "chainweaver_aws:get_tools"
[project.entry-points."chainweaver.flows"]
aws = "chainweaver_aws:get_flows"
利用側:
from chainweaver import FlowExecutor, FlowRegistry
# Auto-register every tool / flow advertised by an installed plugin.
registry = FlowRegistry(discover_plugins=True)
executor = FlowExecutor(registry=registry, discover_plugins=True)
検出はオプトイン方式です。chainweaver をインポートしても、プラグインのインポートは実行されません。問題のあるプラグイン(インポート時に例外を発生させる、誤った型を返す)は WARNING でログに記録され、スキップされます。明示的にエラーにする場合は、discover_tools() / discover_flows() に strict=True を渡してください。
実行可能な例:examples/plugin_discovery.py。
実行時学習
ChainWeaver はエージェントの動作を監視し、繰り返される経路に対して決定的フローの候補を提案できます。同じシーケンスが繰り返されたからといって、その経路をコンパイルすることが安全または有益だと証明されたわけではありません。提案にはレビューが必要であり、製品検証プログラムでは、偽陽性、偽陰性、有益な却下を明示的に測定しています。
from chainweaver import ChainObserver, FlowRegistry
observer = ChainObserver()
# Record tool calls as the agent makes them.
observer.record("fetch", {"url": "..."}, {"body": "..."})
observer.record("validate", {"body": "..."}, {"valid": True})
observer.record("transform", {"body": "..."}, {"records": [1, 2, 3]})
observer.end_trace()
# ... many traces later ...
registry = FlowRegistry()
for suggestion in observer.suggest_flows(min_occurrences=3):
# Suggestions are proposals — review; never treat confidence as authorization.
print(suggestion.flow.name, suggestion.confidence,
suggestion.estimated_llm_calls_avoided)
registry.register_flow(suggestion.flow)
ChainObserver(#78)は、実行時トレースから繰り返されるツールシーケンスを抽出し、ランク付けされたFlowSuggestionを出力します。自動登録されることはありません。chainweaver record(#226)は、記録済みの JSONL トレースを抽出し、明示的なレビュー/昇格のためのフローファイル候補を書き出します。ChainWeaverService(#101)は、観測、静的解析、オプションのオフライン提案を結び付け、分析 → 提案 → 統制 → 昇格 のループを実現します。
提案を、ある経路を決定的にするべきだという証拠として解釈する前に、製品検証と導入ゲートを参照してください。
ロードマップ
現在のロードマップは、機能数優先ではなく検証優先です。最新の公開リリースは v0.14.1 です。main でのそれ以降の作業は、次のリリースが作成されるまで未リリースのままです。
| 優先度 | 作業 | 理由 |
|---|---|---|
| P0 | #553 独立した製品反証 | トレース由来の発見/統制が、人による調査と単純な関数を使ったベースラインを上回るかどうかを確認します。 |
| P0 | #554 認可/承認の維持 | コンパイルによって推論の境界が取り除かれることはあっても、セキュリティの境界が暗黙のうちに取り除かれることはありません。 |
| P0 | #522 安定/サポート対象/実験的 API の階層 | 互換性の約束が実装の範囲より小さくなるようにします。 |
| P0 | #519 リリースの整合性 | ソース、パッケージ、タグ、リリース、ドキュメント、成果物の整合性が必要です。 |
| P1 | #527 プライバシープロファイル | トレース分析は、最小化された/ローカルの証拠を使って実行できる必要があります。 |
| #553 の結果を待つ | #334 正規の証拠アーキテクチャ | ユーザーがその作業を検証した後にのみ、大規模なライフサイクルモデルを構築します。 |
| #553 の結果を待つ | #498 本番環境向けのゴールデンパス | 検証済みのニーズを、正規のエンドツーエンドの証明にします。 |
| 需要があれば検討 | #555 移植可能なコンパイル済み機能 | ユーザーが分析を評価しても FlowExecutor を評価しない場合、受け入れられた成果物を移植可能にします。 |
| 広範な配布の前に | #556 命名/検索に関する判断 | 移行コストが低いうちに、見つけやすさ/曖昧さの問題を解決します。 |
これらのゲートで証拠が得られるまでは、広範なディレクトリへの登録申請、ホスト型プレイグラウンドへの投資、追加のフレームワークアダプターの拡充は、意図的に優先度を下げています。
v1.0.0 も証拠を条件としています。docs/v1-release-criteria.mdに従い、独立したワークロード/採用者、手動ベースライン、外部セキュリティレビュー、反復利用、下流の統合、30 日間の RC 互換性検証が必要です。
コマンドラインインターフェース
ChainWeaver には、次のサブコマンドを備えた chainweaver コンソールスクリプトが付属しています。
.flow.yaml ファイルを読み込むには YAML エクストラが必要です
(pip install 'chainweaver[yaml]' — インストールにも記載されています)。
以下の run の例では examples/ に含まれるフローを使用するため、
リポジトリのルートから実行してください。
# Run a flow from disk — no Python required.
chainweaver run examples/double_add_format.flow.yaml \
--tools examples.simple_linear_flow \
--input '{"number": 5}'
# Serve a flow as MCP tools (needs chainweaver[mcp]) — agents call the whole
# compiled flow as one deterministic tool. See docs/mcp-server.md.
chainweaver serve examples/double_add_format.flow.yaml \
--tools examples.simple_linear_flow
# Validate a flow file (used by CI gates and editor tooling).
chainweaver validate flows/etl.flow.yaml
chainweaver check flows/ # whole-directory variant
# Scaffold a runnable first flow project (tools + flow file + run script).
chainweaver init my-first-flow --template linear --with-tests
# Render a flow as ASCII, Graphviz DOT, or Mermaid. Discover it from a directory
# of flow files, an installed package's entry points, or the default registry.
chainweaver viz my_flow --discover-dir flows/ --format dot | dot -Tpng -o my_flow.png
chainweaver viz my_flow --discover-dir flows/ --format mermaid
chainweaver viz --result trace.json --format mermaid # overlay a real run
# Explain a flow deterministically (LLM-free) for review — paste into a PR.
chainweaver explain my_flow --discover-dir flows/ > flow-review.md
# Inspect a flow's structure (table or JSON). `flows list` previews what is
# discoverable so you can see what `inspect`/`viz` can target.
chainweaver inspect my_flow --discover-dir flows/ --format json
chainweaver flows list --discover-dir flows/
# Check that your environment is ready before running anything.
chainweaver doctor flow --profile first-run
# Inspect a coding-agent workspace's MCP / observe setup (read-only).
chainweaver doctor vscode --workspace .
# Install tab-completion for your shell (bash/zsh/fish).
chainweaver --install-completion
# Analyze ExecutionResult traces — bottlenecks, p50/p95/p99 across runs,
# and per-step / per-tool retry / skip / fallback / failure aggregates.
chainweaver profile trace_a.json trace_b.json --format json
# Compare two ExecutionResult JSON files step-by-step.
chainweaver diff baseline.json current.json --perf-tolerance 25
# Observed-determinism attestation: run N inputs × M repeats.
chainweaver attest flows/etl.flow.yaml --tools my_pkg.tools --runs 50 --repeats 3
# Advisory optimization suggestions for a saved flow.
chainweaver suggest flows/etl.flow.yaml --tools my_pkg.tools --trace trace_a.json
# Mine candidate flows from a recorded JSONL tool trace (offline, no LLM).
chainweaver record examples/agent_tool_trace.jsonl --output-dir candidates/
chainweaver flows promote candidates/suggested__fetch__validate.flow.yaml --to reviewed
chainweaver flows promote candidates/suggested__fetch__validate.flow.yaml --to active
# Run one continuous-analysis service pass and report flow proposals.
chainweaver service --tools my_pkg.tools --trace trace.jsonl
# Check saved flows for tool schema drift against the live registry.
chainweaver doctor flow flows/ --check-drift --tools my_pkg.tools
# Property-based fuzzing: generate cases, check invariants, save/minimize failures.
chainweaver fuzz flows/etl.flow.yaml --tools my_pkg.tools \
--property my_pkg.props:no_unauthorized_action --runs 1000 --seed 42 \
--minimize --save-failures failures/
run は、新規インストールからフローの実行を確認するまでの最短ルートです。
.flow.yaml/.flow.json ファイルを指定し、--tools <module>(トップレベルに Tool インスタンスを公開する Python モジュールのインポートパス)を渡して、初期入力を JSON で指定します。手動で作成するフローファイルでは、先頭に type: Flow(または type: DAGFlow)の識別子を宣言する必要があります。詳しくはフローファイル形式のリファレンスをご覧ください。ほとんどのレポート用サブコマンドは、機械処理向けに --format json も受け付けます(inspect、validate、check、run、profile、diff、attest、suggest、doctor)。例外は、--format ascii|dot|mermaid を使う viz、--format md|text を使う explain、および生の JSON Schema を書き出し、--format フラグを持たない dump-schema です。結果を生成するコマンド(inspect、validate、check、profile、diff、attest)は、--format json の出力を安定したバージョン付きエンベロープ({"schema_version", "status", "data", "errors"})でラップするため、自動化処理で status やエラーコードに基づいて分岐できます。詳しくは機械可読な出力をご覧ください。すべてのサブコマンドで同じ終了コード規約(成功は 0、ビジネスロジックエラーは 1、ファイルが見つからない場合/引数エラーは 2)を共有しており、CLI にはタブ補完も付属しています(chainweaver --install-completion)。
inspect と viz は、ディスクまたはレジストリからフローを解決します。
--file <path>、--discover-dir <dir>、または --discover-entry-points を渡すと、Python コードを記述せずにフローを解決できます(issue #381)。chainweaver flows list を使うと、検出可能な項目を事前に確認できます。検出フラグを指定しない場合、プログラムから設定されたプロセス内限定のレジストリにフォールバックします。フラグも設定済みレジストリもない状態で chainweaver inspect my_flow を実行すると、No registry configured. Call chainweaver.cli.set_default_registry(...) before invoking the CLI. と表示され、終了コード 1 で終了します。デフォルトレジストリの経路を接続するには、簡単なエントリースクリプトを使用してください。
# my_cli_entry.py
from chainweaver import FlowRegistry
from chainweaver.cli import main, set_default_registry
from my_app import build_registry # returns a populated FlowRegistry
set_default_registry(build_registry())
main()
詳しいパターン(この分割が存在する理由、つまりファイル指向のコマンドは設定不要のまま、レジストリ指向のコマンドはイントロスペクションしやすい状態に保たれることを含む)については、docs/cli.md § プログラムによる登録をご覧ください。
開発
新しいコントリビューターの方は、good-first-issue/good-first-ai-issue の入門情報と、初めての PR までのステップごとの手順について、CONTRIBUTING.md の最初のコントリビューションをご覧ください。
# Install with the integration extras and the maintainer tooling group
pip install --upgrade pip # --group needs pip >= 25.1
pip install -e ".[integrations]" --group dev
# Run tests
python -m pytest tests/ -v
# Run the examples
python examples/simple_linear_flow.py # simple arithmetic flow
python examples/etl_flow.py # ETL flow
python examples/mcp_search_flow.py # MCP-style search & summarize flow
python examples/naive_vs_compiled.py # naive vs compiled timing comparison
python examples/coding_agent_pr_review.py
python examples/coding_agent_changelog.py
python examples/coding_agent_debug_log.py
ライセンス
このプロジェクトは Apache License 2.0 のもとでライセンスされています。詳しくは LICENSE ファイルをご覧ください。
コメント
AI アプリケーションが外部のツールやデータソースに統一的な方法で接続するためのオープンなプロトコルです。クライアントはモデルとの対話を担い、MCP サーバーはツール・リソース・プロンプトテンプレートを提供します。標準メッセージでやり取りするため、1 つのサーバーを複数のクライアントで再利用できます。