viz は何をしますか?
固定のレンダラ assets/viz.js がすべてのビジュアルを描画します。エージェントは 文法 に従ってデータのみを記述するため、ビジュアルのトークン消費は、置き換え対象のASCIIツリーとほぼ同程度です。その代わり、ステップリプレイ、ノードインスペクタ、エッジトレース、フィルタリング、パスコピーといった機能を利用できます。
ビューの選択
HTMLではなくデータを記述します:== graph セクション(ノード、パス、view:)またはチャートセクション。読者が求めている問いに基づいてビューを選び、必要な文法のみを参照してください:文法(グラフ、ツリー、差分)、チャート(== timing、gantt、hist、retries、causes、board、stock、waits)。
どのように流れるか?
- コンポーネント間のデータ移動(分岐、フォールバック、非同期ホップ、障害終了)→
view: flow(デフォルト)。「ウォークスルー」を追加するとナレーションテールが付きます(後述)。各エッジに移動する内容をラベル付けし、エッジを発生順に宣言します。番号は自動で付与されます。 - 誰が動作し、何を送信し、何がフィルタリングし、その結果は何か →
ranks:列、トリガーごとに1パス、通過した場合は=> result、フィルタリングされた場合は=| resultで終了。チームやサービスを帯として表示するにはlane:を追加します。 - サービス間の経時的なリクエスト →
view: seq、待機時間が重要な場合はat:時刻を付けます。seqは呼び出し順序とその間の待機時間がポイントである場合に、flowは分岐がポイントである場合に選択します。各メッセージの後の各サービスの状態 → エッジの下にsets: id=*charging、ノードの下にstate:を記述します。 - 1つのフィールドやジョブのライフサイクル →
view: states、ストーリーごとに1パス(!giveup: running > blocked => dead)。ユーザー向けフローには開始ドット([*] -> form)、トーン、groupボックスを追加します(ビュー)。 - 誰が誰を呼ぶか →
== tree。ある時点のコールスタックと、問題となった値 →view: stackとlocals:。
いつ、どれだけの間?
- 同時に実行されるもの:競合、重複する作業 →
== timing、ワーカーごとに1レーン、重複範囲に!window。 - リトライが積み上がった理由:バックオフ、ジッター、諦めポイント、同時に多数のクライアント →
== retries、policy:を付加。 - リクエストのレイテンシがどこで消費され、どのチェーンがそれを制約するか(クリティカルパス、スラック) →
== gantt、afterでバーを連結。budget:で制限を描画し、変更行にwas 140msと記述すると、古い実行結果がその下に描画されます。
どのくらいの量か?
- ボリュームの分割:トラフィック分割、ファネル、リクエストの離脱箇所 →
view: sankey、各パスにweight:を付け、離脱するパスは=| <exit node>で終了。ボリュームが重要な場合は、ranks:よりもサンキーを使用します。 - テールなのか全体なのか(p50 vs p99、レイテンシリグレッション) →
== hist、旧分布にはwas:を付加。 - しきい値に対する経時的な1つの量(キュー深度、ラグ、使用中のプール)、ストック・アンド・フローとして →
== stock、meter:帯を付加。繰り返しパターンの場合は、典型的な1ウィンドウをプロットして説明を加えます。
なぜ壊れ、どこで詰まっているか?
- 誰がどのロックを保持し、誰がそれを待っているか、デッドロック →
== waits:循環を検出します。 - インシデントの推定原因、原因として断定/否定されたもの →
== causes、フィッシュボーン図。 - ステージをまたぐ作業項目(バックフィルのシャード、パイプラインのジョブ)、WIP制限とブロックされているもの →
== board、かんばん図。 - チェックが読み取る入力と、各入力を最新に保つトリガー → グラフの後に
== cover。ライター × フィールド行列 →columns: <rank>。
何が変わったか?
- 1つのレイアウトに対する変更 → ノードとパスに
+と-。読者は before / both / after の切り替えが可能。 - コールツリーに対する変更の影響 →
== diff、手動ではなくコンバーターから生成。<viz>はこのスキルのディレクトリです。最初の2つの引数はベースとヘッドの参照(PRのベースブランチ、次にHEAD)、<paths>でスキャン範囲を制限します:
python3 <viz>/scripts/viz.py calldiff main HEAD --max-depth 4 <paths> # base + == diff を出力、変更のないサブツリーは折りたたみ
python3 <viz>/scripts/viz.py calltree --entry submitForm
必要に応じて任意のビューに追加:
- 各ステップの理由 → パスに
| payload | narrationテールを追加。それぞれがリプレイステップになります。 - シナリオを説明するデザインドキュメント →
theme drawing、ステップの下にshows: id = text、1つの数値が結果を左右する場合はmeter:を追加(描画)。 - 保存、印刷、共有されるページ →
theme paper。独自のシートを描画するため、インラインT3レンダリングはデフォルトテーマを維持します。
すべてを証拠に基づいて記述します。各ノードには @path:line と、読み取り、書き込み、障害動作の詳細行を付けます。各数値(期間、重み、レベル)は、トレース、ログ、クエリ、またはコードから取得します。読み取ったり測定したりしていないものには ? を付けます:ノード、パス、バー、セグメントの先頭に ? を、ストックポイントには # estimate という注釈を入れます。
表示方法
T3 Code(ツールリストに html_render が含まれている場合):ページをそのまま html_preview に書き込み、コンソールで viz: のパースエラーを確認し、同じページを html_render に渡します。viz.js をインライン化しないでください。
<!doctype html><script src="https://cdn.jsdelivr.net/gh/Yeshwanthyk/agent-skills@efe8911d3765b764d7f0bf775e395d5201e29b16/skills/viz/assets/viz.js"></script>
<script type="text/viz">
…
</script>
プレビューコンソールでスクリプトの読み込みに失敗したことが示された場合は、以下のページ(その他の場所)にフォールバックし、そのパスをユーザーに通知します。T3レンダリングで viz.js をインライン化しないでください:呼び出しごとに約55kトークンになります。
その他の場所:データを /tmp/viz/<name>.viz に保存し、python3 <viz>/scripts/viz.py html /tmp/viz/<name>.viz --open を実行します。パースエラーを報告し、レンダラをインライン化した /tmp/viz/<name>.html を書き込み、ブラウザで開きます。glimpse がインストールされた pi では、代わりにそのファイルを開きます(pi)。パスを報告します。
自己完結型で保存されるページ内(ユーザーが保持または共有するページ):ビューが属する場所に text/viz ブロックを書き込み、body の末尾に <script data-viz></script> を追加し、viz.py inline page.html を実行します。viz.js を更新した後は再実行します。ストーリーのキャプション、テーブル行、用語集の項目に data-viz-id="<node id or path name>" を付けると、ホバー時にそのページ上のすべてのグラフの該当部分がハイライト表示されます(ページスクリプトは不要)。
応答
ビジュアルが構造を伝えます。応答では、ビジュアルで表現できないものだけを追加します:検証しなかったこと、および最初に見るべき1つの事項。
完了条件
viz: エラーなしでビジュアルがレンダリングされ、すべてのノードと数値が証拠に基づいているか ? でマークされ、読者が見るであろう場所(T3のインライン、または開かれたページのスクリーンショット)で確認できた場合に完了します。ヘッドレスロード、curl、空のコンソールでの確認は「見た」ことにはなりません。確認できなかった場合は、「レンダリング済み」と言う代わりにその旨を伝えます。