jedipunkz 🚀 のブログ

SRE になるために学んでいくブログです

自作 Go ツールに導入したガードレール策

こんにちは。ジェダイパンくず🚀 です。 以前の記事 Go によるコマンド履歴・ファイル・Git ブランチ/Worktree/コミットを検索する Fish Plugin 開発 で紹介した fuzz.fish は、Fish shell のコマンド履歴・ファイル・Git ブランチなどをファジー検索する Fish plugin です。plugin ですが、検索と TUI の本体は Go で実装していて、Fish 側のスクリプト(conf.d/fuzz.fish)はキーバインドの登録と Go バイナリの呼び出しだけを担っています。このツールを自分で毎日使いながら一人で開発・運用しています。最近はコードの大半を Claude Code や opencode といった AI agent に書いてもらっていて、自分はレビューとマージが中心です。 この開発スタイルで一番気になっていたのは、LLM に何を意識させ続けられるかでした。具体的には次の 4 つです。 セキュリティ: シェルに文字列を渡して実行する箇所や、サプライチェーンに穴を開けないこと バグ混入: 既存の挙動を壊さないこと、テストを減らさないこと パフォーマンス: キー入力のたびに走るフィルタ処理を遅くしないこと 設計思想: パッケージの依存方向や Bubble Tea の Model / Update / View の分担を崩さないこと これらは CLAUDE.md に書いてあります。ただ、プロンプトに書いたルールは守られる保証がありませんし、一度守られても次の変更では忘れられます。チームであれば他のメンバーのレビューで拾えることも、一人だと自分が見落とした時点で main に入ってしまいます。 そこで「ルールは CLAUDE.md で宣言し、違反は linter と CI で機械的に落とす」という方針でガードレールを 17 件 issue 化して実装しました。この記事はその記録です。 方針: 宣言 → 可視化 → gate 化 ガードレールは次の 3 段階で考えました。 ...

2026-10-12 · 8 分 · jedipunkz

Google ADK Go 2.x の Dynamic Workflow とその為のガードレール

こんにちは。ジェダイパンくず🚀 です。 前回の記事 ADK Go 2.0 のグラフワークフローを読んで SRE Agent への応用を考える の最後に、こんな宿題を残していました。 インシデント対応は「調べて、分からなかったらもう少し調べる」という反復が本質なので、完全に静的なグラフでは表現しきれない部分があります。NewDynamicNode で調査ループを書き、確定した対処だけを静的グラフに戻す、というハイブリッドが現実解な気がしていますが、そうすると動的ノードの中身が結局ブラックボックスになるジレンマがあります。 その後、Claude Agent SDK の agent loop や、Claude Code の dynamic workflows を眺めていて、「自律的に、動的に回るループ」を Google の Agent Development Kit(ADK)でやるとどうなるのかが気になりました。結論を先に書くと、ループそのものは ADK でも回せます。ただし止める仕組みは自分で書く必要があります。この記事はその「止める仕組み」、つまりガードレールの話です。 記事中のコードは jedipunkz/adk-playground の investigation-loop にあり、ADK Go v2.5.0(2026-09-30 リリース)で go vet とテストを通しています。 「ループ」は 2 種類ある 最初に整理しておきたいのは、「自律的なループ」と言ったときに 2 つの別のものが混ざりがちだという点です。 Claude 側 ADK Go 側 agent loop(1 エージェントの中で、モデル → ツール → モデルを繰り返す) Claude Agent SDK の query() llmagent オーケストレーションのループ(エージェントを何度も呼び、結果を見て次を決める) Claude Code の dynamic workflows(loop until done パターン) workflow.NewDynamicNode Claude Code の dynamic workflows は、Claude 自身が JavaScript のオーケストレーション用スクリプトを書き、ランタイムがそれをバックグラウンドで実行する機能です。スクリプトの中では agent() でサブエージェントを起動し、parallel() / pipeline() で fan-out します。ループ・分岐・途中結果はスクリプトの変数が持つので、Claude のコンテキストには最終結果しか入りません。 ...

2026-10-12 · 7 分 · jedipunkz

[Go 再学習] Go のテストを理解する 後編: 性能・堅牢性を確かめる

前編 では、テーブル駆動テストからカバレッジまで、コードが正しく動くことを確かめるテストの書き方を整理しました。後編では、正しさ以外のことを確かめるテストを扱います。 性能: ベンチマーク、サブベンチマーク 堅牢性: Fuzzing 時間: testing/synctest 前編と同じく Go 1.27 を前提にしていて、実行結果は Go 1.27.1 で実行したものです。ベンチマークの数値は実行環境によって変わります。 コードは以下のレポジトリにあります。 https://github.com/jedipunkz/go-playground/tree/main/testing パターン9: ベンチマーク func BenchmarkXxx(b *testing.B) という関数を書き、go test -bench で処理時間とメモリ割り当てを計測するパターンです。 使い所 「+ で文字列を連結するより strings.Builder の方が速い」とよく言われますが、自分のユースケースでどれくらい差があるのかは、測ってみないと分かりません。ベンチマークを書いておけば、実装を選ぶときや性能改善をしたときに、効果を数値で確認できます。 テスト対象として、文字列を連結する 2 つの実装を用意しました。 package concat import "strings" // Plus は + 演算子で文字列を連結する func Plus(words []string) string { s := "" for _, w := range words { s += w } return s } // Builder は strings.Builder で文字列を連結する func Builder(words []string) string { var sb strings.Builder for _, w := range words { sb.WriteString(w) } return sb.String() } ベンチマークは for b.Loop() { ... } の中に計測したい処理を書きます。 ...

2026-10-11 · 9 分 · jedipunkz

[Go 再学習] Go のテストを理解する 前編: 正しさを確かめる

Go の再学習を続けています。今回はテストです。テーブル駆動テストやサブテスト、ベンチマークは普段から書いているのですが、それ以外にどんな書き方や機能があるのかを網羅的には把握できていませんでした。そこで標準の testing パッケージ周りを一通り調べ直し、前編・後編の 2 本にまとめることにしました。 前編 (この記事): 正しさを確かめる。テーブル駆動テスト、サブテスト、並列実行、テストヘルパー、テストダブル、httptest、Example テスト、カバレッジ 後編: 性能・堅牢性を確かめる。ベンチマーク、サブベンチマーク、Fuzzing、testing/synctest Go 1.27 を前提にしていて、古いバージョンとの違いには触れません。実行結果は Go 1.27.1 で実行したものです。 コードは以下のレポジトリにあります。 https://github.com/jedipunkz/go-playground/tree/main/testing Go のテストの基本 Go のテストは標準の testing パッケージと go test コマンドだけで書けます。ルールは次の 3 つです。 テストコードは xxx_test.go という名前のファイルに書く テスト関数は func TestXxx(t *testing.T) という形にする 失敗を報告するには t.Error / t.Errorf か t.Fatal / t.Fatalf を呼ぶ t.Error と t.Fatal の違いは重要です。t.Error は失敗を記録してテスト関数の実行を続けますが、t.Fatal は失敗を記録した時点でそのテスト関数を終了します。この違いがパターン 2 の話につながります。 この記事では、次の割り算の関数をテスト対象にして説明を始めます。 package calc import "errors" var ErrDivideByZero = errors.New("divide by zero") // Div は a を b で割った結果を返す func Div(a, b int) (int, error) { if b == 0 { return 0, ErrDivideByZero } return a / b, nil } よく使う go test のオプションは以下です。 ...

2026-10-11 · 12 分 · jedipunkz

AI SRE Agent 評価ベンチマークを読んでみた

こんにちは。ジェダイパンくず☁️ です。 以前 2026年6月現時点において SRE がどう AI に向き合っているか調べてみた や Google が提唱する AI in SRE とは何か で、AI SRE エージェントの動向や Google の評価フレームワークについて書きました。その後 ADK Go 2.0 のグラフワークフローを読んで SRE Agent への応用を考える で、実際にインシデントトリアージのワークフローも書いてみています。 ここまでやってみて、ずっと引っかかっていたのが「で、そのエージェントはどれくらい正しく原因を当てられるの?」という問いです。ベンダーの発表では「MTTR が何割短縮」といった数字がよく出てきますが、その多くは自社インフラ上での自己申告で、横並びで比較できるものではありません。 そこで 2026 年に出た AI SRE エージェント向けの評価ベンチマーク 4 本を読んでみました。 OpenRCA 2.0 ORCA-bench Cloud-OpsBench SREGym 読んでみると、4 本ともアプローチは違うのに、エージェントが間違えるパターンについてはほぼ同じことを言っていて面白かったです。本記事では、各ベンチマークの中身、各論文が挙げる課題と解決策、そして自分で SRE エージェントを作るときに持ち帰れることを整理します。 なお 4 本ともプレプリント (arXiv) で、数値は論文に書かれたものをそのまま引用しています。 4 本の全体像 4 本とも「LLM エージェントは障害の root cause を特定できるか」という同じ問いを扱っていますが、何をエージェントに渡して、何を採点するかが違います。 ベンチマーク エージェントに渡すもの 採点の重点 規模 OpenRCA 2.0 静的なテレメトリ (trace / metrics / log) 答えに加えて、原因から症状までの伝播経路 500 件 ORCA-bench 曖昧なユーザー報告 + Grafana 経由の 6 日分テレメトリ + ソースコード on-call に近い条件で当てられるか 1,079 タスク Cloud-OpsBench 障害時の Kubernetes 状態を固めた snapshot を、診断ツール経由で調査 答えに加えて、必要な証拠を集めたか 754 件 SREGym 動いている Kubernetes 環境 診断に加えて、修復まで完了できるか 90 問 ざっくり言うと、OpenRCA 2.0 と Cloud-OpsBench は「答えが合っていても根拠が伴っているか」を測る方向、ORCA-bench と SREGym は「現実の障害対応にどこまで近づけるか」を測る方向に振っています。 ...

2026-10-11 · 6 分 · jedipunkz

Rust 入門: 構文集

こんにちは @jedipunkz です。 自作ツールの gm を Go から Rust に書き換えたことをきっかけに、Rust の構文を網羅的に理解する必要性を感じてサンプルコードを作成し動作確認した上で構文集を作成しました。この記事では Rust の主要な構文をまとめたいと思います。 サンプルコードは Rust 1.98 / Edition 2024 で動作確認しています。各コードは fn main() を含む単体のプログラムなので、rustc --edition 2024 main.rs でそのまま実行できます (非同期の節のみ tokio クレートを使います)。 ※ 気が向いたときに新しい構文が出てきた際に更新し続ける記事にしようと思っています。 目次 1. 基本的な型システム スカラー型 変数と可変性 型注釈と型推論 型変換 型エイリアス 2. 複合型 タプルと配列 文字列 構造体 列挙型 Option と Result 3. 制御フロー 条件分岐とループ パターンマッチ if let と let else と let チェーン 4. 所有権と借用 所有権とムーブ 参照と借用 ライフタイム 5. 関数とクロージャ 関数の定義 クロージャ 6. メソッドとトレイト impl ブロック トレイトの定義と実装 スーパートレイトとトレイトオブジェクト derive と標準トレイト 演算子オーバーロード 7. ジェネリクス ジェネリクスの基本 トレイト境界 関連型と const ジェネリクス 8. エラーハンドリング 独自のエラー型と ? 演算子 main から Result を返す 9. コレクションとイテレータ Vec HashMap と HashSet イテレータ 独自のイテレータ 10. スマートポインタ Box と Rc と RefCell 11. 並行処理と非同期 スレッド async と await 12. モジュール モジュールと可視性 クレートと Cargo 13. 高度な機能 マクロ 属性 テスト unsafe 基本的な型システム Rust は静的型付け言語で、すべての値の型がコンパイル時に決まります。型推論が強力なため、多くの場合は型を書かずに済みます。 ...

2026-09-25 · 34 分 · jedipunkz

ghq の気になる点を改善した Rust 製ツール開発

jedipunkz🚀 です。 今回は自作した ツール gm を紹介します。 gm は ghq と同じくリポジトリを clone して管理するツールです。違うのは Fuzzy Finder を内蔵していることと、clone だけでなく Git Worktree も同じ画面から扱えることです。ブランチや Pull Request を選べば、その場で Worktree を作って移動します。Ctrl-G を押すと Finder が開き、選んだリポジトリまたは Worktree に cd します。またランク機能を設けて頻繁にアクセスするレポジトリを優先的に選択するようにしています。 最初は Go (Bubble Tea) で書いていましたが、PR #83 で挙動を変えずに Rust (ratatui) へ書き換えました。gm.toml・訪問記録・ディレクトリ構成は互換なので、Go 版から入れ替えてもそのまま動きます。 リンク ソースコード: https://github.com/jedipunkz/gm 公式サイト: https://jedipunkz.rocks/gm/ Finder の画面 左がリポジトリ一覧、右が選択中のリポジトリの詳細、下が入力欄とキーの案内です。詳細には path・remote・ブランチ・作業ツリーの状態・訪問回数・直近 3 コミットが出ます。最有力候補は入力欄のすぐ隣、一覧の一番下に置いています。入力欄の右端の箱には、いま絞り込んでいる一覧の名前 (repository / worktree / branch / pr) が出ます。 (公式サイトに置いてあるモックです) 開発動機 普段の作業で ghq を頻繁に使っています。長く使っていて不満はほとんど無かったのですが、2点だけ引っかかるなと気が付きました。 1 つは頻繁にアクセスするレポジトリに似た名前のレポジトリがあるとそちらが起動直後に選択されて ctrl-n/p で移動して毎回アクセスしていました。毎日多用してるのでこの作業無駄では・・と考えるようになりました。 もう 1 つは Git Worktree です。最近は 1 つのリポジトリに対して複数の Worktree を切って作業することが増えました。以前作った agx も Worktree 前提のツールです。しかし ghq は Worktree にはアクセスが出来ないので、Worktree への移動だけは別の手段を用意することになっていました。これも以前作った fuzz.fish で Worktree にアクセスしていたのですが、これはレポジトリに移動した後に利用できるツールです。なので ghq を起動してその流れで Worktree にアクセスしたい!という要望が出てきました。 ...

2026-09-23 · 6 分 · jedipunkz

Claude Agent SDK の基本的な使い方を学ぶ

こんにちは。ジェダイパンくず☁️ です。 Claude Agent SDK を触ってみたので、基本的な使い方と主要な機能を整理しました。この SDK は Claude Code 本体をライブラリとして使えるようにしたもので、agent loop・組み込みツール・コンテキスト管理・権限制御が最初から入っています。自分でツール呼び出しのループを書く必要がありません。 この記事で使ったコードは下記に置いてあります。 https://github.com/jedipunkz/claude-agent-sdk-playground 検証に使ったバージョンは @anthropic-ai/claude-agent-sdk v0.3.278 です。この SDK は Claude Code のネイティブバイナリを同梱していて、バージョンは Claude Code 側に追従します。 どれを使うべきか Claude 関連で「エージェントを作る」手段が複数あって最初に混乱したので、先に整理しておきます。 手段 何をしてくれるか ホスティング Claude Code CLI 対話的な日常利用。-p でヘッドレス実行も出来る 自分 Client SDK (@anthropic-ai/sdk) API を直接叩く。ツールのループは自分で書く 自分 Tool Runner (client.beta.messages.tool_runner) 自分で定義したツールのループだけ回してくれる 自分 Claude Agent SDK Claude Code のハーネスまるごと。組み込みツール付き 自分 Managed Agents Anthropic がループとサンドボックスをホストする Anthropic 名前が紛らわしいのは Tool Runner と Agent SDK です。Tool Runner は Anthropic SDK 側の機能で、組み込みツールもファイルアクセスも持ちません。自分が定義したツールを呼ぶループを代わりに回してくれるだけのものです。対して Agent SDK は Read / Write / Edit / Bash / Grep / Glob / WebSearch といったツールを最初から持っていて、実体は Claude Code そのものです。 ...

2026-09-19 · 7 分 · jedipunkz