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

UNCUTでシェルパイプライン上のロスレスなコーディングエージェントを実行する

このチュートリアルでは、ターミナル、CIジョブ、コンテナ、実験環境向けの小型ヘッドレス・コーディングエージェント・ハーネス「UNCUT」のインストールと設定方法を説明します。プロンプトの実行、パイプ入力の処理、安全なツールの使用、JSONLセッションの再開、NDJSONイベントの利用、暗黙の切り詰めを伴わないプロバイダー制限への対処方法を学べます。

UNCUTでシェルパイプライン上のロスレスなコーディングエージェントを実行する

UNCUTとは?

UNCUTは、シェルパイプライン、CIジョブ、コンテナ、エージェントの実験向けに設計された、ヘッドレスのコーディングエージェント・ハーネスです。小型の静的リンク済みGoバイナリとして配布され、標準入力と標準出力を介して通信します。ターミナルUI、テレメトリ、プラグインシステム、バックグラウンドエージェント、自動リトライ、隠れたコンテキスト圧縮はありません。

最大の特徴は、ロスレスな転送契約です。UNCUTはモデルを呼び出すたびに会話全体を送信し、有効なUTF-8プロンプト、保存済みメッセージ、ファイル内容、コマンド出力を切り詰めたり、要約したり、削除したり、書き換えたりしません。プロバイダーが出力制限によってレスポンスを途中で停止した場合、UNCUTは部分的なレスポンスを成功した回答として扱わず、エラーを報告します。

重要:ロスレス転送によって、モデルのコンテキストウィンドウが拡張されたり、プロバイダー側の処理が制御されたりすることはありません。プロバイダーは、サイズ超過したリクエストを引き続き拒否できます。UNCUTは、コンテンツを黙って削除するのではなく、その失敗を明示します。

主な機能

  • 完全なコンテキスト:保存されているすべてのメッセージとツール結果が、各モデルリクエストで送信されます。
  • ヘッドレス動作:最終テキストはstdoutに書き込まれ、--jsonを使うと構造化されたNDJSONイベントが提供されます。
  • ポータブルバイナリ:Linux、macOS、Windows向けに、amd64とarm64のリリースが用意されています。
  • プロバイダーに依存しないプロトコル:UNCUTは、ローカルサーバーを含むOpenAI互換のChat Completionsエンドポイントで動作します。
  • 再開可能なセッション:追記専用のJSONLファイルに、完全なメッセージとツール結果が保持されます。
  • 4つの専用ツール:エージェントは、ファイルの読み取り、ファイルの書き込み、テキストの完全一致置換、コマンドの実行を行えます。
  • 明示的な失敗:不正なUTF-8、壊れたセッション、出力の切り詰め、ステップ制限の超過は、黙って復旧せずエラーになります。

UNCUTをインストールする

Linux

お使いのアーキテクチャに合ったリリースバイナリをダウンロードします。ARM64システムではamd64をarm64に変更してください。

VERSION=0.1.1
ARCH=amd64
curl -fSLo uncut "https://github.com/Balanov/uncut/releases/download/v${VERSION}/uncut-linux-${ARCH}"
mkdir -p "$HOME/.local/bin"
install -m 0755 uncut "$HOME/.local/bin/uncut"
export PATH="$HOME/.local/bin:$PATH"
uncut --version

$HOME/.local/binが永続的なPATH設定にまだ含まれていない場合は、追加してください。

macOS

Apple Siliconシステムでは通常arm64を使用し、Intel Macではamd64を使用します。

VERSION=0.1.1
ARCH=arm64
curl -fSLo uncut "https://github.com/Balanov/uncut/releases/download/v${VERSION}/uncut-darwin-${ARCH}"
mkdir -p "$HOME/.local/bin"
install -m 0755 uncut "$HOME/.local/bin/uncut"
export PATH="$HOME/.local/bin:$PATH"
uncut --version

Windows PowerShell

$Version = "0.1.1"
$Arch = "amd64"
$Dest = "$env:LOCALAPPDATA\Programs\UNCUT"
New-Item -ItemType Directory -Force $Dest | Out-Null
Invoke-WebRequest -Uri "https://github.com/Balanov/uncut/releases/download/v$Version/uncut-windows-$Arch.exe" -OutFile "$Dest\uncut.exe"
$env:Path = "$Dest;$env:Path"
uncut --version

Windows ARM64では、amd64の代わりにarm64を使用してください。今後のPowerShellセッションでもコマンドを使用できるように、保存先ディレクトリをユーザーのPATHに追加します。

Goでインストールまたはビルドする

Go 1.26以降がインストールされている場合は、最新バージョンを直接インストールできます。

go install github.com/Balanov/uncut/cmd/uncut@latest

または、リポジトリのチェックアウトからビルドします。

git clone https://github.com/Balanov/uncut.git
cd uncut
go build -trimpath -ldflags="-s -w" -o bin/uncut ./cmd/uncut

Windowsでは、出力先にbin/uncut.exeを使用してください。

ダウンロードしたバイナリを検証する

すべてのリリースにはchecksums.txtファイルが含まれています。次の例では、Linux amd64版のダウンロードを検証します。

VERSION=0.1.1
ARCH=amd64
curl -fSLO "https://github.com/Balanov/uncut/releases/download/v${VERSION}/checksums.txt"
grep "uncut-linux-${ARCH}$" checksums.txt | sha256sum -c -

現在、リリースバイナリにはコード署名がないため、GatekeeperまたはSmartScreenに警告が表示される場合があります。実行ファイルを許可する前に、SHA-256チェックサムを検証してください。macOSでの検証後は、インストールしたバイナリだけから隔離属性を削除できます。

xattr -d com.apple.quarantine "$HOME/.local/bin/uncut"

モデルプロバイダーを設定する

UNCUTにはモデル識別子が必要です。ホステッドサービスでは通常、APIキーも必要になります。両方の値を設定してから、プロンプトを実行します。

export UNCUT_API_KEY="your-api-key"
export UNCUT_MODEL="your-model-id"
uncut "Inspect this repository and fix the failing tests"

UNCUT_BASE_URLまたはOPENAI_BASE_URLが設定されていない場合、デフォルトのエンドポイントはhttps://api.openai.com/v1です。別のOpenAI互換エンドポイントを使用するには、そのベースURLを指定します。

export UNCUT_BASE_URL="https://openrouter.ai/api/v1"

UNCUTは、UNCUT_API_KEYがない場合にOPENAI_API_KEYも使用します。ローカルエンドポイントでは、デフォルトでキーは必要ありません。

ローカルのOllamaに接続する

READMEでテスト済みの例では、ツール対応のqwen3:8bモデルをインストールして使用します。

ollama pull qwen3:8b
export UNCUT_BASE_URL="http://localhost:11434/v1"
export UNCUT_MODEL="qwen3:8b"
uncut "Explain this repository"

例を、使用するマシンにインストールされているモデルに置き換えてください。ツール呼び出しの品質と動作は、選択したモデルによって異なります。

最初のコーディングタスクを実行する

エージェントに検査させたいリポジトリからUNCUTを開始します。デフォルトでは、現在のディレクトリがファイルツールとシェルコマンドのワークスペースになります。

cd path/to/project
uncut "Inspect this repository, run the tests, and fix the failure"

タスク中、モデルは4つのツールを呼び出せます。

  • read_fileは、UTF-8テキストファイル全体を読み取ります。
  • write_fileは完全な内容を書き込み、存在しない親ディレクトリを作成します。
  • replaceは、1つの一致箇所だけを置換します。一致が0件または複数件の場合は失敗します。
  • run_commandは、終了コードと標準出力・標準エラーを結合した完全な内容を返します。

ファイルツールのパスはワークスペース内に留める必要があります。Unixでは、コマンドは/bin/sh -cを通して実行されます。Windowsでは、cmd.exe /D /S /Cを通して実行されます。

UnixパイプラインでUNCUTを使う

UNCUTは、パイプで渡された入力をそのままプロンプトに追加します。そのため、一時ファイルを作成せずにレビューやログ分析を行えます。

git diff | uncut "Review this diff. Do not edit files."
cat failing-test.log | uncut "Find the likely cause"

入力は有効なUTF-8でなければなりません。UNCUTはバイトを黙って置換せず、無効な入力を拒否します。また、バイナリファイルも拒否します。Windowsでは、一部のコマンドがUTF-16やコードページの出力を生成するため、可能な限りユーティリティがUTF-8を出力するよう設定してください。

構造化されたNDJSONイベントを利用する

UNCUTをスクリプト、CIシステム、その他のエージェント基盤と統合する場合は、--jsonを使用します。

uncut --json "Run the tests and fix the failure"

イベントストリームには、次のレコードタイプが含まれる場合があります。

  • userはユーザーメッセージを表します。
  • assistantはアシスタントメッセージと、完了したツール呼び出しを表します。
  • assistant_metaは使用量の情報と終了理由を表します。
  • toolは完了したツール結果を表します。
  • doneは実行が正常に完了したときに出力されます。
  • errorは実行に失敗したときに出力されます。

UNCUTはストリーミングを行わないChat Completionsを使用します。テキストとツール呼び出しに対応していますが、画像入力には対応していません。

セッションを作成して再開する

セッションは、会話全体とツール結果を含む追記専用のJSONLレコードです。セッションファイルを指定してタスクを開始し、同じファイルを再利用して続行できます。

uncut --session .uncut/work.jsonl "Start the refactor"
uncut --session .uncut/work.jsonl "Continue with the tests"

ファイルがすでに存在する場合、UNCUTは完全な履歴を読み込みます。新しいレコードは各ステップの後に追加され、同期されます。無効または不完全なレコードがある場合は明示的なエラーになり、セッションを読み込むために破棄されることはありません。

セッションファイルには、ソースコード、コマンド出力、認証情報、その他の秘密情報が含まれる場合があります。適切に保護し、バージョン管理にコミットしないでください。

ワークスペースとエージェントループを制御する

現在のディレクトリ以外のワークスペースに対して実行するには、--cwdを使用します。

uncut --cwd ./services/api "Run the API tests and explain any failures"

リクエストとループの動作は、いくつかのフラグで制御できます。

  • --max-steps <n>はモデル呼び出し回数を制限します。デフォルトは32です。
  • --max-tokens <n>は、プロバイダーのデフォルト値を使わず、明示的な出力上限を設定します。
  • --request-timeout <duration>は、リクエストごとのタイムアウトをデフォルトの10mから変更します。値に0を指定するとタイムアウトが無効になります。
  • --no-agentsは、UNCUTがワークスペースのAGENTS.mdを読み取るのを防ぎます。

デフォルトでは、UNCUTはワークスペースルートにあるAGENTS.mdをすべて読み取り、システムプロンプトに追加します。セッションを再開するときは、現在のファイルから再構築せず、保存されている元のシステムメッセージを再利用します。

終了コードを理解する

信頼できる終了コードにより、UNCUTは自動化で使いやすくなります。

  • 0は、エージェントが正常な最終回答を生成したことを示します。
  • 1は、プロバイダー、入出力、セッション、または実行のエラーを示します。
  • 2は、コマンドラインの使用方法が無効であることを示します。
  • 3は、プロバイダーがfinish_reason=lengthまたはmax_tokensを返したことを示します。UNCUTは不完全な回答を拒否します。
  • 4は、最終回答に到達する前に最大ステップ数へ達したことを示します。

CIでは、0以外のコードをすべて実行失敗として扱い、標準エラーまたは--jsonの最終errorイベントを確認してください。

高度なヒント

上限を意図的に設定する

UNCUTはコンテキストを圧縮しないため、長いセッションや大きなツール結果によって、最終的にモデルのコンテキストウィンドウを超えることがあります。適切なタイミングで新しいセッションを開始し、十分なコンテキスト容量を持つプロバイダーを選択してください。また、--max-tokensはプロバイダーの応答上限を理解したうえでのみ設定してください。UNCUTは不完全な応答を結合したり、自動的に再試行したりしません。

自動実行を機械可読に保つ

CIや統合では、会話形式の最終テキストを解析するのではなく、--jsonを使用してください。分離されたメタデータイベントにより、アシスタントの内容に混在させずに終了理由と使用量を確認できます。

信頼できない作業には隔離環境を使う

UNCUTはサンドボックスではありません。ファイルツールはワークスペースの境界を強制しますが、run_commandは現在のオペレーティングシステムユーザーの権限で実行され、これらのファイルチェックによって制限されることはありません。信頼できないプロンプトやリポジトリは、使い捨てコンテナなどの隔離環境で実行してください。ファイルの変更とセッションレコードは、自分で確認してください。

承認ダイアログ、自動コミット、自動リトライ、隠れた復旧ループはありません。これにより実行動作は直接的になりますが、同時に、適切に制限された環境を選ぶ責任が生じます。

ロスレス契約をローカルで検証する

リポジトリには、実際のバイナリとローカルプロバイダーを使用する決定論的な検証スクリプトが含まれています。Python 3が必要ですが、APIキー、外部モデル、サードパーティ製Pythonパッケージは必要ありません。

go build -o bin/uncut ./cmd/uncut
python bench/proof.py ./bin/uncut

この検証では、大容量ファイルとコマンド出力の完全な転送、セッションの正確な再開、編集動作、明示的な切り詰めエラー、ステップ数の上限、不正なUTF-8の処理を確認します。これらのチェックが測定するのはモデルの品質ではなく、転送動作です。記録済みの結果と再現手順はUNCUTリポジトリで確認できます。

開発時のチェックを実行する

UNCUT自体を変更する場合は、Goコードをフォーマットし、テストを実行して、vetで検査します。

gofmt -w cmd internal
go test -count=1 ./...
go vet ./...

まとめ

UNCUTは、ターミナル、パイプライン、コンテナ、CIシステムからコーディングエージェントを実行するための、意図的に小規模で透明性の高い手段を提供します。完全なメッセージ転送、明示的なエラー処理、再開可能なセッション、構造化イベント、4つの組み込みツールを備えているため、コンテキストが気付かないうちに削減されることを許容できない場合に役立ちます。OpenAI互換エンドポイントを設定し、隔離されたワークスペースで開始してください。再現可能な自動化が必要な場合は、セッションまたはNDJSON出力を使用します。