メインコンテンツへ移動
AIチュートリアル

HEXISで信頼性の高いエージェントスキルをステートマシンにコンパイルする

HEXISのインストール方法、エージェントスキルを拡張有限状態機械にコンパイルする方法、実行トレースから更新する方法、CLIまたはPython APIで実行する方法を学びます。マシンの概念、検証、ツールバックエンド、生成ガイド、フォールバック動作、実践的なセキュリティ上の注意点についても解説します。

HEXISで信頼性の高いエージェントスキルをステートマシンにコンパイルする

HEXISとは?

HEXISは、SKILL.mdドキュメントで表現されたエージェントスキルを拡張有限状態機械にコンパイルする、Pythonパッケージ兼コマンドラインツールです。言語モデルにスキル全体を解釈させ、次のステップをすべて選択させる代わりに、HEXISはプログラムで定義された状態、変数、ガード、遷移を使用して処理順序を強制します。

言語モデルは、関連する状態内で推論と生成を引き続き実行します。ただし、次に実行する操作、利用可能な変数、ループを停止するタイミング、到達する終端結果は機械が決定します。この設計により、スキルに記述された要件をエージェントが省略、並べ替え、または誤って適用するリスクを低減します。

HEXISエージェントスキルのコンパイルワークフロー

HEXISはMITライセンスで公開されており、現在はアルファ版ソフトウェアとして位置付けられています。論文Compiling Agent Skills into Extended Finite State Machinesと併せて提供されています。

中核ワークフロー

一般的なHEXISワークフローは、次の3段階で構成されます。

  1. コンパイル:モデルがスキルドキュメント、タスク入力、ツール定義、スキルルールを読み取り、efsm-v1マシンの草案を作成します。HEXISはスキーマ、ガード、到達可能性、終了性、節の網羅性、ツール参照を検証します。無効な草案はモデルに返され、修正されます。
  2. 更新:新しい実行トレースをイベントに正規化します。各トレースステップについて、モデル、決定ファイル、または決定論的アライナーが、既存の状態に一致させるか、状態を作成するか、ノイズを無視するか、トレースを除外するかを決定します。
  3. 実行:ランタイムが現在の状態に関連付けられたアクションを実行し、宣言された出力を記録したうえで、ガードがtrueと評価された最初の遷移を選択します。

更新されたマシンは、必要な検査に合格し、新しいトレースだけでなく、これまでに受け入れられたすべてのトレースも再生できる場合にのみ受け入れられます。検証に失敗した場合、既存のマシンは変更されません。

主な機能

  • OpenAI互換コンパイル:コマンドラインからモデル、エンドポイント、APIキーの環境変数を選択できます。
  • トレースベースの更新:受け入れ済みのトレースを無効にすることなく、成功した実行動作を1つずつの判断として取り込めます。
  • 可読性の高いJSONマシン:マシンは、型付き変数と明示的な遷移を備えたプレーンJSONのefsm-v1形式を使用します。
  • 複数のアクションタイプ:状態ではtool、model、judge、user、endの各アクションを実行できます。
  • 有界制御フロー:順序付けられたガードとループカウンターにより、分岐と再試行回数の上限をサポートします。
  • ドキュメント生成:通常のビルドごとにGUIDE.mdとPROMPT.mdが生成されます。
  • フォールバック動作:フォールバック状態は直近のツールステップから再試行し、元のスキルを解釈実行に引き渡すこともできます。
  • ツールバックエンド:マシンはOpenCodeツール、ローカルBash実行環境、またはモデルによって実現されるレジストリ定義ツールを利用できます。
  • ハーメチックテスト:リポジトリには、APIキー、モデルエンドポイント、ネットワーク接続を必要としないテストが350件以上含まれています。

インストールと前提条件

PyPIからインストール

HEXISにはPython 3.11または3.12が必要です。pipでパッケージをインストールします。

pip install hexis-agent

Pythonではパッケージをhexisとしてインポートし、コマンドライン実行ファイルにはhexis-agentという名前を使用します。

チェックアウトからインストール

pip install .

pytest、Ruff、build、Twineなどの開発用依存関係には、編集可能インストールを使用します。

pip install -e ".[dev]"

ランタイム要件

モデルを利用するマシンのコンパイルと実行には、OpenAI互換のチャットエンドポイントが必要です。デフォルトの実行バックエンドでは、OpenCodeもPATH上に必要です。マシンがBashのみを必要とする場合は、--executor localを選択すると、OpenCodeを使わずにローカルのサブプロセスでコマンドを実行できます。

オフラインクイックスタートを試す

パッケージにはtable_cleanという小規模なハーメチック例が含まれています。スクリプト化されたモデル、ツール、インメモリファイルシステムを使用するため、ネットワークに接続せず実行できます。

from hexis.execution import runtime
from hexis.examples import table_clean as tc

machine = tc.reference_machine()
task = tc.gen_tasks(1, seed=0)[0]

result = runtime.run_task(
    machine,
    task,
    model=tc.build_model(),
    tools=tc.build_registry(tc.MemFS(task["files"])),
    doc=tc.skill_doc(),
)

print(
    result.stopped,
    " -> ".join(result.path()),
    tc.verify(task, result.trace),
)

この例は終端結果で終了し、状態パスを表示するとともに、生成されたトレースが例の検証ツールに合格したかどうかを報告します。外部エンドポイントを設定する前に、インストールが正常に完了したことを確認するのに役立ちます。

モデルエンドポイントを設定する

HEXISは、コマンドラインオプションまたは環境変数からモデル識別子、ベースURL、APIキーを読み取ります。基本的なシェル設定は次のようになります。

export API_KEY=your-key
export MODEL=qwen3.6-flash
export BASE_URL=https://your-endpoint/v1

MODEL、BASE_URL、API_KEYは.envファイルに記述することもできます。HEXISは作業ディレクトリから上位へ向かって検索し、環境にすでに存在する変数を優先します。

再利用するエンドポイント引数をシェル変数に保持するには、次のようにします。

M="--model qwen3.6-flash --base-url https://your-endpoint/v1"

--api-key-env NAMEオプションを使用すると、キーに使用する別の環境変数を選択できます。APIキーがコマンドラインで渡されたり、ビルドマニフェストに保存されたりすることはありません。

スキルをマシンにコンパイルする

コンパイラーにスキルのパスを指定し、出力ディレクトリを選択します。

hexis-agent compile \
  --skill path/to/skill \
  --out build/ \
  $M

スキルディレクトリにはSKILL.mdが含まれている必要があります。また、ターミナル、派生イベントラベル、要件、ターミナル条件を宣言するcompile.jsonを含めることもできます。このファイル内の各ルールには、そのルールの導出元となった文が引用されています。

compile.jsonがない場合、コンパイラーはモデルにスキルからルールを抽出させ、引用文をドキュメントと照合します。その後、有効な設定がrules.jsonとして保存されます。

ビルドディレクトリの内容

  • machine.jsonには現在のマシンが保存されます。
  • machine_init.jsonには初期コンパイル済みマシンが保持されます。
  • build.jsonにはソース情報、コマンド設定、モデルの詳細、結果、トークン使用量が記録されますが、APIキーは決して記録されません。
  • skill/SKILL.md、tools.json、rules.jsonにはコンパイル入力が保持されます。
  • traces/にはビルドで使用されたトレースのハッシュ化コピーが格納されます。
  • progress.jsonにはトレースの結果と、マシンを保護するために受け入れられたトレースが記録されます。
  • decisions.jsonlには更新に関する質問と回答がキャッシュされます。
  • report.md、context.json、ログファイルには診断情報が記録されます。
  • GUIDE.mdでは、入力、ツール、状態、遷移、ループ、フォールバック動作について説明します。
  • PROMPT.mdには、ツールを使用するエージェントがマシンを状態ごとに実行するためのシステムプロンプトが記載されています。

マシンモデルを理解する

HEXISマシンは、efsm-v1形式を使用するJSONドキュメントです。主な要素は、変数、状態、アクション、遷移、ターミナル、フォールバック状態です。

変数

変数は、init_fromを使用してタスク入力フィールドから初期化するか、initを使用して定数値から初期化できます。アクションは、宣言された変数にのみ結果を書き込みます。

アクション

  • Model: 状態固有のプロンプトと選択された入力変数から、宣言された変数を生成します。
  • Tool: 指定された名前のツールを呼び出します。${command}などの参照は実行時に置換されます。
  • Judge: 固定された選択肢からラベルを選ぶか、abstainラベルを返します。
  • User: ユーザー入力を要求します。
  • End: ターミナル結果を返して実行を停止します。

遷移とガード

遷移は、状態のアクション完了後に順番に評価されます。ランタイムは、ガード条件が成立する最初の遷移を実行します。空のガードは無条件を意味するため、最後に配置する必要があります。遷移ではincによってカウンターを増分することもでき、回数制限付きの再試行ループを実現できます。

ガードは、hexis.machine.condが実装する制限付きの式言語を使用します。相互排他やループ上限などのプロパティを静的解析できますが、Pythonのevalは使用しません。

トレースからマシンを更新する

実行トレースはJSON Linesファイルです。タスクのメタデータと判定で始まり、その後に1行につき1つのイベントが続きます。トレースには、ツール呼び出し、モデル出力、終了イベントを含めることができます。

まず、モデル呼び出しや変更の書き込みを行わずに、保留中のトレースをプレビューします。

hexis-agent update \
  --build build/ \
  --traces traces/ \
  --show 3

次に、更新を実行します。

hexis-agent update \
  --build build/ \
  --traces traces/ \
  $M

各トレースステップについて、判定器は4つの結果のいずれかを選択します。

  • matchは既存の状態を再利用し、必要に応じて遷移を追加します。
  • newは、記述された目的に基づいて状態を作成します。
  • ignoreは、ハーネスのノイズを検討対象から除外します。
  • excludeは、トレース全体を除外します。

モデルの回答では、候補となる状態の特定とステップの目的の説明も行われ、スキルの条項との関連付けが示される場合もあります。HEXISは、生成された候補マシンを検証し、保護されているすべてのトレースを再実行してから受け入れます。

更新を再開し、コストを管理する

モデルの回答はdecisions.jsonlにキャッシュされます。同じコマンドを繰り返すと、それらの回答が再利用されます。また、終了ステータス3で中断された実行は、保存済みの進行状況から再開できます。モデルに意図的に再回答させる場合にのみ、--no-cacheを使用してください。

更新には通常、トレースステップごとにモデル呼び出しが約1回必要です。実行を制限するには--max-traces Nを使用します。モデルを使用しない方法として、--decisions FILEで人間または外部の判断を指定するか、--decider alignで決定論的なアライメントを選択できます。

新しいトレースを処理する前に、HEXISは現在のマシンを検証し、受け入れられたすべてのトレースを再実行します。手動編集や変更されたツール定義によってビルドが壊れている場合、コマンドはステータス2で終了し、ビルドは変更されません。

コンパイル済みマシンを実行する

実行前にbuild/GUIDE.mdを確認してください。必要なタスク入力、利用可能なツール、状態のアクション、遷移順序、再試行上限、フォールバック動作が記載されています。

キーと値の形式でタスク入力を指定してマシンを実行します。

hexis-agent run \
  --machine build/ \
  --input request="Process this task" \
  --workdir work/ \
  --executor local \
  $M

マシンが必要とする各入力に対して、追加の --input KEY=VALUE オプションを渡します。実行を再利用可能な JSON Lines トレースとして保存するには、次を追加します。

--json run-trace.jsonl

デフォルトのエグゼキューターは OpenCode ツールを使用します。ローカルエグゼキューターはサブプロセスで Bash コマンドを実行します。実行時、マシンはバックエンドから提供されたツール、またはツールレジストリで定義されたツールのみを使用できます。HEXIS が不足しているツールを暗黙的に置き換えることはありません。

Python からマシンを使用する

コアランタイムのエントリーポイントは hexis.execution.runtime.run_task です。ロード済みのマシン、input オブジェクトを含むタスク、モデルアダプター、ツールレジストリ、およびフォールバック実行で必要になる可能性があるスキルドキュメントを渡します。

from hexis.execution import runtime

result = runtime.run_task(
    machine,
    {"input": {
        "request": "Answer the question",
        "output_path": "answer.txt",
    }},
    model=model,
    tools=tools,
    doc=skill_document,
)

print(result.stopped)
print(result.path())
print(result.trace)

関連する API には、マシンをロードする hexis.machine.schema.load_machine、エンドポイントを設定する hexis.llm.llm_client.client_from_env、ガイド、プロンプト、Mermaid 図を生成する hexis.guide の関数があります。

付属のサンプルマシンを使用する

リポジトリには、examples/machines/ 以下にコンパイル済みのマシンが4つ含まれています。

  • dabench: 計算を使ってデータファイルに関するデータ分析の質問に答えます。
  • livemath: 定理に基づく数学の多肢選択問題に答えます。
  • sealqa: ローカルコーパスから質問に答え、根拠を含めます。
  • spreadsheet: 構造を変更せずにワークブックを編集します。

これらのマシンは通常、モデル状態でシェルコマンドを作成し、ツール状態でそれを実行し、returncode に基づくガード付きリトライを行い、ツールステップで回答を読み戻し、判定状態で検証済みまたは未検証の終端のいずれかを選択します。

たとえば、次のように LiveMath マシンを実行します。

hexis-agent run \
  --machine examples/machines/livemath \
  --input request="..." \
  --input output_path=answer.txt \
  --workdir work/ \
  --executor local \
  $M

サンプルマシンはモデルなしでロードし、構造をチェックできますが、実行には設定済みのモデルエンドポイントが必要です。

高度なヒント

ドキュメントを再生成する

--no-guide を使用しない限り、コンパイルと更新によってドキュメントが自動生成されます。次のコマンドで手動生成することもできます。

hexis-agent guide --build build/

machine.json をコマンドに直接指定することもできます。生成されたエージェントプロンプトに元のスキルを含め、フォールバック後の解釈実行を可能にするには、--embed-skill を追加します。

ツール定義を明示的に指定する

マシンがカスタムツールを使用する場合は、--tools registry.json を渡します。コンパイル中、ツール名は不透明な識別子として扱われます。実行時、レジストリで定義されたツールはモデルによってシェルコマンドとして実現できますが、ネイティブツールは選択したバックエンドから提供する必要があります。

モデルリクエストを調整する

コンパイルと更新では、--temperature、--max-tokens、--llm-timeout、--llm-retries、--stream、--extra-body JSON などのオプションを使用できます。Qwen 互換エンドポイントでは、--no-think、--think-budget、--judge-think-budget によって実行時の推論を制御できます。

プロバイダー固有の環境変数を使用する

--provider NAME オプションは、NAME_MODEL、NAME_BASE_URL、NAME_API_KEY を読み取ります。MiniMax および DeepSeek のプロバイダー名には組み込みのデフォルトが用意されています。

終了ステータスを確認する

  • 0 は成功を示します。
  • 2 は使用方法、設定、またはビルドの問題を示します。
  • 3 はモデルエンドポイントの失敗または中断を示します。再開できるように進行状況が保存されます。

開発用チェックを実行する

pytest
ruff check src tests
python -m build && twine check --strict dist/*

テストスイートは外部依存なしで実行できます。opencode 実行ファイルが利用できない場合、OpenCode 固有のテストはスキップされます。

セキュリティとプライバシー

HEXIS は、シェルコマンドを含む、言語モデルが生成したツール引数を実行できます。信頼できないワークロードは隔離された環境で実行し、信頼できるマシン、スキル、レジストリ、タスクファイルのみを使用してください。

更新処理では、トレースのステップ、短縮されたツール結果、スキルの節が設定済みのモデルエンドポイントに送信されます。ビルドディレクトリにはトレースのコピーとモデルへの質問が保持されます。さらに、PROMPT.md には、スキルから生成された完全なマシンとプロンプトが含まれます。これらの成果物を共有する前に確認してください。

ランタイムは、すべての呼び出しにマシン全体を公開するのではなく、各モデル呼び出しを現在実行中の状態のプロンプトに限定します。

まとめ

HEXIS は、自然言語によるエージェント指示を、明示的で検証可能なワークフローに変換します。状態内でのモデル推論に、プログラムによる遷移、トレースの再生、上限付きリトライ、ツール制限、生成されたガイド、フォールバック処理を組み合わせることで、スキル実行の予測可能性を高める構造化された方法を提供します。まずオフラインの例から始め、信頼できる小さなスキルをコンパイルし、生成されたガイドを確認してから、検証結果を監視しつつトレースを段階的に導入してください。