TECH PLAY

サイオステクノロジー(Tech.Lab)

サイオステクノロジー(Tech.Lab) の技術ブログ

601

ども!龍ちゃんです。 前回の記事 では Draw.io の公式 MCP Tool Server を検証しました。しっかり動くし、Mermaid 入力のトークン効率もよかったのでぱっと使う分には良かったですね。問題があったんでブログを書いているんですけどもwww 今回の内容です。 MCP Tool Server の問題 — ファイルが残らない Skill + VS Code 拡張機能のセットアップ VS Code 内で完結する作業の流れ(生成 → プレビュー → 編集 → エクスポート → Git 管理) MCP Tool Server との比較と使い分け Mermaid / PlantUML も含めた図解ツール全体の選び方 MCP Tool Server の問題: 設計図が Git 管理できない 検証していて問題になったことがあります。 Draw.io で描く図って、設計情報なんですよね。アーキテクチャ図、シーケンス図、フロー図。どれもシステムの設計を表現したもので、ソースコードと同じように GitHub に置いてバージョン管理したい。PR でレビューもしたい。 ところが MCP Tool Server は URL 方式です。図を生成すると app.diagrams.net の URL が返ってきて、ブラウザで開く。図のデータは URL に埋め込まれているだけで、手元にファイルが残らない。git add できるものがないんですよね。 MCP が悪いわけじゃないです。ブラウザで図を確認・共有する用途は十分見たいしてます。Slack に URL を貼れば相手もすぐに見られるし、受け取り側に環境も要らない。ただ、設計情報を Git で管理するという用途には合わないだけですね。 同じ jgraph/drawio-mcp リポジトリに、 .drawio ファイルをローカルに生成するアプローチがあります。これと VS Code の Draw.io 拡張機能を組み合わせると、生成からプレビュー、手動編集、エクスポート、Git 管理まで VS Code の中で完結するので、そちらの検証結果をブログにまとめています。 Skill + 拡張機能のセットアップ やることは2つだけです。Skill 定義ファイルを1つと VS Code の拡張機能を1つ追加する。MCP サーバーの起動も Node.js も要りません。 Skill のセットアップ jgraph/drawio-mcp リポジトリの skill-cli/SKILL.md を取得して、プロジェクトに配置します。 mkdir -p .claude/skills/drawio curl -sL https://raw.githubusercontent.com/jgraph/drawio-mcp/main/skill-cli/SKILL.md \ > .claude/skills/drawio/SKILL.md これだけです。MCP のように .mcp.json に設定を書いたり、 npx でサーバーを起動したりする必要はありません。 VS Code 拡張機能の追加 .drawio ファイルを VS Code で開けるようにするために、Draw.io の拡張機能を追加します。 devcontainer を使っている場合は devcontainer.json に追加するだけです。 { "customizations": { "vscode": { "extensions": [ "hediet.vscode-drawio" ] } } } ローカル環境なら VS Code のマーケットプレイスから hediet.vscode-drawio をインストールしてください。 この拡張機能を入れると、 .drawio ファイルを開いたときに VS Code 内に GUI エディタが表示されます。ドラッグ&ドロップで図形を動かしたり、色を変えたり、接続線を引いたりできます。ブラウザの draw.io と同じ操作感です。 PNG や SVG へのエクスポートも、この拡張機能のメニューから手動でできます。draw.io の CLI ツールは要りません。 なぜ「CLI」ではなく「拡張機能」なのか jgraph/drawio-mcp のリポジトリでは、このアプローチを「Skill + CLI」と呼んでいます。ここでいう CLI は draw.io のデスクトップアプリをコマンドラインで使うエクスポート機能( drawio -x -f png ... )のことです。 ただ、devcontainer 環境でこの CLI を動かそうとすると面倒なんですよね。draw.io のデスクトップアプリは Electron ベースなので、ヘッドレス環境で動かすには xvfb と大量の X11 依存パッケージが必要になる。Docker イメージが 500MB くらい膨らみます。 VS Code の Draw.io 拡張機能なら、devcontainer.json に1行追加するだけで済みます。プレビュー、編集、エクスポートが全部揃います。 devcontainer 環境での現実解は Skill + 拡張機能 です。 VS Code で完結する作業の流れ セットアップが終わったら、実際の作業の流れを見ていきましょう。ブラウザを開かずに、VS Code の中だけで図の生成から Git 管理まで完結します。 生成 → プレビュー → 編集 → エクスポート → Git 管理 流れはこうなります。 Claude Code に指示 → .drawio ファイル生成 → VS Code でプレビュー(Draw.io 拡張が自動で開く) → GUI で手動微調整(色・配置・接続) → 拡張機能から PNG/SVG にエクスポート → git add → commit → push 実際に Claude Code に指示するときはこんな感じです。 ログイン処理のフローチャートを .drawio で作って。 開始 → メールアドレス入力 → パスワード入力 → 認証API呼び出し → 成功/失敗の分岐 → 完了 特別なコマンドは要りません。 .drawio で作って と言えば、Skill の定義を参照して .drawio ファイルを生成してくれます。フローチャートに限らず、アーキテクチャ図やシーケンス図も同じように自然言語で指示するだけで作れます。 AI 生成 + 手動仕上げ Claude が生成する .drawio ファイルは、そのまま使えるレベルではあります。ノードの配置も接続も合っている。ただ、色やレイアウトの微調整は人間が GUI でやったほうが速いんですよね。 ここが Mermaid や PlantUML との大きな違いです。テキストベースのツールだと、色を変えたければソースコードを編集して再レンダリングする。Draw.io なら GUI で直接ドラッグして色を塗れば終わりです。Figma を触る感覚に近いです。 AI が 80% の構造を作って、人間が 20% の見た目を GUI で仕上げる。このハイブリッドが .drawio ファイルとして Git にコミットされるのが、この流れのポイントです。 GitHub での管理 .drawio ファイルは Git にそのままコミットできます。バージョン管理される。ブランチを切って PR でレビューもできる。 設計情報を Git 管理する最大のメリットは、PR で図をレビューできることです。設計変更があったら図も一緒に PR に含めて、レビュアーが確認できる。ただ、ここで1つ問題があります。 GitHub は .drawio ファイルをレンダリングしません。リポジトリ上で開くと生の XML が表示される。これだと PR を開いてもレビュアーは図が見られないんですよね。 解決策が .drawio.svg 形式です。VS Code の拡張機能から SVG にエクスポートすると、SVG の中に Draw.io の XML が埋め込まれます。GitHub 上では画像として表示されるので、PR でレビュアーが図を確認できる。しかも draw.io で開けば再編集もできます。 .drawio ファイル(編集用ソース)と .drawio.svg (GitHub 表示・レビュー用)の両方をコミットしておくのがおすすめです。 CI で自動変換したい場合は render-drawio-action も選択肢に入ります。 MCP vs Skill の比較 ここまで Skill + 拡張機能のセットアップとワークフローを見てきました。じゃあ MCP Tool Server はもう要らないのかというと、そんなことはないです。用途が違うだけなんですよね。 比較表 比較項目 MCP Tool Server Skill + 拡張機能 出力 URL → ブラウザで確認 .drawio ファイル → VS Code で確認 Git 管理 できない(ファイルが残らない) できる(.drawio をコミット) 入力フォーマット XML / Mermaid / CSV XML のみ コンテキスト消費 3ツール分の定義が常に載る 使うときだけ読み込まれる(普段はゼロ) 編集環境 ブラウザ(app.diagrams.net) VS Code 内 オフライン 初回ダウンロード後は可能 完全オフライン対応 セットアップ .mcp.json + Node.js SKILL.md 1つ + 拡張機能 エクスポート ブラウザから手動 拡張機能から手動 Mermaid 入力に対応しているのは MCP だけです。Mermaid はトークン効率が良くて、XML の 1/10 くらいで同じ図を表現できる。フローチャートで比べると、XML だと約 800 トークンかかるところが Mermaid なら約 100 トークンで済みます。 逆に、Git 管理ができるのは Skill + 拡張機能だけです。ここは明確に分かれます。 どちらを選ぶか 判断はシンプルです。 Git で管理したい → Skill + 拡張機能。これ一択 Mermaid から変換したい → MCP Tool Server URL を共有して相手にすぐ見せたい → MCP Tool Server VS Code の中で完結したい → Skill + 拡張機能 両方使い分けたい → 併用できる。同じリポジトリの別アプローチなので競合しない 僕の場合は、設計情報を GitHub で管理するのが前提なので Skill + 拡張機能をメインで使っています。Mermaid から Draw.io に変換したいときだけ MCP を使う、という使い分けですね。 全ツールの使い分け — Draw.io だけで考えない Draw.io の話をしてきましたが、図を作るツールは Draw.io だけじゃないです。Mermaid、PlantUML、HTML ベースの図解もある。目的に合わせて選ぶのが大事なんですよね。 Draw.io の立ち位置 Draw.io の強みは GUI で直感的に編集できることです。AI が生成した図をそのままドラッグして色を塗って形を変えられる。Mermaid や PlantUML だとソースコードを書き換えて再レンダリングしないといけないけど、Draw.io ならマウスで触るだけです。 デザインの自由度も段違いで、色、形状、アイコン、グラデーション、何でもいける。素の Mermaid / PlantUML だと見た目の調整に限界があって、 Mermaid を Tailwind で拡張する記事 と PlantUML を Tailwind で仕上げる記事 を書いたくらいなんですよね。Draw.io ならそもそもその問題が起きません。 ただ弱点もあります。 Git diff が見づらい : .drawio の中身は XML なので、diff を見ても座標やスタイル情報が大量に出てきて、何が変わったのかわかりにくい。Mermaid や PlantUML はテキストベースだから diff がきれいに出る GitHub でレンダリングされない : さっき書いた通り、 .drawio のままだと生 XML が表示される。 .drawio.svg で回避はできるけど、ひと手間かかる 使い分け表 ユースケース 推奨ツール 理由 ブログ記事のフロー図・概念図 HTML + Mermaid / PlantUML PNG が直接出る。テキストで完結 テキスト管理したい仕様書の図 Mermaid / PlantUML diff がきれい。テキストで完結 デザインにこだわりたい図 Draw.io(Skill + 拡張機能) GUI 編集、デザイン自由度が高い Mermaid / CSV からの変換 Draw.io MCP 変換に対応しているのはこれだけ URL を貼って即共有 Draw.io MCP リンク1つで相手が見られる ブログ記事の図を作るだけなら、正直 HTML + Mermaid で作る図解 や PlantUML で作る図解 のほうが手軽です。PNG が直接出てくるし、テキストだけで完結する。 Draw.io が活きるのは「デザインにこだわりたい」か「GUI で編集したい」場面です。設計書に載せる図とか、お客さんに見せる図とか、見た目が大事な場面ですね。 判断フロー 迷ったらこの流れで考えるとすっきりします。 仕様書の図はAIに読ませるな — 軽量コードを添える設計パターン や 図解作成、AIに丸投げしたら「たまに自分より上手い」件 も合わせて読むと、図解ツール全体の使い分けが見えてくると思います。 まとめ Draw.io で描く図は設計情報です。設計情報なら GitHub で管理したい。MCP Tool Server は URL 方式で図が手元に残らないから、Git 管理には向かない。 だから Skill + VS Code 拡張機能を使う。SKILL.md を1つ置いて、devcontainer.json に拡張機能を1行追加する。これで .drawio ファイルの生成からプレビュー、GUI 編集、エクスポート、Git 管理まで VS Code で完結します。 MCP Tool Server が使えないわけじゃないです。Mermaid 変換や URL 共有には MCP のほうが向いている。同じリポジトリに両方のアプローチが用意されているのは、用途が違うからなんですよね。 ツールは目的で選ぶ。Git 管理が要るなら Skill + 拡張機能、共有が要るなら MCP。テキスト管理や diff 重視なら Mermaid / PlantUML もある。全部を1つで解決しようとしないで、場面に合わせて使い分けるのがいいんじゃないかなと思います。 ほなまた〜 関連ブログ Draw.io MCP シリーズ 前回の記事: Draw.io 公式 MCP でできること・セットアップガイド — MCP Tool Server のセットアップと Mermaid / CSV 入力の検証結果をまとめた記事です MCP と Skills の使い分け Claude Code MCP が遅い・重い問題、CLI + Skills で解決 — Notion・Playwright MCP の接続・トークン問題を CLI + Skills 移行で軽量化した話。今回の「用途の適合性」とは別の切り口です Claude Code: 公式MCPを補完するSkills設計パターン — 公式 MCP の不足機能を Skills で補完する設計パターン。MCP → CLI → Skill の判断基準を整理しています AI × 図解作成 図解作成、AIに丸投げしたら「たまに自分より上手い」件 — Claude Code Skill で HTML 図解を自動生成 → PNG 変換する流れ。気に入ったデザインを蓄積して AI のスキルを育てる方法も紹介 ClaudeでMermaid図作成を自動化!2時間→5分の劇的時短術 — Claude + Mermaid でフローチャートやシーケンス図を自動生成。Live Editor の活用術と日本語フォントの対処法 Claude Codeで仕様書のPlantUML図を自動生成 — PlantUML の各種図を Claude Code で自動生成し、VS Code Preview で確認する環境構築と実践例 仕様書の図はAIに読ませるな — 軽量コードを添える設計パターン — Mermaid / PlantUML のソースコードと設計意図を HTML コメントで添える設計パターン。AI が推測ではなく正確に読める形式にする方法 図解のデザイン強化 Mermaidのデザインが物足りない?Tailwindで拡張して設計書品質に — Mermaid 図に Tailwind CSS の注釈パネルを組み合わせて設計書品質にアップグレード。PNG 変換手段とテンプレートも紹介 PlantUMLの表現力をTailwind CSSで設計書品質に仕上げる — PlantUML + Tailwind CSS で設計書品質を実現。skinparam 設定と2つのレイアウトテンプレート ご覧いただきありがとうございます! この投稿はお役に立ちましたか? 役に立った 役に立たなかった 0人がこの投稿は役に立ったと言っています。 The post Draw.io公式Skillで設計図をGitHub管理 — VS Code完結のセットアップ first appeared on SIOS Tech Lab .
アバター
ども!最近は仕様書×AIの文脈で図解まわりの検証をやってる龍ちゃんです。 Draw.io の開発元である jgraph 社が、公式の MCP サーバーを出しました。 jgraph/drawio-mcp リポジトリで Apache 2.0 ライセンスで公開されています。 コミュニティ実装の MCP サーバーはいくつかありましたが、公式となると話が変わってきます。draw.io 本体と同じ開発元が直接メンテしてくれるので、コミュニティ版よりも長くメンテされやすいんですよね。 MCP の基本的な仕組みについては「 AIエージェントの進化が分からない?秘書で理解する3段階 」で解説しているので、「MCPってなに?」という方はそちらを先にどうぞ。 jgraph/drawio-mcp リポジトリ、中を見てみると実は4つのアプローチが入っていて、それぞれ対象環境や出力形式が異なります(全体像は後半で紹介します)。 この記事では、Claude Code ユーザーに一番スタンダードな MCP Tool Server を試していきます。セットアップ方法、3つの入力フォーマット(Mermaid / XML / CSV)の使用感、そして正直「できないこと」まで、検証した結果をまとめました。 今回の内容です。 MCP Tool Server のセットアップ( .mcp.json に数行追加するだけ) 3つの入力フォーマットを実際に試した比較 MCP Tool Server の「できないこと」を正直に語る 向いている人・向いていない人の判断材料 龍ちゃん できないことを紹介していますが、それの対処法に関しては「 Draw.io公式Skillで設計図をGitHub管理 — VS Code完結のセットアップ 」で紹介しています。併せてご一読ください! セットアップ: .mcp.json に数行追加するだけ Claude Code なら、ターミナルで以下のコマンドを実行するだけ。 claude mcp add -s project drawio -- npx @drawio/mcp これで .mcp.json が自動で作られます。手動で書く場合はこう。 { "mcpServers": { "drawio": { "type": "stdio", "command": "npx", "args": ["@drawio/mcp"] } } } 前提として Node.js が必要です(npx を使うので)。検証時の環境は Node.js v25.7.0、npm パッケージ @drawio/mcp v1.1.2 でした。 以前 MCP のトークン消費問題について記事を書いた んですが、draw.io MCP はツール定義が3つしかないので、コンテキストへの負担はかなり軽い部類です。Notion MCP みたいに大量のツールが常駐するタイプとは全然違います。 使えるようになる3つのツール ツール 入力 用途 open_drawio_mermaid Mermaid.js 構文 フローチャート・UML 全般 open_drawio_xml draw.io XML(mxGraphModel) 細かいスタイル制御が必要な図 open_drawio_csv draw.io CSV インポート形式 データ駆動の組織図・ツリー どのツールも lightbox (読み取り専用モード)と dark (ダークモード)のオプションが付いています。 設定はこれだけで、すぐに使い始められます。 使ってみた: 3つの入力フォーマット Mermaid で図を生成 まずは Mermaid から。Claude Code に「ロードバランサー構成図を Mermaid で描いて」とお願いしてみました。 すると Claude が Mermaid 構文を生成して、MCP ツール経由で draw.io に渡してくれます。数秒後にブラウザがパッと開いて、draw.io のエディタに図が表示されました。 これ、良いですね。Mermaid の構文自体がシンプルなので、5ノード程度の図なら入力トークンは約100程度で済みます。しかも Mermaid エンジンが自動レイアウトしてくれるので、ノードが重なったり変な配置になったりしない。ノード数が増えても構文が簡潔なぶん、トークン消費は抑えられます。 ブラウザで開いた draw.io エディタ上で、色やフォントを変えたりノードの位置を微調整したりもできます。AI が下書きして、人間が仕上げる感じですね。 XML で図を生成 次に XML。同じ構成図を XML フォーマットで試してみます。 XML だと draw.io の全プロパティを指定できるので、ノードの色、枠線のスタイル、フォントサイズまで細かく制御できます。Mermaid ではテーマに依存する部分も、XML なら自由自在。 ただし、トレードオフがあります。 同じ図を表現するのに XML は約800トークン使います。Mermaid が約100トークンだったので、ざっくり8倍。さらに、AI がノードの座標(x, y)を自分で計算して配置するので、レイアウトが微妙になることもあります。Mermaid なら自動でいい感じに並べてくれるのに、XML だとそこは AI 任せなんですよね。 トークンもレイアウトも Mermaid に分がありますが、「この色で、このフォントで、この位置に」って指定したいなら XML 一択です。 CSV で図を生成 最後に CSV。これは少し特殊で、draw.io 固有の CSV インポート形式に従う必要があります。 CSV ヘッダーに # label: %name% のようなメタ記法を書いて、データ行で親子関係を定義していく形式です。ツリー構造や組織図を作るには向いてるんですが、ただ汎用性はあまり高くないので、フローチャートや UML を CSV で書こうとは思わないですね。 フォーマット比較 3つ試した結果をまとめます。 比較項目 Mermaid XML CSV トークン効率 高(XML の約 1/10) 低(冗長) 中 レイアウト 自動 手動(AI が座標指定) 自動 スタイル制御 低(テーマ依存) 高 中 対応図形 flowchart, sequence, class, state, ER 等 全て ツリー・組織図 結論としては、特別な理由がなければ Mermaid を使うのが正解 です。トークン効率が XML の約 1/10、自動レイアウトで配置も綺麗、対応する図形タイプも広い。XML は「どうしても色やスタイルを細かく指定したい」ときの選択肢。CSV は組織図やツリーを大量のデータから生成したいときのニッチ枠です。 正直に言う: MCP Tool Server の「できないこと」 ここまで「Mermaid いいじゃん」って話をしてきましたが、MCP Tool Server には正直「できないこと」も結構あります。 まず仕組みを知っておく さっき Mermaid で図を生成したとき、ブラウザがパッと開きましたよね。あれ、実はローカルにファイルを作ってるわけじゃないんです。 MCP Tool Server は、AI が生成したコンテンツを圧縮・エンコードして app.diagrams.net の URL に全部詰め込んでいます( ソースコード )。その URL をブラウザで開くと draw.io エディタが表示される、という仕組みです。 つまり すべてが URL に埋め込まれている 。ローカルにファイルは一切残りません。 この「URL 方式」が、以下の制約の根本原因です。 できないこと 一番大きいのは、 ローカルにファイルが残らない ことです。 .drawio ファイルが生成されないので、Git で管理したり、VS Code の Draw.io 拡張で開いたりができません。 これに連動して、VS Code 内で作業を完結させることもできません。図を確認するにはブラウザに切り替える必要があるし、PNG や SVG が欲しければ draw.io エディタから手動でエクスポートする手間が発生します。GitHub に図を置きたい場合も、URL からは .drawio ファイルを取り出せないので、リポジトリ管理のワークフローとは噛み合わない。 もう1つの本質的な制約は、 差分更新ができない こと。URL は毎回まるごと新規生成されるので、「さっきの図のここだけ修正して」ということができません。修正するには図全体を再生成するか、ブラウザの draw.io エディタ上で手動で直す必要があります。 あとは環境面の話で、 app.diagrams.net に接続できないとそもそも動きません。オフラインでは使えないです。 一方で、URL だからこそ便利な面もある URL をそのまま Slack やチャットに貼れば、相手がブラウザで即座に図を見られます。受け取る側に draw.io のインストールは不要で、ブラウザさえあれば OK。しかも URL を開いた先の draw.io エディタでそのまま編集もできるんですよね。 ファイルを共有してもらって、ツールを入れて、開いて…みたいな手間がゼロ。検証で 27ノードのマイクロサービス構成図を作ったときも、URL 長は 1851 文字でブラウザの制限内に収まっていました。 jgraph/drawio-mcp の4つのアプローチ ここまで MCP Tool Server を試してきましたが、 jgraph/drawio-mcp リポジトリには4つのアプローチが用意されています。 アプローチ 対象環境 出力形式 MCP 必要 MCP Tool Server Claude Code, Cursor 等 URL → ブラウザで draw.io を開く ○ MCP App Server Claude Desktop 等 チャット内にインライン描画 ○ Skill + CLI Claude Code .drawio ファイルをローカル生成 × Project Instructions Claude Project Python コード実行で URL 生成 × 「MCP サーバー」と聞くと1つのツールを想像しますが、対象環境と用途に応じて手段が分かれています。MCP Tool Server と MCP App Server は MCP 対応クライアントが必要で、Skill + CLI と Project Instructions は MCP なしで動作します。 まとめ: 向いている人・向いていない人 Draw.io 公式 MCP Tool Server、使い所を選べば便利だけど万能ではない、というのが正直な感想です。 向いていない人 を先に挙げておきます。 VS Code で作業を完結させたい .drawio ファイルをローカルで管理したい GitHub リポジトリに図を保存したい 向いていない人向けには、上で紹介した Skill + CLI が選択肢になります。MCP なしで .drawio ファイルをローカルに生成できるので、VS Code + Git のワークフローに乗せられます。次回の記事で Skill + CLI のセットアップと MCP Tool Server との比較をやっていく予定です。 逆に、 向いている人 はこういう方です。 ブラウザで draw.io を使い慣れている Mermaid で図を書きたい(トークン効率が圧倒的) セットアップを最小限にしたい( .mcp.json に数行追加するだけ) URL を Slack やチャットで共有したい 最後にもう1つ。Draw.io は Mermaid や PlantUML とは違って GUI エディタなので、AI が生成した図を人間がブラウザ上で手で仕上げるワークフローが成立します。テキストベースのツールだと AI の出力がそのまま最終成果物になりがちですが、draw.io なら色・配置・形状を自由に調整できる。この「AI が 80% 作って、残りを人間が仕上げる」感覚は、他のダイアグラムツールにはないものでした。 ではまた! 関連ブログ MCP と Skills の使い分け Claude Code MCP が遅い・重い問題、CLI + Skills で解決 — Notion・Playwright MCP の接続・トークン問題を CLI + Skills 移行で軽量化した話。MCP のパフォーマンス面の課題と解決策を扱っています Claude Code: 公式MCPを補完するSkills設計パターン — 公式 MCP の不足機能を Skills で補完する設計パターン。MCP → CLI → Skill の判断基準を整理しています AIエージェントの進化が分からない?秘書で理解する3段階 — MCP の基本的な仕組みを秘書の比喩で解説。「MCP ってなに?」という方向けの入門記事です AI × 図解作成 図解作成、AIに丸投げしたら「たまに自分より上手い」件 — Claude Code Skill で HTML 図解を自動生成 → PNG 変換する流れ。気に入ったデザインを蓄積して AI のスキルを育てる方法も紹介 ClaudeでMermaid図作成を自動化!2時間→5分の劇的時短術 — Claude + Mermaid でフローチャートやシーケンス図を自動生成。Live Editor の活用術と日本語フォントの対処法 Claude Codeで仕様書のPlantUML図を自動生成 — PlantUML の各種図を Claude Code で自動生成し、VS Code Preview で確認する環境構築と実践例 仕様書の図はAIに読ませるな — 軽量コードを添える設計パターン — Mermaid / PlantUML のソースコードと設計意図を HTML コメントで添える設計パターン。AI が推測ではなく正確に読める形式にする方法 ご覧いただきありがとうございます! この投稿はお役に立ちましたか? 役に立った 役に立たなかった 0人がこの投稿は役に立ったと言っています。 The post Draw.io公式MCPでできること・できないこと — 3フォーマット比較 first appeared on SIOS Tech Lab .
アバター
サイオステクノロジーのひろです。今回はAzureOpenAIを使用したFunctionCallingについて解説していきます。 このブログのゴール FunctionCallingとは何かわかる AzureOpenAIモデルを使用したFunctionCallingの実装方法がわかる FunctionCallingとは FunctionCallingはLLMに関数を使わせることができる機能です。 関数は予め作成しておく必要がありますが、このFunctionCallingを使用することで、LLMができることを拡張することが可能です。 例えば、LLMは文章の生成が可能で、様々な質問に回答してくれます。しかしなんでも正しい答えを教えてくれるわけではなく、最新の情報(例えば今日の天気等)やクローズドな情報には回答できません。 しかしながら、最新の情報を検索して取得する関数や、データベースを検索してクローズドな情報を取得する関数を用意し、FunctionCallingによってLLMに関数を使用させれば、回答させることも可能になります。 さらにそれどころではなく、外部APIを操作する関数を実行させればGoogleカレンダーへのイベント登録やメール送信も可能ですし、ロボットを動作させる関数を実行させれば現実へ干渉させることも可能になります。 組み合わせ次第で新たな価値を生み出すことができるかもしれません。 FunctionCallingでできることについて理解していただけたでしょうか。 ここから具体的な内容に入っていきたいと思います。 FunctionCallingのシーケンス どのようにLLMが関数を実行するかというと、以下のシーケンス図を見ていただければと思います。 まず、アプリケーションからLLMに対して使用可能な関数とプロンプトを渡します。 次に、LLMはプロンプトに沿って独自にどの関数を使用すべきか判断し、アプリケーションへ関数の呼び出しをリクエストします。 実行する関数を教えてもらったアプリケーションは関数を実行し、実行結果をLLMに渡します。 最終的に、LLMが実行結果をもとに回答を生成します。 このような流れでFunctionCallingが行われます。 最終的な回答を生成するまでに必要な情報が足りない場合は複数の関数を実行させることもあります。 例えば、「八王子の天気と現在時刻を教えて」とプロンプトを投げたとします。 その場合、FunctionCallingは並列で2つの関数(天気取得関数と時刻取得関数)を実行して回答します。 また、アプリケーション側で、最終的な回答がされるまでツールの実行を続ける実装を行った場合、LLMが続けて関数を実行できます。 例えば、「天気情報を取得してそれを表にまとめて」とプロンプトを投げたとします。 その場合、1回目のFunctionCallingで天気情報を取得し、2回目に表を操作する関数を使って天気情報を書きこむ等といった処理が可能になります。 生成AIが行っているのは関数と引数を渡すことのみで、関数の実行はアプリケーション側で行います。そのため、アプリケーション側でLLMから渡される関数と引数を読み取って、関数を実行する機能を実装する必要があります。 FunctionCallingの説明については以上です。 続いてAzure OpenAIにおけるFunctionCallingについて解説していきます。 Azure OpenAIのFunctionCalling Azure OpenAIのFunctionCallingは、APIを叩く際のパラメータとして、toolsとtool_choiceを追加することで可能になります。 Azure OpenAIモデルのデプロイ方法は こちら のブログで解説しております。 以下にサンプルコードを記載しています。また、サンプルコードは こちら のリポジトリで公開しています。実行方法をreadmeに記載しているのでクローンして是非試してみていただければと思います。 まずは今回FunctionCallingで使用する関数を作成しましょう。 今回非常に簡易的な、辞書型で値を返す関数を2つ作成します。 サンプルコード Python import datetime def current_time(location: str): # 簡易的に現在時刻を送信 current_time = datetime.now().strftime("%Y-%m-%d %H:%M:%S") return { "current_time": current_time, "timezone": location, } def current_weather(location: str): # ダミーの天気データを返す return { "location": location, "temperature": 15, "description": "晴れ", } 今回作成した関数では、地域名を引数として、疑似的にその地域の現在時刻を返す関数と天気情報を返す関数を作成しました。これらの関数をFunctionCallingで実行していきます。 次にFunctionCallingで渡すツールについてです。 渡すツール定義のJSONは以下のようになっています。 JSON { "type": "function", "function": { "name": "関数名", "description": "関数の説明(生成AIがこの説明を読んで関数を実行するか判断します)", "parameters": { "type": "object", "properties": { "【引数名】": { "type": "データ型(string, integer, booleanなど)", "description": "引数の説明" }, }, "required": [ "必須の引数名", ] } } } 関数名と関数の説明、引数の説明や引数のデータ型を定義して渡します。 ツール定義はJSONをそのまま記述すると量が多く、メンテナンスし辛いことがあるため、今回はPythonのライブラリであるPydanticを使用します。これにより、メンテナンスし易くなるだけでなく、後ほど引数のバリデーションに使用することができます。 以下はサンプルコードです。 Python from pydantic import BaseModel, Field from typing import Dict, Any class WeatherArgs(BaseModel): """get_current_weather関数の引数モデル""" location: str = Field( ..., description="天気情報を取得したい都市名(日本語)。例: '東京'", ) class TimeArgs(BaseModel): """get_current_time関数の引数モデル""" location: str = Field( ..., description="時刻を取得したい都市名(日本語)。例: '東京', 'ニューヨーク'", ) class FunctionSchemaManager: """複数の関数スキーマを管理するクラス""" @staticmethod def get_weather_tool() -> Dict[str, Any]: """天気取得ツールのスキーマ""" return { "type": "function", "function": { "name": "current_weather", "description": "指定された都市の現在の天気情報を取得します", "parameters": WeatherArgs.model_json_schema(), }, } @staticmethod def get_time_tool() -> Dict[str, Any]: """時刻取得ツールのスキーマ""" return { "type": "function", "function": { "name": "current_time", "description": "指定された都市の現在時刻を取得します", "parameters": TimeArgs.model_json_schema(), }, } @staticmethod def get_all_tools() -> list[Dict[str, Any]]: """利用可能な全てのツールを返す""" return [ FunctionSchemaManager.get_weather_tool(), FunctionSchemaManager.get_time_tool(), ] descriptionには引数の例を入れておくことで正しい引数が期待できます。 最後にFunctionCallingを行う部分のサンプルコードです。 Python import os import json from openai import AzureOpenAI from dotenv import load_dotenv from schemas import FunctionSchemaManager, TimeArgs, WeatherArgs from functions import current_time, current_weather # .envファイルから環境変数を読み込み load_dotenv() api_key = os.getenv("AZURE_OPENAI_API_KEY") endpoint = os.getenv("AZURE_OPENAI_ENDPOINT") api_version = os.getenv("AZURE_OPENAI_API_VERSION") deployment = os.getenv("AZURE_OPENAI_DEPLOYMENT_NAME") # Azure OpenAIクライアントの作成 client = AzureOpenAI( api_version=api_version, azure_endpoint=endpoint, api_key=api_key, ) # ツール取得 tools = FunctionSchemaManager.get_all_tools() messages = [ { "role": "system", "content": "あなたは優秀なアシスタントAIです。", }, {"role": "user", "content": "八王子の今の天気と時刻を教えてください。"}, ] # 1回目のFunctionCallingリクエスト response = client.chat.completions.create( messages=messages, max_tokens=1000, temperature=0.7, model=deployment, tools=tools, tool_choice="auto", ) response_message = response.choices[0].message messages.append(response_message) print("レスポンス:") print(response_message) # 関数実行 if response_message.tool_calls: for tool_call in response_message.tool_calls: function_name = tool_call.function.name function_args = json.loads(tool_call.function.arguments) print(f"関数呼び出し: {function_name}") print(f"引数: {function_args}") if function_name == "current_weather": args = WeatherArgs.model_validate(function_args) # 引数チェック tool_response = current_weather(location=args.location) elif function_name == "current_time": args = TimeArgs.model_validate(function_args) # 引数チェック tool_response = current_time(location=args.location) else: tool_response = {"error": "不明な関数"} messages.append( { "tool_call_id": tool_call.id, "role": "tool", "name": function_name, "content": json.dumps(tool_response, ensure_ascii=False), } ) else: print("関数呼び出しはありませんでした。") # 最終回答生成 final_response = client.chat.completions.create( messages=messages, max_tokens=1000, temperature=0.7, model=deployment, ) print("最終レスポンス:") print(final_response.choices[0].message.content) 生成AIモデルからのレスポンスには使用する関数と引数が書かれているため、それを使用して関数の実行を行います。 Azure OpenAIのFunctionCallingは並列関数呼び出しが可能で、一回のレスポンスで複数の使用する関数名を返してくれます。 実行結果 実行結果は以下のようになりました。 レスポンス: ChatCompletionMessage(content=None, refusal=None, role='assistant', annotations=[], audio=None, function_call=None, tool_calls=[ChatCompletionMessageFunctionToolCall(id='call_iFwCt1t3Lzl2WMqQJDvP26Z7', function=Function(arguments='{"location": "八王子"}', name='current_weather'), type='function'), ChatCompletionMessageFunctionToolCall(id='call_6LbONbarZs3sCqoPiZstpieN', function=Function(arguments='{"location": "八王子"}', name='current_time'), type='function')]) 関数呼び出し: current_weather 引数: {'location': '八王子'} 関数呼び出し: current_time 引数: {'location': '八王子'} 最終レスポンス: 八王子の現在の天気は晴れで、気温は15度です。また、現在の時刻は2026年2月24日の13時36分です。 current_weatherとcurrent_timeの2つの関数を一度のレスポンスで呼び出していることがわかります。 また、関数の実行結果をもとにして回答してくれています。 messagesを変更することで、1つの関数だけ実行させることも可能です。 以下にmessagesを変更した場合の実行結果を示します。 時刻を聞くmessages Python messages = [ { "role": "system", "content": "あなたは優秀なアシスタントAIです。", }, {"role": "user", "content": "八王子の時刻を教えてください。"}, ] 実行結果 レスポンス: ChatCompletionMessage(content=None, refusal=None, role='assistant', annotations=[], audio=None, function_call=None, tool_calls=[ChatCompletionMessageFunctionToolCall(id='call_5m0PwZa4t2AIty1trBlKTGAs', function=Function(arguments='{"location":"八王子"}', name='current_time'), type='function')]) 関数呼び出し: current_time 引数: {'location': '八王子'} 最終レスポンス: 現在の八王子の時刻は、2026年2月24日 14:22です。 天気を聞くmessages Python messages = [ { "role": "system", "content": "あなたは優秀なアシスタントAIです。", }, {"role": "user", "content": "八王子の天気を教えてください。"}, ] 実行結果 レスポンス: ChatCompletionMessage(content=None, refusal=None, role='assistant', annotations=[], audio=None, function_call=None, tool_calls=[ChatCompletionMessageFunctionToolCall(id='call_MZmeJ11LfOQufB1dFzyztQEu', function=Function(arguments='{"location":"八王子"}', name='current_weather'), type='function')]) 関数呼び出し: current_weather 引数: {'location': '八王子'} 最終レスポンス: 現在の八王子の天気は晴れで、気温は15度です。 傘が必要か聞くmessages Python messages = [ { "role": "system", "content": "あなたは優秀なアシスタントAIです。", }, {"role": "user", "content": "今から八王子に行きます。傘はいるかな"}, ] 実行結果 レスポンス: ChatCompletionMessage(content=None, refusal=None, role='assistant', annotations=[], audio=None, function_call=None, tool_calls=[ChatCompletionMessageFunctionToolCall(id='call_Hoa7qoq13vJa4nVqzCdegVJp', function=Function(arguments='{"location":"八王子"}', name='current_weather'), type='function')]) 関数呼び出し: current_weather 引数: {'location': '八王子'} 最終レスポンス: 八王子の天気は晴れで、気温は15度です。今のところ傘は必要なさそうですが、念のため天気予報を確認しておくと良いかもしれません。安全に行ってきてください! 直接天気や時刻を聞かなくとも関数を実行して答えてくれます。 まとめ 今回はAzure OpenAIでFunctionCallingを行う方法についてまとめました。 Azure OpenAIのFunctionCallingは並列関数呼び出しが可能で、前章の例のように複数の関数を一度のレスポンスで呼び出すことができます。 どのような関数を実行させるかはアイデア次第です。是非FunctionCallingを使用して生成AIとツールを組み合わせてみてください。 今後もAzure OpenAIについて学んだことを共有していきたいと思います。 読んでいただきありがとうございました。 関連記事 これまでのAzure OpenAI入門 Azure OpenAI入門:モデルのデプロイとpythonからAPIを実行 AzureOpenAI入門:JSON形式のデータを出力させる 参考文献 https://learn.microsoft.com/ja-jp/azure/ai-foundry/openai/how-to/function-calling?view=foundry-classic&tabs=python-secure ご覧いただきありがとうございます! この投稿はお役に立ちましたか? 役に立った 役に立たなかった 0人がこの投稿は役に立ったと言っています。 The post AzureOpenAI入門:FunctionCallingで生成AI×ツールを実現する first appeared on SIOS Tech Lab .
アバター
日々の業務で、見積書・請求書・報告書・管理表など、 Excelが中心になっている現場 は少なくありません。一方で、ファイルが増え続けるほど「探す」「集計する」「整える」作業が重くなり、 時間とミスのリスク が膨らみがちです。 当社では、Excelのユーザー体験はそのままに、 自然言語で検索・集計・可視化まで行えるAIエージェントシステムの構築 を行っています。 現在、 無料で体験いただけるトライアル環境 を公開中です。まずは触ってみて、貴社の課題をお聞かせください。 M365アカウントを持っていない方、アドインを社内規定で追加できない方に対しても、当社側でテスト用のアカウントを払い出すため、どなたでもトライアルに参加いただけます。 無料トライアルを試す 相談・お問い合わせ メール : ka-sasaki@sios.com AIエージェント開発やDXに関するご相談も広く受け付けています。 「こんなことできる?」というアイデアベースのご相談も歓迎です。 こんな課題を解決します 課題 AIで解決 複数ファイルから必要なデータを探すのに 何時間もかかる 自然言語で 横断検索 、数秒で回答 毎月の集計作業で 半日かかる 「先月の売上を店舗別にグラフ化して」で 自動処理 担当者しかわからない 属人化 AIが構造を理解し、 誰でも検索可能 に 各システムからCSVを出力して Excelで手作業集計 システム連携で リアルタイム分析 Excel AI エージェントでできること 1. 過去のExcel帳票をそのままデータとして活用 結合セル、複数行ヘッダー、階層構造 を持つ複雑な帳票も、AIが構造を自動解析。 ファイルを取り込むだけで、検索・分析対象になります。 見積書・請求書 売上報告書(複数行ヘッダー) 料金表(結合セル多数) 管理台帳・マスタデータ   2. 過去の類似Excel帳票からドラフト作成 ユースケース : 過去に作成した帳票を学習し、新規作成時のドラフトを自動生成。 例: 「昨年のA社向け見積書をベースに、今年の単価で新しい見積書のドラフトを作って」 入力作業の大幅削減と、過去ナレッジの活用を同時に実現します。 3. 自然言語で検索・集計・グラフ作成 AIエージェントが あいまいな指示も理解 して処理を実行します。 質問例 AIの処理 「店舗Aの決済手段別売上をグラフに」 データ検索 → 集計 → グラフ生成 「先月より売上が下がった店舗は?」 期間比較 → 条件抽出 → 一覧表示 「完了していない作業は何件?」 ステータス値を理解 → カウント 4. 既存システムとの連携 Excelだけに閉じない、企業全体のデータ活用 が可能です。 SQLエージェント : 社内データベース(SQL Server、Oracle、PostgreSQL等)と連携 MCP対応 : 外部API・サービスとの柔軟な接続 ※ システム連携は、貴社環境に合わせた個別構築となります トライアル環境について 体験できること デモ環境には、以下のサンプルデータが用意されています: サンプル 内容 特徴 デモマート 小売業の売上データ 売上報告書(結合セル)、商品・店舗マスタ、トランザクション デモリゾート ホテル・リゾートの予約データ 宿泊料金表(複数行ヘッダー)、施設・客室マスタ、予約データ 試せる機能: 自然言語でのデータ検索 複数ファイルを横断した集計 グラフ・表の自動作成 書式設定の指示(「完了行を緑色に」等) 類似帳票からのドラフト作成 入力済みデータ例 トライアルの制約事項 デモ環境は機能検証を目的としており、以下の制約があります: お客様独自のデータ投入には対応していません(サンプルデータでの検証となります) 「自社データで試したい」 という場合は、PoC(概念実証)としてご相談ください。 データの取り扱いについて 項目 内容 AI学習利用 入力されたデータはAIの学習には使用しません アクセス制御 他のユーザーに入力内容が共有されることはありません。 データ削除 トライアル終了後、一定期間で削除いたします 商用環境の導入形態 クラウド基盤での提供 本システムは クラウド基盤 で提供します。ExcelアドインはMicrosoft 365上で動作し、バックエンドのAI処理はクラウドで実行されます。 構成 内容 フロントエンド Microsoft Excel アドイン(Office.js) バックエンド クラウド基盤(AI処理・検索エンジン) セキュリティ 閉域接続の構成も相談可能 貴社専用のAI環境を構築します 当社はこの技術を基盤とした「貴社専用のAIエージェントシステム構築」を行っています。 ご要望 対応内容 既存システムとの連携 基幹システム、CRM、ERPとの接続構築 社内DBとの接続 SQLエージェントで既存DBを分析対象に 独自フォーマット対応 業界特有・社内独自の帳票に最適化 セキュリティ要件 閉域接続など、貴社ポリシーに準拠した構成 まずはトライアルで技術の可能性を体感いただき、「自社のあの業務で使えるか?」をご検討ください。 その後、無償で簡易要件ヒアリングを実施し、貴社に最適なシステム構成をご提案します。 デモ動画 https://tech-lab.sios.jp/wp-content/uploads/2026/02/c7a3cb943abf893c211da41841707cc6.mp4 よくある質問 Q. どんなExcelファイルでも対応できますか? 結合セル、複数行ヘッダー、階層構造を持つ複雑な帳票にも対応しています。見積書、請求書、売上報告書、料金表など、様々なフォーマットで動作確認済みです。 Q. 既存のExcelファイルをそのまま使えますか? はい。ファイルをシステムにインポートするだけで、検索・分析対象になります。Excelのフォーマットを変更する必要はありません。 Q. 社内の基幹システムとも連携できますか? はい。SQLエージェント技術により、SQL Server、Oracle、PostgreSQLなど主要なデータベースとの連携が可能です。連携構築は貴社環境に合わせた個別対応となります。 Q. セキュリティ面が気になります 入力されたデータはAIの学習には使用しません。また、閉域接続の構成も相談可能です。貴社のセキュリティポリシーに合わせた構成をご提案します。 Q. 費用感を知りたいです 貴社の要件に応じた個別見積もりとなります。まずはトライアルで技術を体感いただき、要件ヒアリングの上でお見積もりいたします。 お問い合わせ 無料トライアルを試す 相談・お問い合わせ メール : ka-sasaki@sios.com AIエージェント開発やDXに関するご相談も広く受け付けています。 「こんな業務を自動化したい」 「既存システムとAIを連携させたい」 「まずは話を聞いてみたい」 本トライアルではM365アカウントを持っていない方、アドインを社内規定で追加できない方に対しても、当社側でテスト用のアカウントを払い出すため、どなたでもトライアルに参加いただけます。 どんなご相談でもお気軽にお問い合わせください。   ご覧いただきありがとうございます! この投稿はお役に立ちましたか? 役に立った 役に立たなかった 0人がこの投稿は役に立ったと言っています。 The post Excel AI エージェント 無料トライアルを開始しました! first appeared on SIOS Tech Lab .
アバター
前回の記事ではSCANOSS CLIを使ったローカルスキャンの手順 を紹介しました。ローカルで動作確認ができたら、次はCI/CDパイプラインへの統合です。 本記事では、 SCANOSS Code Scan Action を使ったGitHub Actionsでのコードスキャン自動化の手順を紹介します。 この記事でわかること : GitHub Actionsでの基本的なスキャン設定と実行方法 ポリシーチェック(Copyleft / Undeclared)の設定と挙動 API Keyあり/なしの挙動差(GitHub ActionsではAPI Key必須) scanoss.jsonによるスキャン結果の制御とポリシーチェックへの影響 サブディレクトリスキャンやスキャンチューニングの活用方法 前提条件 GitHubリポジトリにActions実行権限があること SCANOSS API Keyを取得済みであること( SCANOSSとの契約 が必要) リポジトリのSettings > Secrets に SCANOSS_KEY を登録済みであること 基本スキャン(Non-Policy) 最もシンプルな構成です。ポリシーチェックなしで、コードスキャンのみを実行します。 # .github/workflows/scanoss-scan.yml name: SCANOSS Security Scan on: workflow_dispatch: permissions: contents: write pull-requests: write checks: write actions: read jobs: scanoss-scan: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - uses: scanoss/gha-code-scan@v1.5.0 with: api.key: ${{ secrets.SCANOSS_KEY }} 実行すると、以下のArtifactが自動生成されます。 Artifact 内容 scanoss-raw.json スキャン結果(JSON) scanoss-cyclonedx.json CycloneDX SBOM scanoss-spdxlite.json SPDX-Lite SBOM scanoss-sbom.csv CSV形式レポート 今回の検証では、実行時間は約33秒でした(Docker imageのpull含む)。 ポリシーチェック付きスキャン(Full Policy) ライセンスポリシーの自動チェックを有効にする構成です。 - uses: scanoss/gha-code-scan@v1.5.0 with: policies: copyleft, undeclared, dt matchAnnotations: false api.key: ${{ secrets.SCANOSS_KEY }} ポリシー チェック内容 copyleft コピーレフトライセンス(GPL等)の混入検出 undeclared 未宣言のOSSコンポーネントの検出 dt Dependency Track サーバーとの連携チェック チェック結果はGitHubのChecks APIを通じてCheck Runとして表示されます。今回の検証では、Copyleft: success、Undeclared: success、Dependency Track: failure(サーバー未構築のため)という結果でした。 matchAnnotations はスニペットマッチ検出時にコミットコメントを自動作成する機能です。デフォルトは true で、不要な場合は false を指定してください。 Dependency Trackポリシーについて dt ( Dependency Track )ポリシーを使うには、Dependency Trackサーバーの構築と以下のパラメータ設定が必要です。 deptrack.url deptrack.apikey deptrack.projectid (または deptrack.projectname + deptrack.projectversion ) 設定がない場合はwarningが出ますが、ワークフロー全体はsuccessで完了します。Dependency Track連携が不要であれば、 policies: copyleft, undeclared のように dt を外しても問題ありません。 API Keyは必須 ローカルスキャンではAPI Keyなしでも動作しましたが、 GitHub ActionsではAPI Keyが必須です 。 API Keyなしで実行した場合、以下のエラーが即座に返されます。 ERROR: SCANOSS API rejected the scan request due to service limits being exceeded ERROR: Details: {"error":"Rate limit exceeded","retry_after":411781} retry_after の値は約411,788秒(約5日)です。つまり約5日に1回しかリクエストできない計算になります。GitHub Actionsの共有IPからの無料APIへのアクセスがレート制限に達しているため、API Keyなしでは実質的にスキャンできません。(お試しでは十分です!あとは週次スキャンには対応できますね…) 項目 API Keyあり API Keyなし 接続先 Premium API api.osskb.org/scan/direct ステータス success failure(HTTP 503) 実行可否 可能 不可 サブディレクトリスキャン scanPath パラメータで、スキャン対象をリポジトリの特定ディレクトリに限定できます。 - uses: scanoss/gha-code-scan@v1.5.0 with: scanPath: ./application api.key: ${{ secrets.SCANOSS_KEY }} 今回の検証では、ルートスキャンとサブディレクトリスキャンでスキャン結果が大きく変わりました。 項目 ルートスキャン サブディレクトリスキャン スニペットマッチ 0件(filtered) 5件 検出ライセンス 0 3 ルートスキャンではMarkdown等のドキュメントファイルが大量に含まれるため、コードファイルのスニペットマッチがfilteredされていました。 scanPath でコードディレクトリのみに絞ることで、検出精度が向上します。モノレポ構成では積極的に活用してください。 なお、 scanPath を指定すると scanoss.json の読み込みパスも変わります。詳しくは後述の「scanoss.jsonによるスキャン制御」セクションを参照してください。 scanoss.jsonによるスキャン制御 リポジトリに scanoss.json を配置すると、スキャン結果のフィルタリングやポリシーチェックの挙動を制御できます。GitHub Actionsではデフォルトで自動読み込みが有効( scanossSettings: true )になっているため、ファイルを配置するだけで設定が反映されます。 読み込みの仕組み scanoss.json はスキャン対象ディレクトリの直下から自動的に読み込まれます。 scanPath 読み込まれるscanoss.json . (デフォルト) リポジトリルートの scanoss.json ./application application/scanoss.json scanPath を指定している場合、ルートの scanoss.json は読み込まれません。 settingsFilepath パラメータで明示的にパスを指定するか、 scanPath で指定したディレクトリに scanoss.json を配置してください。 設定できる内容 scanoss.json では以下の3つの制御が可能です( 公式ドキュメント )。 { "bom": { "include": [ { "purl": "pkg:github/owner/repo", "comment": "宣言済みコンポーネント" } ], "remove": [ { "path": "src/app.py", "purl": "pkg:github/owner/repo", "comment": "誤検出" } ] }, "skip": { "patterns": ["*.pyc", "__pycache__/**", "docs/**"] }, "settings": { "file_snippet": { "min_snippet_hits": 3, "min_snippet_lines": 5, "ranking_enabled": true, "ranking_threshold": 5, "honour_file_exts": true } } } セクション 効果 ポリシーへの影響 bom.include コンポーネントを「宣言済み」としてAPIに送信 Undeclared違反を解消できる bom.remove 指定したpath + purlの組み合わせを結果から除外 除外されたコンポーネントはポリシーチェック対象外になる skip.patterns マッチしたファイルをスキャン対象から除外 スキャンされないためポリシーチェックにも影響しない settings.file_snippet スニペットマッチの感度を調整(v1.5.0) 感度を下げることで誤検出を減らせる Undeclaredポリシーとの連携 undeclared ポリシーは、スキャンで検出されたOSSコンポーネントが bom.include で宣言されていない場合に違反として報告します。 運用の流れは以下の通りです。 Full Policyスキャンを実行し、Undeclared違反が報告される 違反コンポーネントのPURLをスキャン結果から確認する 正しく使用しているものであれば、 bom.include にPURLを追加する 再スキャンでUndeclared違反が解消されることを確認する スキャンチューニング(v1.5.0) v1.5.0から、 scanoss.json の settings.file_snippet セクションでスニペットマッチの感度を調整できるようになりました。最小ヒット数や最小行数の閾値を設定することで、誤検出を減らすことができます。 チューニングパラメータはGitHub Actionの入力パラメータではなく、 scanoss.json で設定します。詳細は 公式ドキュメント(Scan Tuning Parameters) を参照してください。 推奨する運用フロー scanoss.json なしでスキャンを実行し、検出結果を確認する 誤検出があれば bom.remove で除外、正規利用のOSSは bom.include で宣言する 不要なファイル(テストデータ、ドキュメント等)は skip.patterns で除外する スニペットの誤検出が多い場合は settings.file_snippet で感度を調整する scanoss.json をリポジトリにコミットし、以降のCI/CDスキャンに反映させる 段階的な導入ステップ API Keyの準備 : SCANOSSとの契約後、GitHub Secretsに SCANOSS_KEY を登録 Non-Policyで開始 : 基本スキャンで動作確認( workflow_dispatch トリガー) 結果の確認 : Artifactから scanoss-raw.json をダウンロードして内容確認 Full Policyに拡張 : policies: copyleft, undeclared を追加 チューニング : 誤検出が多い場合は scanoss.json で感度を調整 PRトリガーに変更 : workflow_dispatch → pull_request に変更して自動化 まとめ SCANOSS GitHub Actionsを使ったCI/CDでのコードスキャン自動化の手順を紹介しました。 項目 ポイント API Key GitHub ActionsではAPI Key必須(無料APIはレート制限で使用不可) ポリシーチェック copyleft / undeclaredで自動チェック。Dependency Trackはサーバーが別途必要 scanPath サブディレクトリ指定で検出精度が向上。scanoss.jsonの読み込みパスに注意 チューニング v1.5.0でスニペットマッチの感度調整が可能に(scanoss.jsonで設定) バージョン v1.5.0推奨。v1.4.0から後方互換性あり 参考資料 関連リンク SCANOSS Code Scan Action(GitHub リポジトリ) SCANOSS Code Scan Action(GitHub Marketplace) SCANOSS 公式ドキュメント scanoss-py 公式ドキュメント SCANOSS Pricing Dependency Track ご覧いただきありがとうございます! この投稿はお役に立ちましたか? 役に立った 役に立たなかった 0人がこの投稿は役に立ったと言っています。 The post SCANOSS GitHub Actionsでコードスキャンを自動化 first appeared on SIOS Tech Lab .
アバター
AI開発ツールの普及に伴い、ソースコードに含まれるOSSライセンスリスクへの対応が避けられなくなってきました。SCA(Software Composition Analysis)ツールを使うと、コードベースに混入したOSSコンポーネントを自動検出し、ライセンス違反や既知の脆弱性を可視化できます。 本記事では、SCAツール「 SCANOSS 」のPython CLI( scanoss-py )を使ったローカルスキャンの手順を紹介します。 この記事でわかること : scanoss-pyのインストールから基本スキャン、結果の読み方 scanoss.jsonによる誤検出のチューニング方法 CycloneDX / SPDX / CSV形式でのSBOM生成 ScanCode Toolkit連携による依存関係スキャン(uv環境での回避策含む) 検証環境 項目 内容 OS Linux(WSL2 / devcontainer) Python 3.12 パッケージ管理 uv scanoss-py 1.45.1 API Key なし(匿名 / OSSKB パブリック API) 今回はAPI Keyなし(無料の OSSKBパブリックAPI )で検証しています。小〜中規模のプロジェクトであれば、API Keyなしでも十分に利用できます。 インストール pip または uv でインストールできます( PyPI: scanoss )。 # pip の場合 pip install scanoss # uv の場合(dev依存として追加) uv add --dev scanoss インストール後、バージョンを確認します。 $ scanoss-py version Version: 1.45.1 scanoss-py --help でサブコマンド一覧を確認できます。主なサブコマンドは以下の通りです。 サブコマンド 説明 scan ソースコードのスキャン fingerprint フィンガープリント(WFP)の生成 dependencies 依存関係のスキャン convert スキャン結果のフォーマット変換 file_count ファイル数・サイズのサマリー 基本スキャン ファイル数の確認 スキャン前に、対象ディレクトリのファイル構成を確認できます。 $ scanoss-py file_count ./src Found 144 files with a total size of 7.16 MB. extension,count,size(MB) .py,47,0.20 .pyc,44,0.39 .html,21,0.07 .png,21,5.90 144ファイルありますが、実際にスキャン対象となるのはソースコードファイルのみです。バイナリ(.png)や.pycは自動的に除外されます。 スキャンの実行 $ scanoss-py scan -o results.json ./src 実行すると、対象ファイルのフィンガープリントを生成し、 OSSKB (Open Source Knowledge Base)のナレッジベースと照合します。OSSKBには2億7,600万以上のURL [1] がインデックスされており、OSSファイル1億以上 [1] 、コード行数3兆行以上 [1] をカバーしています。今回の検証では48ファイルのスキャンが約5秒で完了しました。 スキャン結果の読み方 結果はJSON形式で出力されます。各ファイルごとにマッチ情報が記録されます。 { "src/app.py": [ { "id": "snippet", "component": "some-oss-project", "matched": "18%", "lines": "24-31", "oss_lines": "513-520", "purl": ["pkg:github/owner/repo"], "licenses": [{ "name": "MIT", "copyleft": "no" }], "url": "https://github.com/owner/repo", "status": "pending" } ] } 主要フィールドの意味は以下の通りです。 フィールド 説明 id マッチ種別。 none (マッチなし)/ snippet (部分一致)/ file (完全一致) matched マッチ率 lines / oss_lines 自分のコード / OSSコードの該当行範囲 purl Package URL(コンポーネントの一意識別子) licenses 検出されたライセンス情報( copyleft フラグ付き) status レビュー状態( pending = 未レビュー) 今回の検証結果は以下の通りです。 項目 件数 スキャン対象 48ファイル マッチなし(id=none) 43 スニペットマッチ(id=snippet) 5 フルファイルマッチ(id=file) 0 自社開発のコードなので、フルファイルマッチ(OSSファイルの完全コピー)は0件。5件のスニペットマッチが検出されましたが、いずれもDockerfileやpytestの定型パターンによるもので、実質的な誤検出でした。 scanoss.jsonで検出結果をチューニングする 初回スキャンで誤検出が含まれる場合、 scanoss.json で検出結果を制御できます( 公式ドキュメント )。 設定ファイルの構成 { "bom": { "include": [ { "purl": "pkg:github/owner/repo", "comment": "宣言済みコンポーネントとして登録" } ], "remove": [ { "path": "src/app.py", "purl": "pkg:github/owner/repo", "comment": "誤検出のため除外" } ] }, "skip": { "patterns": ["*.pyc", "__pycache__/**"] } } セクション 効果 bom.include スキャン時に追加コンテキストとしてPURLをAPIに送信する [2] bom.remove スキャン後の結果から特定PURLを除去する [2] skip.patterns マッチしたファイルをスキャン対象から除外する [2] 設定を適用してスキャン $ scanoss-py scan --settings /absolute/path/to/scanoss.json -o results.json ./src 設定適用前後の比較結果です。 ファイル Before After app.py ollama-workbench (18%) マッチなし(removeで除外) Dockerfile ip-query-system (62%) minimage (39%)(includeにより次候補に変化) scanoss.jsonの注意点 検証を通じて、いくつか注意すべき点が見つかりました。 --settings には絶対パスを指定する 相対パスを指定すると、カレントディレクトリではなくスキャン対象ディレクトリからの相対パスとして解決されます。 # NG: パスが「src/path/to/scanoss.json」と結合される scanoss-py scan --settings path/to/scanoss.json ./src # OK: 絶対パスなら問題なし scanoss-py scan --settings /home/user/scanoss.json ./src bom.remove はpathとpurlの完全一致が必要 スキャン結果のpurlと設定ファイルのpurlが一致しないと除外されません。必ず初回スキャン結果のpurlを確認してから設定してください。 bom.include はマッチを消すのではなく「宣言済み」にする includeに登録しても、スキャン結果からマッチ自体が消えるわけではありません。該当コンポーネントが「宣言済み」として扱われ、スキャン結果は次候補のコンポーネントに変化する場合があります。 SBOM生成 スキャン結果を業界標準のSBOM形式に変換できます。 # CycloneDX scanoss-py convert -i results.json -f cyclonedx -o sbom.cdx.json # SPDX-Lite scanoss-py convert -i results.json -f spdxlite -o sbom.spdx.json # CSV scanoss-py convert -i results.json -f csv -o results.csv 3形式の使い分けは以下の通りです。 形式 用途 CycloneDX Dependency Track等のSBOM管理ツールへの連携 SPDX-Lite ライセンスコンプライアンス管理(業界標準仕様) CSV Excelやスプレッドシートでの手動レビュー 注意点として、CycloneDX出力は拡張子を .xml にしても実際の出力はJSON形式です。XML形式での出力が必要な場合は別途変換が必要です。 依存関係スキャン scanoss-pyは、 requirements.txt や pyproject.toml 等から依存パッケージを検出する機能も備えています。ただし、この機能には ScanCode Toolkit が別途必要です。 セットアップ # 1. scancode-toolkit のインストール pip install scancode-toolkit # または uv add --dev scancode-toolkit # 2. libgomp1 のインストール(Debian系のslimイメージの場合) sudo apt-get install -y libgomp1 # 3. 動作確認 scancode --version # → ScanCode version: 32.5.0 uv環境での注意点 ScanCode Toolkitは uv.lock に対応していません( GitHub Issue #4501 、2026年2月時点でOpen)。サポート対象のパッケージマニフェスト形式は 公式ドキュメント で確認できます( requirements.txt 、 pyproject.toml 、 poetry.lock 、 Pipfile.lock 等は対応済み)。 uv環境で依存関係をスキャンする場合、 uv export で requirements.txt に変換する必要があります。 uv export --format requirements-txt --no-hashes --no-emit-workspace -o requirements.txt なお、 --no-dev オプションを付けると、直接依存がすべてdev依存のプロジェクトでは空ファイルになります。必要に応じてオプションを調整してください。 依存関係スキャンの実行 # dep サブコマンド(API送信なし、ローカルのみ) scanoss-py dep \ --sc-command /path/to/.venv/bin/scancode \ -o dependencies.json ./src # scan --dependencies(通常スキャン + 依存関係スキャン) scanoss-py scan --dependencies \ --sc-command /path/to/.venv/bin/scancode \ -o results.json ./src ディレクトリを指定すると、ScanCode Toolkitが配下の requirements.txt や pyproject.toml 等のマニフェストファイルを自動検出してパースします。個別にファイルを指定する必要はありません。 --sc-command にはscancode実行ファイルの 絶対パス を指定します。 uv run scancode のような形式は内部のsubprocess呼び出しの都合で使えません。 dep サブコマンドと scan --dependencies の違いは以下の通りです。 dep scan --dependencies SCANOSS API送信 なし あり ライセンス情報の付与 なし あり 用途 事前確認・デバッグ フルSBOM生成 フィンガープリントの活用 fingerprint サブコマンドを使うと、スキャンとAPI送信を分離できます。 # フィンガープリントの生成(オフラインでもOK) scanoss-py fingerprint -o fingerprint.wfp ./src # 後からスキャン(ネットワーク接続時) scanoss-py scan --wfp fingerprint.wfp -o results.json ネットワークに接続できない環境でフィンガープリントだけ先に生成し、接続時にスキャンを実行するワークフローに活用できます。 運用上のポイント 検証を通じて得られた実践的なポイントをまとめます。 推奨ワークフロー 初回スキャン を設定なしで実行し、検出結果を確認する 誤検出を確認し、 scanoss.json を作成してチューニングする チューニング後の結果に問題がなければ、 SBOM を生成する scanoss.jsonをリポジトリに含め、CI/CDでの継続的スキャンに移行する デフォルトの設定ファイル探索 scanoss-pyは、 --settings を指定しなくても、スキャン対象ディレクトリ直下の scanoss.json を自動的に読み込もうとします。リポジトリのルートに scanoss.json を配置しておけば、オプション指定なしでチューニング済みのスキャンを実行できます。 API Keyなしとありの違い 今回の検証はAPI Keyなし(OSSKBパブリックAPI)で実施しています。小〜中規模のプロジェクトであればAPI Keyなしで十分ですが、本番運用ではAPI Keyの利用を検討してください。 項目 API Keyなし API Keyあり 基本スキャン 利用可能 利用可能 可用性保証 なし SLA保証あり スループット保証 なし 保証あり ナレッジベース更新 四半期ごと リアルタイム同期 API Keyありでスキャンする場合は、 --key オプションを指定します。 scanoss-py scan --key YOUR_API_KEY -o results.json ./src API Keyの取得には SCANOSSとの契約 が必要です。CI/CD環境で利用する場合は、GitHub Actionsの secrets.SCANOSS_API_KEY のようにシークレットとして管理してください。 今回の検証規模(48ファイル)では、API Keyなしでもレート制限に抵触せず、スキャン速度も5秒程度と快適でした。なお、具体的なレート制限値は公式ドキュメントに記載されていないため、大規模プロジェクトでの利用時はSCANOSSへの問い合わせを推奨します。 まとめ scanoss-pyを使ったローカルスキャンの手順を一通り紹介しました。 機能 ポイント 基本スキャン API Keyなしで即実行可能。バイナリは自動除外 scanoss.json 誤検出のチューニングに必須。purlの完全一致と絶対パス指定に注意 SBOM生成 CycloneDX / SPDX / CSVの3形式に対応 依存関係スキャン ScanCode Toolkitが別途必要。uv.lockは未対応 ローカルスキャンで動作を確認した後は、CI/CDパイプラインへの統合(GitHub Actionsの SCANOSS Code Scan Action 等)を検討することで、プルリクエスト単位での自動チェックが可能になります。 参考資料 # 出典 [1] OSSKB – Software Transparency Foundation [2] scanoss-py 公式ドキュメント 関連リンク scanoss-py GitHub リポジトリ scanoss-py PyPI SCANOSS 公式ドキュメント OSSKB API ドキュメント ScanCode Toolkit GitHub リポジトリ ScanCode Toolkit 対応パッケージパーサー一覧 SCANOSS Code Scan Action(GitHub Actions) ご覧いただきありがとうございます! この投稿はお役に立ちましたか? 役に立った 役に立たなかった 0人がこの投稿は役に立ったと言っています。 The post SCANOSS CLIでローカルスキャン:インストールからSBOM生成まで first appeared on SIOS Tech Lab .
アバター
今日から使えるGemini活用術シリーズ(全3回) ググる前に、まずGemini。日常がちょっとラクになる3つの使い方 Geminiの回答が「ちょっとズレる」人へ。一言足すだけで変わる3つのコツ ← この記事! 毎回コピペはもう卒業。Geminiの「Gem」で選ぶだけにする方法 ども!普段はエンジニア向けにAIの記事を書いている龍ちゃんです。前回に引き続き、エンジニアじゃない方に向けて書いていきます。 前回紹介した「ググる・読む・書く」の3つの習慣、試してみましたか? 便利なんだけど、使っていくうちに「そうじゃないんだよな…」って回答が返ってくること、ありません? 聞いたことには答えてくれてるんだけど、なんか微妙にズレてる。欲しかったのはそこじゃない、みたいな。 これ、Geminiが悪いわけじゃないんですよね。自分が何を求めているか、Geminiには伝わっていないだけなんです。 今回は、そのズレをなくす3つのコツを紹介します。そんなに難しく考えなくて大丈夫です。 いつもの質問に、一言足すだけ。 前回出てきた「プロンプト」(Geminiへの指示文)に、ちょっとだけ情報を足してあげる。それだけでGeminiの回答精度はぐんと上がります。 コツ1: 「何を知りたいか」を絞る 来週の商談、相手の会社のこと調べなきゃ…ってとき、Geminiに「○○社について教えて」って聞いたことありません? 返ってきたのは、ふんわりした会社概要。設立年とか従業員数とか。知りたかったのはそこじゃないんですよね。 こういうとき、漠然と聞くとGeminiは自分が持っている情報からなんとなく答えようとします。知りたいのが最新のニュースなのか、競合との比較なのか、Geminiにはわからない。Geminiが見ている情報と、自分が欲しい情報のギャップ——それがズレの正体です。 じゃあどうするか。「何を知りたいか」を箇条書きで伝えるだけです。 下の文章をまるごとコピーして、Geminiの入力欄に貼り付けてみてください。○○の部分は自分の状況に合わせて変えてくださいね。 来週○○社と商談があります。以下の観点で情報を整理してください。 - ○○社の主力サービス(3つ以内) - 最近のプレスリリースやニュース - 当社の△△と競合する可能性がある領域 「何を知りたいか」を箇条書きにしただけで、返ってくる情報の精度が全然違います。僕がよく使うのは「今日が○月○日で、直近3ヶ月以内の情報に絞って」と日付を入れるやり方です。これだけで古い情報に引っ張られにくくなります。 ただし、Geminiの知識には更新の時点があります。「最近のニュース」と聞いても、数ヶ月前の情報が返ることがある。最新情報がどうしても必要なときは、Geminiに検索させると精度がずっとよくなります。詳しいやり方はこちら。 2026-01-28 Geminiに検索させるプロンプト術|リサーチGemの作り方 コツ2: 「誰として答えて」を伝える やってしまいがちなのが、下書きをそのまま貼って「これ直して」とだけ伝えるやつです。 Geminiは直してくれます。でも、なんか無難すぎる。温度感が違う。丁寧ではあるんだけど、自分が書いた感じがしない。 「直して」にも方向があるんですよね。丁寧にしたいのか、カジュアルにしたいのか、角を立てないようにしたいのか。それをGeminiは知らない。 ここも一言足すだけです。「あなたは○○です」と伝えるだけで、回答のトーンがガラッと変わります。 下の文章をコピーして、Geminiに貼り付けてみてください。()の中は自分の下書きに差し替えてくださいね。 あなたは10年目のベテラン営業です。 以下の断りメールを、今後の関係性を壊さないように修正してください。 私の言いたいことは変えないでください。 (自分の下書きを貼る) 相手:取引先の部長(長い付き合い) 「10年目のベテラン営業」という一言が入るだけで、言い回しに経験値が乗ります。断り方のニュアンスが、ぐっと実務寄りになる。 「私の言いたいことは変えないでください」も大事です。これがないと、Geminiが親切心で中身まで変えてくることがあります。 ただし、修正結果は必ず自分で読み返してください。特に固有名詞や数字。Geminiが「よかれと思って」変えていることがあります。最終判断は自分です。 コツ3: 「この形で出して」を指定する 会議が終わって、手元に残っているのは走り書きのメモだけ。これを議事録にまとめなきゃいけないんだけど、あの作業、地味にしんどくないですか。 Geminiに「まとめて」と投げるとまとめてくれます。ただ、出てきた形がそのまま使えない。決定事項とTODOだけ知りたいのに、考察や補足まで入ってくる。Geminiは情報と自分の考えを混ぜて出してきます。 こういうときは、見本を渡してしまえばいい。 下の文章をコピーして、走り書きメモと一緒にGeminiに貼り付けてみてください。 以下の会議の走り書きメモを、このフォーマットで整理してください。 ■ 決定事項(箇条書き) ■ TODO(担当者・期限を表で) ■ 次回までの持ち越し事項(1行ずつ) メモに書いてないことは追加しないでください。 (走り書きメモを貼る) フォーマットを見せるだけで、Geminiは「この形に合わせよう」と動きます。「メモに書いてないことは追加しないで」が地味に大事で、これがないとGeminiが補完して情報を足すことがあります。 メモが断片的すぎると、フォーマットを指定してもGeminiが空白を埋めようとすることはあります。そういうときは、フォーマットより先に走り書きの質を上げるほうが早い。箇条書きでもいいので、会議中に「誰が」「何を」決めたかだけはメモしておくと、Geminiの出力が安定します。 まとめ 今回紹介した3つのコツ、どれもやっていることは同じです。 「何を知りたいか」を絞る 「誰として答えて」を伝える 「この形で出して」を指定する いつもの質問に、一言足すだけ。 これだけで、Geminiの回答はぐんと変わります。 まずは1つ、今日の仕事で試してみてください。 でも正直、毎回こういうプロンプトを打ち込むのは面倒なんですよね。次回は、よく使うプロンプトをGeminiに覚えさせて「選ぶだけ」にする方法を紹介します。 ではまた! ご覧いただきありがとうございます! この投稿はお役に立ちましたか? 役に立った 役に立たなかった 0人がこの投稿は役に立ったと言っています。 The post Geminiの回答が「ちょっとズレる」人へ。一言足すだけで変わる3つのコツ first appeared on SIOS Tech Lab .
アバター
今日から使えるGemini活用術シリーズ(全3回) ググる前に、まずGemini。日常がちょっとラクになる3つの使い方 Geminiの回答が「ちょっとズレる」人へ。一言足すだけで変わる3つのコツ 毎回コピペはもう卒業。Geminiの「Gem」で選ぶだけにする方法 ← この記事! ども、龍ちゃんです。非エンジニア向けGemini活用術、最終回です。 前回の3つのコツ——「何を知りたいか絞る」「誰として答えて」「この形で出して」——は便利なんですけど、毎回打ち込むのが地味に面倒ですよね。 この記事では、その指示を一度Geminiに保存して 選ぶだけで使えるようにする 方法を紹介します。使うのは Gem(ジェム) という機能です。 Gemとは? — 30秒で理解 Gemは、自分専用のAIアシスタントを作れる機能です。 イメージとしては、スマホのホーム画面によく使うアプリを置いておく感じ。いつもGeminiに伝えている指示を先に登録しておくと、次からはメニューから選ぶだけで、その指示が入った状態から会話を始められます。 設定はかんたんで、名前をつけて指示を書くだけ。プログラミングの知識は一切いりません。 ちなみに、Gemを使うにはGoogle Workspace Business Standard以上のプランが必要です。第1回で紹介したGeminiの基本機能はStarterでも使えますが、Gemは上位プランの機能になります。 Gemを作ってみよう — リサーチアシスタント編 実際に1つ作ってみましょう。今回は「調べ物を整理してくれるGem」を作ります。 Step 1: Gemマネージャーを開く Geminiのトップ画面を開いて、左メニューにある「Gem マネージャー」をクリックしてください。 Step 2: 「Gemを作成」をクリック Gemマネージャーが開きます。Googleが最初から用意してくれているGemがいくつか並んでいますが、今回は自分で作ります。右端の「Gemを作成」をクリックしてください。 Step 3: 名前とカスタム指示を入力する Gem作成画面が開きます。入力するのは2つだけです。 名前 : 「リサーチアシスタント」と入力 カスタム指示 : ここがGemの心臓部。Geminiに毎回伝えたい指示を書く欄です カスタム指示には、下の枠内をそのままコピーして貼り付けてみてください。 あなたはリサーチアシスタントです。 ユーザーが調べたいテーマを伝えたら、以下の形式で情報を整理してください。 - 結論(1〜2行) - 要点(3〜5つ、箇条書き) - 注意点や補足(あれば1〜2行) 情報源が不確かな場合は「要確認」と明記してください。 前回紹介した「何を知りたいか絞る」コツと「この形で出して」を組み合わせたものですね。これを毎回打たなくてよくなるわけです。 ちなみに、画面にはAIがカスタム指示を自動で書き直してくれる機能もあります。見つけても使わなくて大丈夫です。僕も試したんですけど、盛り盛りに書き換えてくるので、結局自分で書いたシンプルなもののほうが使いやすかったんですよね。 Step 4: 保存して、使ってみる 「保存」をクリックすると、左メニューにGemが追加されます。Gem名をクリックすれば、専用のチャット画面が開きます。 ここがポイントです。さっき入力したカスタム指示には、「何を知りたいか絞る」「この形で出して」がもう入っています。だから、あとは「○○について教えて」と聞くだけ。観点も形式も、Gemが覚えてくれている。毎回の型入力はもう不要です。 商談前の企業調査、社内で聞かれたトピックの整理、ちょっとした技術調査——こういう「調べてまとめる」系の作業は、このGem1つでかなりラクになります。 もう1つ作ってみよう:メール添削Gem コツがわかったところで、もう1つ作ってみましょう。 前回紹介した「誰として答えて」のコツ、覚えていますか? あの役割指定を、Gemに最初から入れておけます。 Gemマネージャーを開いて「Gemを作成」をクリック——ここまではさっきと同じです。名前を「メール添削アシスタント」にして、カスタム指示に下の枠内をそのままコピーして貼り付けてください。 あなたはビジネスメールの添削者です(10年以上の実務経験あり)。 ユーザーが下書きを貼ったら、以下のルールで修正してください。 - ユーザーの言いたいことは変えない - 敬語の過不足を直す - 曖昧な表現を具体的にする - 修正した箇所は【】で囲んで示す 相手との関係性をユーザーが指定した場合は、それに合わせてトーンを調整してください。 保存したら、あとはGemを選んで下書きを貼るだけです。「相手:取引先の部長」と一言添えると、トーンまで合わせてくれます。 毎回「あなたは10年目のベテラン営業です」って打ち込まなくていい。選ぶだけ。これがGemの便利さです。 Gemを使うときの注意点 便利な機能ですが、知っておいてほしいことが3つあります。 まず前提として、Gemini自体の限界はGemでも変わりません。情報が間違っていることもあるので、数字や固有名詞は大事な場面で自分でも確認する習慣をつけておいてください。 もう1つ。 会話が長くなると精度が落ちることがあります (会話が長くなると馬鹿になるってのは実際にあります)。「なんか最近ズレるな」と感じたら、新しいチャットを始めるだけ。Gem自体は残っているので、また選び直すだけで使えます。 一番伝えたいのはこれ: カスタム指示は後からいつでも直せます。 最初から完璧を目指す必要はなくて、使いながら「もうちょっとこうしたいな」が出てきたら、そのときに直す。Gemは育てていくものです。 まとめ 第1回でGeminiを開いて聞いてみることから始めて、第2回で一言足すコツを身につけて、今回はそのコツをGemに保存して「選ぶだけ」にしました。 ここまで来たら、あとは自分の仕事に合ったGemを増やしていくだけです。今後は議事録まとめGemや企画書フィードバックGemなど、仕事で使える具体的なレシピも紹介していく予定です。 次は、自分の仕事に合ったオリジナルのGemを作ってみてください。 もっとGeminiを深掘りしたい方は、こちらも。 2026-01-28 Geminiに検索させるプロンプト術|リサーチGemの作り方 2025-07-07 【実践解説】技術ブログ品質チェック術|Gemini Deep Researchで5分検証 ではまた! ご覧いただきありがとうございます! この投稿はお役に立ちましたか? 役に立った 役に立たなかった 0人がこの投稿は役に立ったと言っています。 The post 毎回コピペはもう卒業。Geminiの「Gem」で選ぶだけにする方法 first appeared on SIOS Tech Lab .
アバター
今日から使えるGemini活用術シリーズ(全3回) ググる前に、まずGemini。日常がちょっとラクになる3つの使い方 ← この記事 ! Geminiの回答が「ちょっとズレる」人へ。一言足すだけで変わる3つのコツ 毎回コピペはもう卒業。Geminiの「Gem」で選ぶだけにする方法 ども!普段はエンジニア向けにAIの記事を書いているんですが、最近「Geminiって何に使えばいいの?」と聞かれることが増えたので、今回はエンジニアじゃない方に向けて書いてみます。龍ちゃんです。 「会社でGemini使えるらしいんですけど、正直あんまり使ってなくて…」 これ、めちゃくちゃ聞きます。使えるのは知ってる。でも何を聞けばいいのかわからない。使い道がピンとこない。そんな方、多いんじゃないでしょうか。 安心してください。難しいテクニックの話は一切しません。やることは1つだけです。 ググる前に、Geminiを開く。 Google Workspace(Business Starter以上)を使っている会社なら、Geminiは追加コストなしで今すぐ使えます。この記事では、それだけで日常がちょっとラクになる使い方を3つ紹介します。具体的には、①気になることを聞く、②資料を要約させる、③文章を見てもらう、の3つです。 ちょっと気になってたこと、聞いてみる Geminiの使い方自体はシンプルで、聞きたいことを打ち込むだけです。ただ、いざ仕事で使おうとすると「で、何を聞けばいいんだっけ?」って手が止まりません? 実は、仕事のことじゃなくていいんですよね。まずはプレッシャーゼロのことから試してみましょう。 たとえば、こういうのありません? 「腸活って最近よく聞くけど、結局なにすればいいの?」 「新NISAって始めたほうがいいの?ざっくり知りたい」 「昼寝って何分がベストなの?逆に疲れるときあるんだけど」 気になるけど、わざわざ調べるほどでもないな…で後回しにしてきたやつです。 ググるとなると、検索結果から記事を選んで、読んで、この情報は信頼できるのかな…って判断するのが地味に面倒なんですよね。Geminiなら、なんとなく聞いたら、なんとなく答えてくれる。しかも最新の情報も拾ってきてくれます。この気軽さがいい。 試してみよう Geminiを開いたら、下の文章をまるごとコピーして、入力欄に貼り付けてみてください。(Geminiへの指示文のことを「プロンプト」と呼びます。覚えなくて大丈夫です) 最近よく聞く「腸活」って、結局なにをすればいいの? こんなのでもOKです。 「在宅勤務で腰が痛い。ストレッチ3つ教えて」 「コーヒーは1日何杯まで大丈夫?」 別に正確な答えが欲しいわけじゃなくて、「とっかかり」が欲しいだけなんですよね。そういうとき、Geminiは「ちょっと詳しい友達」くらいの感覚で使えます。 プライベートで1回試してみたら、次は仕事でも同じ感覚で使えます。 読む前に、まず要約させる 上司から「これ読んどいて」と共有された長い資料。業界ニュースの記事。「あとで読もう」と思ってタブだけ増えていく、あの感じ。 これ、Geminiに丸投げできます。やり方はシンプルです。 Webページの場合:ページのURLをコピーして、Geminiの入力欄に貼る PDFの場合:Geminiの入力欄にあるファイルアイコン( )からPDFを選ぶ その後にプロンプトを続けて入力するだけ。それだけで「読む前の仕分け」ができてしまいます。 試してみよう 放置しているURLやPDFを上の方法でGeminiに渡したら、続けて下のプロンプトをコピーして貼り付けてみてください。 この内容を以下の形式で要約してください。 - 結論(1行) - 要点(3つ) - 自分が読むべきかの判断(読むべき/斜め読みでOK/スキップ可) 「読むべきかの判断」を聞くのがコツです。結論が1行で出てくるだけで「あ、これは後でいいや」とか「ここだけ読めばOKか」って判断できる。全部読まなくていいってわかるだけで、タブを閉じる気になれます。僕はこれを知ってから「あとで読む」タブを溜め込む罪悪感がだいぶ減りました。 読む側でGeminiを使えたら、次は自分が書く側でも使ってみましょう。 送る前に、見てもらう メールやチャットを送る前に「この言い方で大丈夫かな…」って迷う瞬間、ありますよね。特に上司やクライアント宛だと、言い回しに悩んで時間が溶ける。 ここでのコツは、AIに0から書かせるんじゃなくて、 自分の下書きを見てもらう ことです。自分で書いた文章をGeminiに貼って「これで大丈夫?」と聞く。それだけで的外れにならないし、自分らしい文章のまま変なところだけ直してくれます。 試してみよう 下書きができたら、Geminiの入力欄にこう貼るだけです。 以下は私が書いた【お断りメール】の下書きです。 (ここに自分の下書きを貼る) このまま送って大丈夫か確認して、改善点があれば直してください。 相手との関係性:【クライアント】 【】の部分を変えるだけで、上司宛でも同僚宛でも使い回せます。社内の文章を使っても大丈夫。Workspaceのプランなら、入力した内容はAIのトレーニングに使われません( Google公式ドキュメント )。 まとめ 今回紹介した3つの使い方、どれも「Geminiを開いて、聞くだけ」です。 ちょっと気になること → 聞いてみる 読む前の資料 → 要約させる 送る前の文章 → 見てもらう 個人的には2番目の要約が一番おすすめです。僕もこれを使い始めてから、放置タブが目に見えて減りました。 聞き方に正解なんてありません。まず1つ、今日試してみてください。 使っていくうちに「もうちょっとこう答えてほしいんだよな」って思う瞬間が出てくるはずです。次回は、その「ズレ」をなくすための簡単なコツを紹介します。 「もっと本格的にGeminiで調べ物がしたい!」という方は、こちらの記事もどうぞ。 Geminiに検索させるプロンプト術|リサーチGemの作り方 技術ブログ品質チェック術|Gemini Deep Researchで5分検証 ではまた! ご覧いただきありがとうございます! この投稿はお役に立ちましたか? 役に立った 役に立たなかった 0人がこの投稿は役に立ったと言っています。 The post ググる前に、まずGemini。日常がちょっとラクになる3つの使い方 first appeared on SIOS Tech Lab .
アバター
今号では、gzip コマンドによるファイルの圧縮、展開について紹介します! 前回の記事 (tar コマンドを使ったファイルのアーカイブ・展開) と併せて見ていただければと思います。 gzip とは gzip とは、ファイルを圧縮してサイズを小さくするためのコマンドです。 前回の記事で紹介した tar コマンドとは異なり、基本的には 1つのファイルを圧縮するためのものです。 そのため、複数ファイルをまとめる (アーカイブする) 機能はありません。 基本の書式 ファイルを圧縮 gzip [ファイル名] の書式で実行します。 例: $ gzip test.txt $ ls test* test.txt.gz 上記のコマンドを実行すると、元のファイル (test.txt) が消えて圧縮後のファイル (data.txt.gz) のみになります。 ファイルを展開 gzip -d [ファイル名] もしくは gunzip [ファイル名] の書式で実行します。 例: $ gzip -d test.txt.gz $ ls test* test.txt 例: $ gunzip test.txt.gz $ ls test* test.txt ファイルの圧縮時と同様に、上記のコマンドを実行すると、元のファイル (test.txt.gz) が消えて展開後のファイル (data.txt) のみになります。 gzip コマンドのオプション gzip コマンド の基本的なオプションをご説明します。 ※すべてのオプションはご紹介せず、よく使用されると考えられるものを抜粋しています。 -r ディレクトリ内のファイルを再帰的に圧縮します。 $ gzip -r testdir $ ls testdir/subdir1 test1.txt.gz $ ls testdir/subdir2 test2.txt.gz ※圧縮されるのは、 ディレクトリ配下にあるファイルのみ です。 なお、-r を指定せずにディレクトリを指定すると、下記のエラーが表示されます。 $ gzip -d testdir gzip: testdir is a directory -- ignored -k ファイルの圧縮、展開時に元のファイルを削除せず残します。 $ gzip -k test.txt $ ls test* test.txt test.txt.gz $ gzip -dk test.txt.gz $ ls test* test.txt test.txt.gz -l 圧縮ファイルの圧縮率や元のサイズを確認します。 $ gzip -l test.txt.gz compressed uncompressed ratio uncompressed_name 29 0 0.0% test.txt ※この操作では、ファイルの展開は行われません。 ご覧いただきありがとうございます! この投稿はお役に立ちましたか? 役に立った 役に立たなかった 0人がこの投稿は役に立ったと言っています。 The post 知っておくとちょっと便利!gzip コマンドを使ったファイルの圧縮・展開 first appeared on SIOS Tech Lab .
アバター
こんにちは! 今月も「OSSのサポートエンジニアが気になった!OSSの最新ニュース」をお届けします。 2/12、Google は最新の脅威追跡レポートにて、ハッカーが Gemini の技術を盗むための「抽出攻撃」を仕掛けていると発表しました。 グーグル「Gemini」の複製を狙う攻撃が判明、10万回超のプロンプトを浴びせる事案も https://japan.cnet.com/article/35243857/ Microsoft 365 Copilot が、数週間にわたり顧客の機密メールを要約していたことが判明しました。 企業向け「Microsoft 365 Copilot」、DLP設定無視で機密メール内容を要約 修正プログラム展開中 https://www.itmedia.co.jp/news/articles/2602/19/news069.html 2/20、Open Source Security Foundation (OpenSSF) より「SBOM データによるリスク管理の意思決定の改善」の日本語版が公開されました。 OpenSSFホワイトペーパー「SBOMデータによるリスク管理の意思決定の改善」を公開 https://prtimes.jp/main/html/rd/p/000000404.000042042.html ご覧いただきありがとうございます! この投稿はお役に立ちましたか? 役に立った 役に立たなかった 0人がこの投稿は役に立ったと言っています。 The post 【2026年2月】OSSサポートエンジニアが気になった!OSS最新ニュース first appeared on SIOS Tech Lab .
アバター
AIと一緒に仕様書を書く ども!最近AIを使った仕様書作りの検証とかに取り組みだした龍ちゃんです。 「AIと人間の両方で仕様書を効率的に管理するため」にはという課題に取り組んでいた時の内容です。 今回はAIツールを開発に使ってるチームで、仕様書をGitで管理してる人向けの話です。 この記事で話すこと: なぜ仕様書の図はAIに伝わりにくいのか 図解にソースコードを添える設計パターン(3パターン) 実際に試して分かった制約と注意点 まず完成形のイメージを見せます。 <!-- この図のソースコード(AI向け): sequenceDiagram Client->>+Server: ログインリクエスト Server->>+DB: ユーザー照合 DB-->>-Server: 結果 Server-->>-Client: トークン発行 設計意図: DB直接参照を避け、サービス層を経由する設計。 理由: テスタビリティとマイクロサービス移行への備え。 --> ![認証フロー図](./images/auth-flow.png) これはMarkdownファイル( .md )に書きます。リポジトリの docs/ 配下に仕様書として置いておくだけ。今はなんとなく雰囲気だけ掴んでもらえればOKです。具体的な書き方は後で3パターン紹介します。 このコメントには3つ詰め込んでます。 図のソースコード (Mermaid記法)→ AIが構造を正確に読める 設計意図 (なぜこの構造にしたか)→ AIが「なぜ」を理解できる 注釈 (制約や前提条件)→ AIがスコープを把握できる 人間はPNG画像を見るだけで、AIはHTMLコメントの中身を読む。両方が同じファイルに収まることでAIの理解と人間の視認性を確保することができます。 今の仕様書、AIに読める形になってますか? 「仕様書にきれいな図を描いた。シーケンス図、アーキテクチャ図、状態遷移図。人間のレビューは問題なく通る。」 でもこの仕様書、AIに渡したらどうなるか考えたことありますか? AIは仕様書の図を「推測」で読んでいる 試しに仕様書の図をAIに見せて「この設計について説明して」と聞いてみてください。それっぽい回答が返ってきます。実際には、2つの「推測」が存在しています。 推測その1: 構造の推測 PNG画像からAIが読み取る構造は、厳密ではないです。矢印の方向、条件分岐の条件、サービス間の依存関係。人間なら「見ればわかる」ものも、AIは画像のピクセルから推測しています。シンプルな図なら当たることが多いけど、複雑になるほど精度が落ちます。 推測その2: 意図の推測 仮に構造を正確に読めたとしても、「なぜこの構造にしたのか」は画像のどこにも書いてない。「なぜこの構成にしたのか」「なぜこのサービスを分けたのか」。AIは設計意図を推測するしかない。推測が当たることもあるけど、外れることもある。 つまりAIは、構造も意図が含まれていなければ推測が入ります。これからAI駆動開発を始めたい人も、既にやってる人も、ここがボトルネックになります。 じゃあ全部テキストで書けばいい? テキストだけの仕様書だと人間が読むのがしんどいんですよね。構造が一目でわからない。フローの分岐とか、サービス間の依存関係とか、図解があるから仕様書として機能してる部分があります。 推測をなくすには ここにジレンマがあって。 人間のためにはPNG画像がほしい AIのためにはテキスト(Mermaid/PlantUMLコード + 設計意図)がほしい ソースコードを添えれば構造の推測がなくなる。設計意図を書いておけば意図の推測がなくなる。この2つをセットで、同じファイル内に持たせる方法があります。次のセクションで具体的に見せます。 図解にソースコードを添える — 人間の視認性とAIの理解を両立する ここからが本題です。 やることはシンプルで、Markdownの仕様書内で図のPNG画像の直前に、HTMLコメントとして以下を書く。 Mermaid/PlantUMLのソースコード — 図の構造そのもの 設計意図 — なぜこの構造にしたか 注釈 (必要なら)— 異常系の考慮、将来の拡張方針など 人間の視認性とAIの理解、両方を1つのファイルで実現する方法です。 なぜHTMLコメントなのか Markdownの中にHTMLコメント( <!-- --> )を書くと、GitHubやドキュメントビューアで表示されない。人間がドキュメントを読むときには見えないんですよね。 でもAI(Claude CodeやCopilot等)がファイルを読むときは、HTMLコメントの中身もテキストとして見える。 つまり「人間には見えないけどAIには見える」メモ欄として機能する。人間は画像を見る。AIはコメントの中身を読む。お互い干渉しない。 リポジトリに置くだけでいい 自分がこのパターンを気に入ってる理由は、「食わせる(AIへのコンテキスト注入)」作業が簡単になるという点です。 GitリポジトリのMarkdownにHTMLコメント付きで置いておくだけで、Claude Codeが勝手に読んでくれる。Claude Codeはプロジェクトのリポジトリ内のファイルを直接参照できるので、わざわざプロンプトに貼り付ける必要がない。RAGの仕組みを作る必要もない。リポジトリにあるドキュメントをAIが自然に参照できる状態にしておくだけ。 これは自分が以前書いた「 AIフレンドリーなドキュメント管理 」や「 調査→構造化→注入の設計パターン 」の記事と同じ考え方です。テキストドキュメントをリポジトリに集約するアプローチの「図解版」ですね。 「それ、二重管理じゃない?」 この後のパターン集では ![認証フロー](./images/auth-sequence.png) のようにPNG画像を参照する形で書いてます。「ソースコードとPNG画像の両方を管理するのは二重管理では?」という疑問が出ると思います。 結論から言うと、 PNG画像が必要になるタイミングとソースコードが必要になるタイミングは別 なので、問題にならないかなと考えています。 エンジニア同士で設計を進めるフェーズでは、Mermaid/PlantUMLのソースコード + テキスト注釈だけで十分。AIも読める。ここでは図の記法で爆速で構造を整理していくことに集中すればいい PNG画像が必要になるのは、非エンジニア(お客さん、品質管理チームなど)に資料を出すタイミング。その瞬間にソースコードから生成すればいい 生成はMermaid CLIやPlantUML Web Service・HTML+Claude Codeを使用して自動化できる 管理するのはソースコードだけ。PNG画像は必要なときに生成する出力物 。二重管理ではなく「ソースが1つ、出力が必要なときに作る」という発想です。Claude Codeを使えばMermaidもPlantUMLも爆速で書けるので、ソースコードの作成・修正も苦になりません。具体的な方法は以下の記事で解説しています。 Mermaid/PlantUMLを知らなくても始められる 記法を知らないから無理、と思った人もいるかもしれません。でもAIに「この図のMermaidコードを書いて」と頼めば書いてくれます。既存のPNG画像を渡して「このPNG画像をMermaid記法に変換して」という方法もあります。 入門(ソースコード作成) ClaudeでMermaid図作成を自動化!2時間→5分の劇的時短術 Claude Codeで仕様書のPlantUML図を自動生成 — VS Codeプレビューで完結 発展(見た目カスタマイズ + PNG変換) Mermaid × Tailwind CSS — ハイブリッド図解の作り方 PlantUMLの表現力をTailwind CSSで設計書品質に仕上げる 記法の習得はあとからで大丈夫です。最初の一歩としては、設計意図のコメントを書くところから始めてみてください。 実装パターン集 ここからは具体的なコードサンプルを3つ見せます。全部コピペして使えます。自分の仕様書に近いパターンを選んでください。 パターン1 : シーケンス図(API設計書の認証フローなど) パターン2 : アーキテクチャ図(マイクロサービス構成など) パターン3 : 状態遷移図(注文ステータス管理など) まず: Mermaid と PlantUML どっちを使う? ソースコードの記法は2種類あります。迷ったらこの表で判断してください。 こういう図なら こっちを使う フローチャート、簡易シーケンス図、状態遷移、ER図 Mermaid アクティビティ図、ユースケース図、コンポーネント図 PlantUML UML準拠が求められる設計書 PlantUML 10ノード以上の大規模な図 PlantUML 迷ったらMermaidで始めて、限界を感じたらPlantUMLに切り替えればいい。AIとの相性はMermaidが最高、PlantUMLも高い。どちらを選んでもAIは読み取れます。 パターン1・3はMermaid、パターン2はPlantUMLで書いてます。使い分け表の通り、コンポーネント構成はPlantUMLのほうが得意です。 設計意図の書き方 パターンに入る前に1つだけ。前のセクションではHTMLコメントに「何を入れるか」(ソースコード・設計意図・注釈)を説明しました。ここでは設計意図の「書き方」の話です。ソースコードだけ貼っても、AIは構造は読めるけど「なぜ」がわからない。コメント内に最低限書くべきはこの3つ。 設計意図 : なぜこの構造にしたか(1-2行) 制約・前提 : この設計が成り立つ条件(あれば) スコープ外 : この図が扱わない範囲(あれば) 全部書く必要はないです。「なぜ」だけでも十分価値がある。以下の3パターンで書き分けの実例を見せます。 パターン1: シーケンス図 + 設計意図コメント ユースケース : API設計書の認証フロー <!-- AI向けソースコード: sequenceDiagram Client->>+API Gateway: POST /auth/login API Gateway->>+Auth Service: validateCredentials() Auth Service->>+User DB: findByEmail() User DB-->>-Auth Service: User Auth Service-->>-API Gateway: JWT Token API Gateway-->>-Client: 200 OK + Token 設計意図: Gateway がトークン発行の責務を持たず、Auth Service に委譲。 理由: 認証ロジックの変更(OAuth追加等)時に Gateway を触らなくて済む。 注意: Rate Limiting は Gateway 側で実装。Auth Service には到達しない前提。 --> ![認証フロー](./images/auth-sequence.png) 上記のソースコードから生成した図がこちら。右側の注釈パネルは、HTMLコメント内の設計意図をビジュアル化したもの。 人間が見るもの : きれいなシーケンス図の画像 AIが読むもの : Mermaidコード + 「なぜGatewayがトークンを発行しないか」の設計意図 制約 : Mermaidシーケンス図は4参加者・8メッセージ以下が読みやすい(検証済み) パターン2: アーキテクチャ図 + 責務定義コメント ユースケース : システム構成書のマイクロサービス構成 <!-- AI向けソースコード: @startuml package "Frontend" { [SPA - React] as SPA [BFF - Next.js] as BFF } package "Backend" { [Auth Service] as Auth [User Service] as User [Order Service] as Order } package "Data" { database "User DB" as UserDB database "Order DB" as OrderDB database "Redis Cache" as Cache } SPA --> BFF BFF --> Auth BFF --> User BFF --> Order Auth --> UserDB User --> UserDB User --> Cache Order --> OrderDB Order --> Cache @enduml 責務定義: - BFF: フロントエンド専用のAPI集約層。バックエンドサービスへの直接アクセスを防ぐ - Auth Service: 認証・認可のみ。ユーザー情報の参照はUser Serviceに委譲 - Cache: Read-through パターン。書き込みはDB直接 技術的制約: サービス間通信は gRPC。BFF→Backend のみ REST --> ![システム構成図](./images/architecture.png) 上記のソースコードから生成した図がこちら。責務定義が右側の注釈パネルに対応している。 人間が見るもの : マイクロサービスの全体像が一目でわかる構成図 AIが読むもの : PlantUMLコード + 各サービスの責務定義 + サービス間の通信方式 + キャッシュ戦略 PlantUMLの利点 : database や queue の専用記号が使える。パッケージでレイヤーを明示できる パターン3: 状態遷移図 + 異常系注釈コメント ユースケース : 業務フロー仕様書の注文ステータス管理 <!-- AI向けソースコード: stateDiagram-v2 [*] --> 注文受付 注文受付 --> 在庫確認中 在庫確認中 --> 決済処理中: 在庫あり 在庫確認中 --> キャンセル: 在庫なし 決済処理中 --> 出荷準備中: 決済成功 決済処理中 --> 決済エラー: 決済失敗 決済エラー --> 決済処理中: リトライ(最大3回) 決済エラー --> キャンセル: リトライ上限超過 出荷準備中 --> 出荷済み 出荷済み --> 配達完了 配達完了 --> [*] キャンセル --> [*] 異常系の設計: - 決済エラー → リトライは最大3回。exponential backoff(1秒→2秒→4秒) - 在庫なし → 即キャンセル。仮押さえはしない設計(在庫ロック競合を避ける) - 出荷後のキャンセル → この図の範囲外。返品フローは別仕様書を参照 --> ![注文ステータス遷移図](./images/order-state.png) 上記のソースコードから生成した図がこちら。正常系(青)と異常系(赤)を色で区別している。 人間が見るもの : 注文の正常系・異常系が一目でわかる状態遷移図 AIが読むもの : 状態遷移のルール + 異常系のリトライ戦略 + スコープ外の明示 制約 : 状態遷移図は8-10状態が上限(検証済み。それ以上は縦に伸びて見切れる) 3つのパターンに共通しているのは、 ソースコードだけでなく「なぜ」を書いている こと。パターン1は設計意図、パターン2は責務定義、パターン3は異常系の設計判断。AIが読んで「この設計の理由」まで理解できる状態にしてます。 実際に試して分かったこと ここまでのパターンを実際に検証して分かった注意点を2つ共有します。 ノード数の上限は思ったより低い Mermaidで図を描くとき、ノード(箱や状態)を増やしすぎると自動縮小されて文字が読めなくなります。1280x720pxの描画領域で検証した推奨上限はこれです。 図の種類 推奨上限 フローチャート 8-10ノード シーケンス図 4参加者・8メッセージ 状態遷移図 8-10状態 上限を超えたら図を分割してください。1つの図に全部詰め込みたくなる気持ちはわかるけど、分割したほうが人間にもAIにも読みやすい。 PlantUMLはサーバー側で描画するので、Mermaidほど厳しくないです。10ノード以上の大規模な図が必要なら、PlantUMLのほうが安全。 本当にAIが読み取れるのか? — 試してみてほしい 「HTMLコメントをAIが読めるって言うけど、本当に?」と思った人へ。自分で試すのが一番早いです。 パターン1のMarkdownをそのままファイルに保存する Claude Code(またはお好みのAIツール)にそのファイルを読ませる 「この仕様書の認証フローについて説明して。設計意図も含めて」と聞く HTMLコメント内の設計意図まで含めて回答してくれるはずです。「GatewayはRate Limitingだけを担当し、トークン発行はAuth Serviceに委譲しています」みたいな回答が返ってきたら、AIがコメントの中身を正確に読み取れている証拠。 やってみてください。 まとめ 仕様書の図を「人間だけが読むもの」から「人間とAIが読むもの」にする。やることはシンプルです。 図のPNG画像の横に、HTMLコメントでソースコードと設計意図を添える。 Mermaid/PlantUMLを使えば、AIが推測ではなく正確に設計構造を理解できる。設計意図を書いておけば「なぜこの構造にしたか」まで伝わる。 「AIに仕様書を食わせる」んじゃなくて、 AIが自然に読める仕様書をリポジトリに置いておく 。これだけ。 これは仕様書を書いてる人にしかできないことです。設計意図を知っているのは仕様書の著者だけだから。このパターンをチーム内で共有しておくと、AIを使ったレビューやコード生成で「設計の意図を汲んだ」出力が得られるようになります。 まずは1つの図から試してみてください。 ほなまた。 関連ブログ・参考リンク 関連ブログ Claude Code設計術:AIフレンドリーなドキュメント管理 今回の記事の前提となる考え方です。テキストドキュメントをリポジトリに集約してAIが自然に参照できる状態を作る設計パターンを解説しています。 Claude Codeに専門知識を仕込む:調査→構造化→注入の設計パターン AIへのコンテキスト注入を「調査→構造化→注入」の3ステップで設計するパターンを紹介。今回のHTMLコメント手法も同じ思想の延長線上にあります。 図解作成、AIに丸投げしたら「たまに自分より上手い」件 Claude CodeのSKILL機能でHTML図解を自動生成し、CLIでPNG変換する方法を紹介しています。図の生成手段を増やしたい人はこちらもどうぞ。 ClaudeでMermaid図作成を自動化!2時間→5分の劇的時短術 Mermaidでフローチャート・シーケンス図・パイチャートを自動生成する方法を解説。今回の記事でソースコードとして使うMermaid記法の書き方はこちらを参照してください。 Claude Codeで仕様書のPlantUML図を自動生成 — VS Codeプレビューで完結 PlantUMLのアクティビティ図・ユースケース図・コンポーネント図をClaude Codeで生成し、VS Code上でプレビューする方法を解説。Mermaidでは作れない図が必要なときはこちら。 Mermaid × Tailwind CSS — ハイブリッド図解の作り方 Mermaid図にTailwind CSSの装飾を組み合わせて設計書品質のPNGに変換する実践方法。見た目をカスタマイズしたいときはこちら。 PlantUMLの表現力をTailwind CSSで設計書品質に仕上げる PlantUML図をTailwind CSSで装飾してPNGに変換するテンプレート付き。コンポーネント図・アクティビティ図・ユースケース図に対応。 参考リンク Mermaid.js公式 Anthropic: Effective Context Engineering for AI Agents ご覧いただきありがとうございます! この投稿はお役に立ちましたか? 役に立った 役に立たなかった 0人がこの投稿は役に立ったと言っています。 The post 仕様書の図はAIに読ませるな — 軽量コードを添える設計パターン first appeared on SIOS Tech Lab .
アバター
テキストベースの図、もっと表現力が欲しい ども! PlantUML × VS Codeの記事 を書いた龍ちゃんです。 Claude Codeを使って爆速でPlantUMLを書けるようになりました。でも!実際に設計書やブログに貼るとなると「もうちょっと見た目をなんとかしたい」ってなるんですよね。図の横に設計ポイントを添えたり、色を揃えて見やすくしたり。 そこで今回は、PlantUMLの図にTailwind CSSの装飾を組み合わせます。1つのHTMLファイルにPlantUML図 + 注釈パネルをまとめて、PNGに変換する仕組みです。 「なんでPlantUML?」理由はシンプルで、Mermaidではカバーできない図があるからです。 コンポーネント図 — database "PostgreSQL" と書くだけであのドラム型DBアイコンが出る アクティビティ図 — ワークフローの分岐・マージを if/else/endif で描ける ユースケース図 — actor "ユーザー" で棒人間アイコンが出る Mermaidはフロー図やシーケンス図が得意ですけど、この3つは守備範囲外なんですよね。PlantUMLならテキストベースのまま作れます。 Mermaid × Tailwind CSSの組み合わせも同時に記事にしてます。フロー図やシーケンス図を作りたい人は「 Mermaid × Tailwind CSS — ハイブリッド図解の作り方 」をどうぞ。 今回の内容です。 コピペ用テンプレート2種(右サイド注釈型 / 左右均等型) PNG変換の手段3つ 関連記事 : 仕様書の図にソースコードと設計意図を添える方法については「 仕様書の図はAIに読ませるな — 軽量コードを添える設計パターン 」で詳しく書いてます。AIに図の構造を正確に伝えたい人はこちらもどうぞ。 テンプレートA: 右サイド注釈型 コピペして使えるHTMLテンプレートを2種類用意しました。 仕組みはシンプルで、plantuml-encoderというライブラリでPlantUML構文をエンコードしてplantuml.comに投げるだけです。Tailwind CDNとの共存も問題なし。テンプレートをコピペすればそのまま動きます。plantuml.comへの通信が発生するのでネット接続は必要ですが、大抵の開発環境では問題にならないです。 まずはテンプレートA。左にPlantUMLで描画したコンポーネント図、右にTailwind CSSで装飾した注釈パネルを並べるレイアウトです。ドラム型のDB記号やキュー記号が見えるのがPlantUMLならではのポイントですね。 向いてる場面 : 横に広がる図(コンポーネント図、シーケンス図)に設計ポイントを3-4個添えたいとき キャンバスサイズ : 1280x720px <!DOCTYPE html> <html lang="ja"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>コンポーネント図: 3層アーキテクチャ</title> <script src="https://cdn.tailwindcss.com"></script> <script src="https://cdn.jsdelivr.net/npm/plantuml-encoder@1.4.0/dist/plantuml-encoder.min.js"></script> <style> body { width: 1280px; height: 720px; margin: 0; padding: 0; background: white; overflow: hidden; } </style> </head> <body class="p-8"> <div class="h-full flex flex-col"> <!-- タイトル --> <h1 class="text-2xl font-bold mb-6 text-gray-800">コンポーネント図: 3層アーキテクチャ</h1> <!-- メインコンテンツ: 2カラム --> <div class="flex gap-6 flex-1"> <!-- 左: PlantUML図 --> <div class="flex-1 flex flex-col"> <div class="bg-blue-50 border-2 border-blue-300 rounded-lg p-4 flex-1 flex items-center justify-center"> <div id="diagram-container" class="flex items-center justify-center"> <p class="text-gray-500">Loading diagram...</p> </div> </div> </div> <!-- 右: 注釈パネル --> <div class="w-72 flex flex-col gap-4"> <div class="bg-yellow-50 border border-yellow-300 rounded-lg p-4"> <h3 class="font-bold text-yellow-800 mb-2">フロントエンド層</h3> <p class="text-sm text-yellow-900">Web・モバイルの2系統。APIゲートウェイを経由して統一的にアクセス</p> </div> <div class="bg-blue-50 border border-blue-300 rounded-lg p-4"> <h3 class="font-bold text-blue-800 mb-2">バックエンド層</h3> <p class="text-sm text-blue-900">認証・記事・通知をマイクロサービスに分離。ゲートウェイでルーティング</p> </div> <div class="bg-green-50 border border-green-300 rounded-lg p-4"> <h3 class="font-bold text-green-800 mb-2">データ層</h3> <p class="text-sm text-green-900">PostgreSQL + Redis + メッセージキューの3点セット。非同期処理はキュー経由</p> </div> </div> </div> </div> <script> window.addEventListener('DOMContentLoaded', function() { const umlSource = `@startuml skinparam style strictuml skinparam backgroundColor transparent package "フロントエンド" { [Webアプリ] as Web [モバイルアプリ] as Mobile } package "バックエンド" { [APIゲートウェイ] as GW [認証サービス] as Auth [記事サービス] as Article [通知サービス] as Notify } package "データ層" { database "PostgreSQL" as DB database "Redis" as Cache queue "メッセージキュー" as MQ } Web --> GW Mobile --> GW GW --> Auth GW --> Article Article --> DB Article --> Cache Article --> MQ MQ --> Notify Auth --> DB @enduml`; try { const encoded = plantumlEncoder.encode(umlSource); const imgUrl = `https://www.plantuml.com/plantuml/svg/${encoded}`; const container = document.getElementById('diagram-container'); container.innerHTML = `<img src="${imgUrl}" alt="コンポーネント図" class="max-w-full max-h-full" />`; } catch (error) { console.error('Error encoding PlantUML:', error); document.getElementById('diagram-container').innerHTML = `<p class="text-red-500">Failed to load diagram: ${error.message}</p>`; } }); </script> </body> </html> 差し替えは3箇所だけです。 PlantUML構文 ( const umlSource の中身)を自分の図に差し替える 注釈パネルの内容 (右側の3つのパネル)を自分の設計ポイントに差し替える タイトル を差し替える 注釈パネルは増減しても大丈夫です。3個が収まりいいですけど、2個でも4個でもレイアウトは崩れません。 skinparamについて Mermaid編では themeVariables で図の配色をTailwindのカラーパレットに合わせましたね。PlantUMLでは skinparam が同じ役割です。 skinparam style strictuml skinparam backgroundColor transparent backgroundColor transparent で背景を透明にするだけで、Tailwind側の bg-blue-50 と自然に馴染みます。追加で色をカスタマイズしたい場合はこんな設定もあります。 skinparam packageBackgroundColor #f0f9ff skinparam ArrowColor #3b82f6 skinparam ParticipantBackgroundColor #dbeafe Mermaidの themeVariables ほど細かい制御はできないですけど、背景透明にするだけで大抵は十分です。もっと細かく調整したい人は PlantUML公式のskinparamリファレンス を参照してください。 PlantUML固有の記法 テンプレートのコードで使ってる記法と、他の図で使える記法をまとめておきます。 テンプレートAで使用 : 記法 表示 database "名前" ドラム型DB記号 queue "名前" キュー型記号 package "名前" { ... } パッケージでグループ化 他の図で使える記法 : 記法 用途 == フェーズ名 == シーケンス図のフェーズ分割 alt / else / end 条件分岐ブロック ref over A, B 外部参照 left to right direction ユースケース図の横向きレイアウト テンプレートB: 左右均等型 テンプレートAだと、縦長の図のときに左側のスペースが余ります。アクティビティ図やユースケース図は縦に伸びるんで、横幅を半々にして右側に説明を置くほうが収まりがいいです。 向いてる場面 : 縦長の図(アクティビティ図、ユースケース図)に説明を横に並べたいとき キャンバスサイズ : 1280x720px <!DOCTYPE html> <html lang="ja"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>アクティビティ図: ユーザー登録フロー</title> <script src="https://cdn.tailwindcss.com"></script> <script src="https://cdn.jsdelivr.net/npm/plantuml-encoder@1.4.0/dist/plantuml-encoder.min.js"></script> <style> body { width: 1280px; height: 720px; margin: 0; padding: 0; background-color: white; overflow: hidden; } </style> </head> <body class="flex"> <!-- 左: PlantUML図 --> <div class="w-1/2 flex items-center justify-center p-8"> <div id="diagram-container"></div> </div> <!-- 右: 注釈パネル --> <div class="w-1/2 flex flex-col justify-center p-8 space-y-6"> <h1 class="text-3xl font-bold text-gray-800 mb-4">ユーザー登録フロー</h1> <div class="bg-yellow-100 border-l-4 border-yellow-500 p-4"> <p class="text-gray-800 font-semibold">バリデーション</p> <p class="text-sm text-gray-600 mt-1">フォーム入力後、サーバー側でバリデーション。失敗時はエラーメッセージを表示してフォームに戻す</p> </div> <div class="bg-blue-100 border-l-4 border-blue-500 p-4"> <p class="text-gray-800 font-semibold">DB保存とリトライ</p> <p class="text-sm text-gray-600 mt-1">保存失敗時はエラーログを記録してリトライ画面を表示。ユーザーに再試行の機会を与える</p> </div> <div class="bg-green-100 border-l-4 border-green-500 p-4"> <p class="text-gray-800 font-semibold">完了通知</p> <p class="text-sm text-gray-600 mt-1">保存成功時は完了メールを送信してから完了画面を表示。メール送信は非同期でもOK</p> </div> </div> <script> window.addEventListener('DOMContentLoaded', () => { const plantUmlSource = `@startuml start :ユーザーがフォームを入力; if (バリデーション?) then (成功) :データベースに保存; if (保存成功?) then (はい) :完了メールを送信; :完了画面を表示; else (いいえ) :エラーログを記録; :リトライ画面を表示; endif else (失敗) :エラーメッセージを表示; :フォームに戻る; endif stop @enduml`; const encoded = plantumlEncoder.encode(plantUmlSource); const img = document.createElement('img'); img.src = `https://www.plantuml.com/plantuml/svg/${encoded}`; img.alt = 'アクティビティ図: ユーザー登録フロー'; img.className = 'max-w-full max-h-full'; document.getElementById('diagram-container').appendChild(img); }); </script> </body> </html> 差し替えポイントはテンプレートAと同じ3箇所です。PlantUML構文、注釈パネル、タイトル。実例はアクティビティ図ですけど、ユースケース図を作りたい場合も const plantUmlSource の中身を差し替えるだけです。 テンプレートAとの違いは2つです。 レイアウトが左右均等 ( w-1/2 + w-1/2 )。図と注釈が50:50で並ぶんで、縦長の図に余裕ができます 注釈のスタイルが border-l-4 (左ボーダーアクセント)。テンプレートAのカード型とは雰囲気が変わります Mermaid編のテンプレートBは縦拡張(1280x1080px)でしたけど、PlantUML編は標準の1280x720pxです。PlantUMLはサーバー側で描画するんで、Mermaidの自動縮小問題がない。CSS transformも不要です。 テンプレート使い分け 条件 テンプレート 横に広がる図(コンポーネント図、シーケンス図) A: 右サイド注釈型 縦長の図(アクティビティ図、ユースケース図) B: 左右均等型 注釈が少ない(2-3個) A 注釈にテキストが多い B 迷ったらテンプレートAで試して、図が窮屈ならBに切り替えてください。 PNG変換 — 3つの手段 手段は3つあります。好みと環境に合わせて選んでください。 手段 自動化 セットアップ 向いてる用途 CLIツール(html-screenshot) できる Python + Playwright 量産やCI/CD Playwright MCP できる MCP設定 Claude Code連携 ブラウザで直接開く 手動 なし 手軽に確認 CLIツール uv run html-screenshot --file template-a.html --output template-a.png 以前の記事 で紹介したhtml-screenshotツールがそのまま使えます。Playwrightの wait_until="networkidle" がplantuml.comからのSVG取得完了を待ってくれるんで、PlantUML図の描画が終わってからスクリーンショットを撮ってくれます。 Playwright MCP Claude CodeからPlaywrightのブラウザ操作を直接呼び出す方法もあります。HTMLファイルを開いてスクリーンショットを撮る操作がMCPのツールで完結します。 Playwright MCPの記事 で詳しく書いてるんで、Claude Code使ってる人はこっちが楽です。 ブラウザで直接開く 一番手軽なのはHTMLファイルをブラウザで直接開くことですね。Tailwind CDNとplantuml-encoder CDNが読み込まれて、PlantUML図がそのまま描画されます。PNG変換は手動(DevToolsやOS標準のスクリーンショット)になりますけど、「ちょっと確認したい」くらいならこれで十分です。 まとめ Mermaid編のテンプレート2種 + 今回のPlantUML編テンプレート2種で、計4種類が揃いました。 テンプレート 図の描画 向いてる図 Mermaid A: 右サイド注釈型 Mermaid フロー、シーケンス、状態遷移 Mermaid B: 下部グリッド注釈型 Mermaid 複雑なシーケンス PlantUML A: 右サイド注釈型 PlantUML コンポーネント、シーケンス PlantUML B: 左右均等型 PlantUML アクティビティ、ユースケース フロー図、シーケンス図、状態遷移図に加えて、アクティビティ図、ユースケース図、コンポーネント図もカバーできるようになりました。特にコンポーネント図の database でドラム型DBアイコンが出せるのは、アーキテクチャ図を書く人にはかなり便利です。 おまけとして、Mermaid編でも触れましたがこのテンプレートで作った図はAI連携にも使えます。PlantUMLもMermaidと同じく宣言的記法なんで、AIが構造を正確に読み取れます。注釈パネルに設計意図を書いておけば、人間が見ても、AIが読んでもどっちにも伝わる。この辺の話は 仕様書の図にソースコードを添える設計パターン で詳しく書いてます。 もう1つ。このテンプレートを毎回コピペするのも手ですけど、Claude Codeの SKILL機能 にreference(参考例)として登録しておくと、「シーケンス図作って」と言うだけでテンプレートに沿った図が出てきます。テンプレートのクオリティがそのままSKILLのクオリティになるんで、良いテンプレートを貯める = 図解の品質を底上げする、という流れができます。コピペ用テンプレートとSKILL化、好きなほうで使ってください。 ほなまた〜 関連ブログ 今回の記事はシリーズの一部です。 Mermaid × Tailwind CSS — ハイブリッド図解の作り方 — 今回の前編。Mermaid + Tailwind CSSのテンプレート2種を紹介してます。まだ読んでない人はこちらから。 ClaudeでMermaid図作成を自動化!プロンプトテンプレート集も公開 — シリーズの出発点。Mermaid記法をAIで生成するところから始めたい人はここから。 図解作成、AIに丸投げしたら「たまに自分より上手い」件 — HTML+Tailwind CSSで図解を丸ごとAIに作らせる方法。フロー図以外の図解(比較図、アーキテクチャ図とか)はこっちが向いてます。 仕様書の図はAIに読ませるな — 軽量コードを添える設計パターン — 仕様書をAIと共有してるチーム向け。図にソースコードと設計意図を添えて、AIの「推測」をなくす方法です。 Claude CodeでPlantUML × VS Code Preview — PlantUMLの基礎とVS Codeでのプレビュー設定。PlantUML自体が初めての人はこちらが入門になります。 Playwright MCPで始めるブラウザ自動化 — PNG変換の手段の1つとして紹介したPlaywright MCP。Claude Codeからブラウザ操作を直接呼び出せます。 ご覧いただきありがとうございます! この投稿はお役に立ちましたか? 役に立った 役に立たなかった 0人がこの投稿は役に立ったと言っています。 The post PlantUMLの表現力をTailwind CSSで設計書品質に仕上げる first appeared on SIOS Tech Lab .
アバター
Mermaidの見た目、もうちょっとなんとかならんか ども!Mermaidで図を作るたびに「構造は最高なんだけど、見た目がなぁ…」と思ってた龍ちゃんです。 「 Claude CodeでMermaid図を作成する 」でMermaid図の自動生成について書きました。Mermaidはコードで構造を書けるから、フローチャートやシーケンス図がサクッと作れます。AIに「こういう図作って」って言えば一発で出てくるんですよね。 ただ、デフォルトのデザインがシンプルすぎるんですよね。設計書やブログに貼るにはちょっと素朴。 HTML+Tailwind CSSで図解を丸投げする方法 も試したんですよ。装飾の自由度は高いんですけど、フロー図やシーケンス図をCSSで手動配置するのが辛い。特に矢印の表現が鬼の難易度です。Mermaidが自動でやってくれる部分を手で書くのはしんどいです。 じゃあ合体させたらどうだ、と。 Mermaidの構造表現力 + Tailwind CSSの装飾力 。Mermaidに図の構造を任せて、周りの見た目はTailwindで自由に作れます。これを1つのHTMLファイルにまとめてPNGに変換します。 今回の内容です。 コピペで使えるHTMLテンプレート2種(右サイド注釈型 / 下部グリッド注釈型) 色を揃えるカスタマイズのコツ 実際にぶつかった壁と対処法 PNG変換の手段3つ まず完成形を見せます こういうのが作れます。 左がMermaidで描画したシーケンス図、右がTailwind CSSで装飾した注釈パネル。これ、1つのHTMLファイルから出てきます。 ポイントは、Mermaid図の色とTailwind装飾の色が揃ってるところですね。青系で統一してるから、「Mermaidの部分だけ浮いてる」みたいなことにならない。 注釈パネルには設計ポイント、セキュリティ考慮、エラーハンドリングみたいな文脈情報を書けます。Mermaid図だけだと「何が起きてるか」は分かるけど「なぜこうしたか」は伝わらないんですよね。注釈パネルがその「なぜ」を補ってくれます。 関連記事 : 仕様書の図でAIの理解と人間の視認性を両立する方法に関しては「 仕様書の図はAIに読ませるな — 軽量コードを添える設計パターン 」で詳しく書いてます。AIに図の構造を正確に伝えたい人はこちらもどうぞ。 テンプレートA: 右サイド注釈型 ここからが本題です。コピペして使えるHTMLテンプレートを2種類用意しました。 仕組みはシンプルで、1つのHTMLにTailwind CDNとMermaid CDN(ESM版)を同時に読み込んでるだけです。2つのCDNは競合しません(検証済み)。テンプレートをコピペすればそのまま動きます。色のカスタマイズについてはテンプレートの後で説明しますね。 まずはテンプレートA。冒頭で見せた完成形がこれです。左にMermaid図、右に注釈パネルを並べるレイアウトですね。 向いてる場面 : シンプルな図(ノード8個以下)に設計ポイントを3-4個添えたいとき キャンバスサイズ : 1280x720px <!DOCTYPE html> <html lang="ja"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Level 2: Mermaid + Tailwind CSS Decoration</title> <script src="https://cdn.tailwindcss.com"></script> </head> <body class="w-[1280px] h-[720px] m-0 p-0 overflow-hidden bg-white"> <div class="w-full h-full flex gap-6 p-10"> <!-- 左: Mermaid図 --> <div class="flex-1 border-2 border-blue-300 rounded-lg p-6 bg-blue-50"> <h2 class="text-xl font-bold text-blue-900 mb-4">認証フローのシーケンス図</h2> <div class="mermaid"> sequenceDiagram participant C as クライアント participant S as サーバー participant DB as データベース C->>+S: ログインリクエスト S->>+DB: ユーザー照合 DB-->>-S: 認証結果 alt 認証成功 S-->>C: アクセストークン発行 else 認証失敗 S-->>C: エラーレスポンス(401) end </div> </div> <!-- 右: 注釈パネル --> <div class="w-72 flex flex-col gap-3"> <div class="bg-yellow-50 border border-yellow-300 rounded p-3"> <h3 class="text-sm font-bold text-yellow-800">設計ポイント</h3> <p class="text-xs text-yellow-700">DB直接参照を避け、サービス層を経由させることで結合度を低減</p> </div> <div class="bg-green-50 border border-green-300 rounded p-3"> <h3 class="text-sm font-bold text-green-800">セキュリティ考慮</h3> <p class="text-xs text-green-700">トークンはJWT形式、有効期限15分で自動失効</p> </div> <div class="bg-red-50 border border-red-300 rounded p-3"> <h3 class="text-sm font-bold text-red-800">エラーハンドリング</h3> <p class="text-xs text-red-700">認証失敗時は具体的なエラー原因を返さない(セキュリティ対策)</p> </div> </div> </div> <script type="module"> import mermaid from 'https://cdn.jsdelivr.net/npm/mermaid@11/dist/mermaid.esm.min.mjs'; mermaid.initialize({ startOnLoad: true, theme: 'base', themeVariables: { primaryColor: '#dbeafe', primaryBorderColor: '#3b82f6', lineColor: '#6b7280', fontFamily: 'system-ui, sans-serif' } }); </script> </body> </html> 使い方はシンプルで、3箇所を差し替えるだけです。 Mermaid記法の部分 ( <div class="mermaid"> の中身)を自分の図に差し替える 注釈パネルの内容 (右側の3つのパネル)を自分の設計ポイントに差し替える themeVariables で色を変えたければカラーコードを調整する 注釈パネルは増減しても大丈夫です。3個が収まりいいですけど、2個でも4個でもレイアウトは崩れません。 色の統一について 完成形の画像を見て「Mermaid図と注釈パネルの色が揃ってるな」と思った人もいるかもしれません。これはテンプレート末尾の themeVariables でMermaid図の配色をTailwindのカラーパレットに合わせてるからです。 themeVariables: { primaryColor: '#dbeafe', // Tailwind blue-100 primaryBorderColor: '#3b82f6', // Tailwind blue-500 lineColor: '#6b7280', // Tailwind gray-500 fontFamily: 'system-ui, sans-serif' } 色を変えたいときはここのカラーコードを差し替えてください。 Tailwindのカラーパレット から持ってくると注釈パネル側と揃えやすいです。 1つ注意点として、 Mermaid図の中にTailwindクラスは効きません 。Mermaid図はSVGとして生成されるんで、外部CSSが適用できないんですよね。色のカスタマイズは themeVariables 経由のみです。 テンプレートB: 下部グリッド注釈型 テンプレートAだと、図が複雑になったときに左側のスペースが足りなくなります。シーケンス図で参加者が4人以上いたり、メッセージが10本近くあると、右の注釈パネルに幅を取られて図が窮屈になるんですよね。 そういうときはテンプレートBです。図を上部に全幅で配置して、注釈パネルは下部にグリッドで並べます。 向いてる場面 : 複雑な図(10ステップ近いシーケンス、状態遷移図)で図に全幅を使いたいとき キャンバスサイズ : 1280x1080px(縦に拡張) <!DOCTYPE html> <html lang="ja"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>OAuth 2.0 認可コードフロー</title> <script src="https://cdn.tailwindcss.com"></script> <style> .mermaid svg { transform: scale(3.2); transform-origin: center center; } </style> <script type="module"> import mermaid from 'https://cdn.jsdelivr.net/npm/mermaid@11/dist/mermaid.esm.min.mjs'; mermaid.initialize({ startOnLoad: true, theme: 'base', sequence: { diagramMarginX: 10, diagramMarginY: 10, actorMargin: 80, messageMargin: 40 }, themeVariables: { primaryColor: '#e0f2fe', primaryBorderColor: '#0284c7', primaryTextColor: '#0c4a6e', lineColor: '#64748b', fontFamily: 'system-ui, sans-serif' } }); </script> </head> <body class="w-[1280px] h-[1080px] m-0 p-0 overflow-hidden bg-white"> <div class="w-full h-full flex flex-col p-8 gap-6"> <!-- 上部: タイトル --> <div> <div class="text-lg font-bold text-gray-800">OAuth 2.0 認可コードフロー</div> <div class="text-sm text-gray-500">ソーシャルログイン実装の標準パターン</div> </div> <!-- 中央: 図(全幅) --> <div class="flex-1 border border-gray-200 rounded-lg p-6 bg-gray-50 flex items-center justify-center"> <div class="mermaid"> sequenceDiagram actor U as ユーザー participant App as Webアプリ participant Auth as 認可サーバー participant API as リソースサーバー U->>App: ログインボタンクリック App->>Auth: 認可リクエスト(client_id, redirect_uri, scope) Auth->>U: ログイン画面表示 U->>Auth: 認証情報入力 Auth->>App: 認可コード(code) App->>Auth: トークンリクエスト(code, client_secret) Auth->>App: アクセストークン + リフレッシュトークン App->>API: APIリクエスト(Bearer token) API->>App: リソースデータ App->>U: ユーザー情報表示 </div> </div> <!-- 下部: 注釈パネル(横並び) --> <div class="grid grid-cols-4 gap-3"> <div class="bg-blue-50 border border-blue-200 rounded-lg p-3"> <div class="text-sm font-bold text-blue-800">フロー概要</div> <div class="text-xs text-blue-700 mt-1">RFC 6749準拠の認可コードグラント。SPAではPKCE拡張を推奨。</div> </div> <div class="bg-amber-50 border border-amber-200 rounded-lg p-3"> <div class="text-sm font-bold text-amber-800">セキュリティ要件</div> <div class="text-xs text-amber-700 mt-1 space-y-1"> <div>state パラメータでCSRF対策</div> <div>client_secret はサーバー側で保持</div> <div>redirect_uri の完全一致検証</div> </div> </div> <div class="bg-green-50 border border-green-200 rounded-lg p-3"> <div class="text-sm font-bold text-green-800">実装チェックリスト</div> <div class="text-xs text-green-700 mt-1 space-y-1"> <div>トークンの安全な保存(httpOnly cookie)</div> <div>リフレッシュトークンのローテーション</div> <div>スコープの最小権限原則</div> </div> </div> <div class="bg-gray-100 border border-gray-200 rounded-lg p-3"> <div class="text-sm font-bold text-gray-700">補足</div> <div class="text-xs text-gray-600 mt-1">アクセストークンの有効期限は15分〜1時間が一般的。期限切れ時はリフレッシュトークンで自動更新。</div> </div> </div> </div> </body> </html> テンプレートAとの違いは3つです。 キャンバスが縦に拡張 (720px → 1080px)。図に余裕ができます 注釈パネルが下部グリッド 。図が全幅を使えるんで、参加者が4人いても窮屈になりません CSS transformでMermaid図を拡大 ( scale(3.2) )。Mermaidは複雑な図を自動縮小するんで、それを補正してます scaleの調整について テンプレートBの scale(3.2) は、上のOAuth 2.0の例(参加者4人・メッセージ10本)に合わせた値です。自分の図に差し替えたら、scaleも調整が必要です。 Mermaidは図の複雑度に応じて自動縮小するんですけど、その縮小率が図ごとに変わるんですよね。なので 図を差し替えるたびにscaleを微調整する のが前提の設計です。 調整の手順はシンプルで、HTMLファイルをブラウザで開いて、文字が読める大きさになるまで scale の数値を上げ下げするだけです。目安としてはこんな感じ。 図の複雑度 scale目安 シンプル(参加者2-3人、メッセージ5本以下) 1.5〜2.0 中程度(参加者3-4人、メッセージ8本前後) 2.5〜3.5 複雑(参加者4人以上、メッセージ10本以上) 3.0〜4.0 どっちを使う? 条件 テンプレート 図がシンプル(ノード8以下) A: 右サイド注釈型 図が複雑、横に広がる B: 下部グリッド注釈型 注釈が少ない(2-3個) A 注釈が多い(4個以上) B 迷ったらまずテンプレートAで試して、図が窮屈ならBに切り替える、でいいと思います。 ぶつかった壁と対処 検証してて何度かハマったので、先に共有しておきます。 ノード数には上限がある Mermaidは図の要素が増えると自動で縮小するんですよね。1280pxの幅に収めようとするから、ノードが多いと文字が潰れて読めなくなります。 実際に検証して、このくらいが上限だなというラインが見えました。 図の種類 推奨上限 超えるとどうなるか フローチャート 8-10ノード 文字が小さくなって読めない シーケンス図 4参加者・8メッセージ ラベルが長いと自動縮小される 状態遷移図 8-10状態 縦に伸びてキャンバスからはみ出す 上限を超えそうなときは、図を分割するか、テンプレートBでキャンバスを拡張するのがいいです。 サイズ問題の対策3種 実際にぶつかったサイズ問題と、それぞれの対処法です。 症状 対策 やり方 図がキャンバスからはみ出す キャンバスを拡張する h-[720px] → h-[1080px] に変更。PNG変換時も --height 1080 を指定 図が小さすぎて読めない CSS transformで拡大 .mermaid svg { transform: scale(X); } を追加 右の注釈パネルが図を圧迫する 注釈を下部に移動 テンプレートAからBに切り替える この3つの対策は組み合わせられます。テンプレートBはキャンバス拡張 + CSS transform + 下部グリッドの3つ全部入りですね。制約はあるけど対策は全部見つかってるんで、複雑な図はまずBを試してみてください。 PNG変換 — 3つの手段 HTMLファイルが完成したら、PNG画像に変換してブログや設計書に貼れます。手段は3つあって、好みと環境に合わせて選んでください。 手段 自動化 セットアップ 向いてる用途 CLIツール(html-screenshot) できる Python + Playwright 量産やCI/CD Playwright MCP できる MCP設定 Claude Code連携 ブラウザで直接開く 手動 なし 手軽に確認 CLIツール uv run html-screenshot --file template-a.html --output template-a.png 以前の記事 で紹介したhtml-screenshotツールがそのまま使えます。改修なしでMermaid CDNの読み込みにも対応してました。Playwrightの wait_until="networkidle" がCDN読み込み完了を待ってくれるんで、Mermaid図の描画が終わってからスクリーンショットを撮ってくれます。 テンプレートBのように高さを変えたい場合は --height 1080 を付けます。 Playwright MCP Claude CodeからPlaywrightのブラウザ操作を直接呼び出す方法もあります。HTMLファイルを開いてスクリーンショットを撮る操作がMCPのツールで完結します。 Playwright MCPの記事 で詳しく書いてるんで、Claude Code使ってる人はこっちが楽かもしれません。 ブラウザで直接開く 一番手軽なのはHTMLファイルをブラウザで直接開くことですね。Mermaid CDNが読み込まれて図がそのまま描画されます。PNG変換は手動(ブラウザのDevToolsやOS標準のスクリーンショット)になりますけど、「ちょっと確認したい」くらいならこれで十分です。 まとめ ノード数の上限やサイズ問題はありましたけど、全部対処法が見つかりました。制約を把握しておけばハマることはないです。 今回のポイントです。 「構造はMermaid、装飾はTailwind」の役割分担 。Mermaidが得意な構造の自動レイアウト(矢印の接続、参加者の配置、分岐の描画)はMermaidに任せて、周りの装飾(注釈パネル、色統一、レイアウト)はTailwind CSSで自由に作る。 テンプレートの使い分けはシンプルです。 条件 テンプレート シンプルな図 + 注釈少なめ A: 右サイド注釈型(1280×720) 複雑な図 + 注釈多め B: 下部グリッド注釈型(1280×1080) あと、おまけとして1つ。このテンプレートで作った図はAI連携にも強いです。Mermaidのソースコードは宣言的な記法( sequenceDiagram 、 graph TD とか)なんで、AIが構造を正確に読み取れます。注釈パネルに設計意図を書いておけば、人間が見ても、AIが読んでもどっちにも伝わる。この辺の話は 仕様書の図にソースコードを添える設計パターン で詳しく書いてるんで、興味あれば読んでみてください。 もう1つ。このテンプレートを毎回コピペするのも手ですけど、Claude Codeの SKILL機能 にreference(参考例)として登録しておくと、「シーケンス図作って」と言うだけでテンプレートに沿った図が出てきます。テンプレートのクオリティがそのままSKILLのクオリティになるんで、良いテンプレートを貯める = 図解の品質を底上げする、という流れができます。コピペ用テンプレートとSKILL化、好きなほうで使ってください。 PlantUML編も書きました。Mermaidが苦手な図種(アクティビティ図、ユースケース図、コンポーネント図)をPlantUMLでカバーする話です。「 PlantUMLの表現力をTailwind CSSで設計書品質に仕上げる 」をどうぞ。 ほなまた〜 関連ブログ 今回の記事はシリーズの一部です。Mermaid図の生成からHTML図解、仕様書への活用まで、一連の流れで読めます。 ClaudeでMermaid図作成を自動化!プロンプトテンプレート集も公開 — 今回の出発点。Mermaid記法をAIで生成するところから始めたい人はここから。プロンプトテンプレートも載せてます。 図解作成、AIに丸投げしたら「たまに自分より上手い」件 — HTML+Tailwind CSSで図解を丸ごとAIに作らせる方法。フロー図以外の図解(比較図、アーキテクチャ図とか)はこっちが向いてます。 仕様書の図はAIに読ませるな — 軽量コードを添える設計パターン — 仕様書をAIと共有してるチーム向け。図にソースコードと設計意図を添えて、AIの「推測」をなくす方法です。 Playwright MCPで始めるブラウザ自動化 — PNG変換の手段の1つとして紹介したPlaywright MCP。Claude Codeからブラウザ操作を直接呼び出せます。 ご覧いただきありがとうございます! この投稿はお役に立ちましたか? 役に立った 役に立たなかった 0人がこの投稿は役に立ったと言っています。 The post Mermaidのデザインが物足りない?Tailwindで拡張して設計書品質に first appeared on SIOS Tech Lab .
アバター
PlantUMLもClaude Codeで書きたい ども!Claude Codeで仕様書を書く方法を模索している龍ちゃんです。 以前、 ClaudeでMermaid図作成を自動化する記事 を書きました。あの記事のおかげで図解作成がめちゃくちゃ楽になったんですが、しばらく使ってるうちに壁にぶつかりました。 アクティビティ図が作れない。ユースケース図も作れない。 PlantUMLなら作れる。確認はVS Code上のMarkdown Previewで完結する。今回はその設定方法と実践例を紹介します。 Mermaidは便利だけど、対応していない図の種類があるんです。仕様書を書いてると「ここはアクティビティ図で表現したい」「アクターの関係をユースケース図で見せたい」って場面が出てきます。Mermaidのフローチャートで無理やり代用しても、分岐やマージが不自然になる。 そこで PlantUML の出番です。 今回は、Claude CodeでPlantUMLの図を生成して、VS Code上のMarkdown Previewでそのまま確認する方法を解説します。VS Code上に拡張機能を入れるだけですぐ確認できていたのですが、PlantUMLではちょっとしたコツが必要になったので紹介していきます。 この記事でわかること: Mermaidでは作れないアクティビティ図・ユースケース図・コンポーネント図をPlantUMLで作る方法 VS Code上でPlantUML図をプレビュー表示する環境設定(Markdown Preview Enhanced + Kroki.io) Claude Codeと組み合わせた実践的な作業フロー 前提環境 : VS Code 1.85以上、インターネット接続必須(Kroki.ioサーバーとの通信に必要) なぜPlantUMLなのか? MermaidとPlantUMLの使い分け 全部PlantUMLに乗り換えろという話ではないです。Mermaidが得意な領域はMermaidを使えばいい。PlantUMLが必要になるのは、Mermaidでは作れない図を描くときだけです。 こういう図なら こっちを使う 理由 フローチャート Mermaid 記法がシンプル、学習コスト低い シーケンス図(シンプル) Mermaid 4参加者程度ならMermaidで十分 状態遷移図 Mermaid stateDiagram-v2が使いやすい ER図 Mermaid erDiagramが直感的 パイチャート Mermaid Mermaid専用機能 アクティビティ図 PlantUML Mermaid非対応。if/else分岐の自然な表現 ユースケース図 PlantUML Mermaid非対応。UML標準のアクター記法 コンポーネント図 PlantUML database/queue専用記号が使える 複雑なシーケンス図 PlantUML ==フェーズ分割==、ref over が使える UML準拠が求められる設計書 PlantUML UML 2.0標準に準拠 シンプルな結論: 迷ったらMermaid。アクティビティ図・ユースケース図・コンポーネント図の3パターンだけPlantUML。 PlantUML固有の強み PlantUMLでしか使えない表現がいくつかあります。記事の後半で実際に使いますが、先に紹介しておきます。 database "名前" — ドラム型のデータベース記号。Mermaidでは汎用の四角になる queue "名前" — キュー型の記号。メッセージキューの表現に最適 == フェーズ名 == — シーケンス図をフェーズで区切る。認証→データ取得のような段階を明示できる left to right direction — ユースケース図の横向きレイアウト。縦長にならず収まりがいい if/else/endif — アクティビティ図の条件分岐。ネストも可能 VS Code Preview設定方法 ここが記事の核です。一度設定すれば、あとはMarkdownに書くだけでPlantUML図がプレビュー表示されます。 必要な拡張機能 Markdown Preview Enhanced を使います。 項目 詳細 拡張機能ID shd101wyy.markdown-preview-enhanced バージョン 0.8.20(2025年11月時点) PlantUML対応 Kroki.ioサーバー経由で描画 Mermaid対応 ブラウザ内JSで描画(同時対応) VS Code標準のMarkdownプレビューではPlantUMLは表示されません。Markdown Preview Enhancedの専用プレビューを使う必要があります。 PlantUMLサーバー設定 PlantUMLのコードを画像に変換するサーバーが必要です。 Kroki.io を使います。無料で登録不要です。 注意 : Kroki.ioはパブリックサーバーなので、PlantUMLのコードがインターネット経由で送信されます。社内の機密情報を含む図を描く場合は、 セルフホスト版のKrokiサーバー (Dockerで立てられる)を検討してください。個人のブログ執筆用途であれば問題ないです。 VS Codeの設定で以下を追加します: { "markdown-preview-enhanced.plantumlServer": "https://kroki.io/plantuml/svg/" } これだけです。 devcontainer.jsonへの設定例 devcontainerを使っている場合は、 devcontainer.json に書いておくとチーム全員が同じ設定で使えます。 { "customizations": { "vscode": { "extensions": [ "shd101wyy.markdown-preview-enhanced", "bierner.markdown-mermaid" ], "settings": { "markdown-preview-enhanced.plantumlServer": "https://kroki.io/plantuml/svg/", "markdown-preview-enhanced.previewTheme": "github-dark.css", "markdown-preview-enhanced.mermaidTheme": "dark" } } } } 自分のプロジェクトでは実際にこの設定を使っています。 Markdown Preview Mermaid Support ( bierner.markdown-mermaid )も入れておくと、VS Code標準プレビュー側でMermaidが表示できて便利です。 動作確認 設定が終わったら、以下の手順で確認します。 以下のコードブロックを書く: Markdown Preview Enhanced のプレビューを開く コマンドパレット(Ctrl+Shift+P)→ Markdown Preview Enhanced: Open Preview to the Side ショートカット: Ctrl+K V Markdownファイルを開く @startuml Alice -> Bob: Hello Bob --> Alice: Hi! @enduml プレビューにシーケンス図が表示されたら設定完了です。表示されない場合は、後述のトラブルシューティングを確認してください。 注意 : VS Code標準のMarkdownプレビュー(Ctrl+Shift+V)ではPlantUMLは表示されません。必ずMarkdown Preview Enhanced のプレビューを使ってください。アイコンが異なるので区別できます。 基本的な作業フロー Claude Code連携の流れ Claude Codeで作業する場合の具体的な流れです。 Markdownファイルを開いた状態でClaude Codeにプロンプトを入力 Claude Codeが plantuml コードブロックを含むMarkdownを生成 VS Code上でMarkdown Preview Enhancedのプレビューを確認 修正が必要なら「この図の〇〇を変更して」と追加指示 完成したらそのまま仕様書・設計書として使える エディタとターミナルの行き来だけで完結するのが強みです。 PlantUML公式エディタで確認する方法 VS Code Previewが本記事のメインですが、ブラウザで手軽に確認したい場面もあります。PlantUMLには公式のWebエディタがあるので紹介しておきます。 PlantUML Web Editor 使い方はシンプルです。 上記URLにアクセス 左側のエディタにPlantUMLコードを貼り付ける 約1.5秒後に右側にプレビューが自動表示される ツールバーからPNG/SVGでダウンロードできる Mermaid版の記事で紹介した「Live Editor」のPlantUML版だと思ってください。URLがそのまま図の共有リンクになるので、チームメンバーに「この図見て」と送るときにも使えます。 ただし自分は普段使いではVS Code Previewのほうを使っています。理由は2つあって、エディタから離れなくていいことと、Markdownファイルにそのまま残せること。公式エディタは「VS Codeの設定がまだの環境で急ぎ確認したい」「誰かに図だけ共有したい」ときの補助ツールという位置づけです。 実践①: アクティビティ図 アクティビティ図とは ワークフローや処理の分岐を表現する図です。フローチャートに似ていますが、UMLの正式な図の1つで、条件分岐(if/else)とマージの表現が自然です。 Mermaidのフローチャートでも似たことはできますが、分岐とマージの接続が不自然になりがちです。PlantUMLのアクティビティ図なら、if/else/endifの構文でネストした分岐も綺麗に描けます。 プロンプト例 以下のワークフローをPlantUMLのアクティビティ図で作成してください。 【ワークフロー】ブログ記事の執筆〜公開プロセス 1. 記事のアウトラインを作成 2. Claude Codeで下書きを生成 3. 内容を確認・修正 4. 判定: 技術的に正確か? - YES → ライティングチェックへ - NO → 技術検証をやり直して下書き修正 5. 判定: 品質OK? - YES → サムネイル作成 → WordPress入稿 → 公開 - NO → AIっぽい表現を修正 → 再チェック ```plantuml のコードブロック形式で出力してください。 PlantUMLコード例 @startuml start :記事のアウトラインを作成; :Claude Codeで下書きを生成; :内容を確認・修正; if (技術的に正確?) then (はい) :ライティングチェック; if (品質OK?) then (はい) :サムネイル作成; :WordPressに入稿; :公開; else (いいえ) :AIっぽい表現を修正; :再チェック; endif else (いいえ) :技術検証をやり直す; :下書きを修正; endif stop @enduml VS Code Previewで見ると、こんな感じで表示されます。 分岐のダイヤモンド記号とマージが自然に接続されます。ネストしたif/elseもインデントで表現されるので読みやすい。Mermaidのフローチャートで同じことをやろうとすると、ノード間の矢印を手動で繋ぐ必要があって面倒です。 実践②: ユースケース図 ユースケース図とは システムの機能(ユースケース)と、それを使う人やシステム(アクター)の関係を表現する図です。要件定義の初期段階で「誰が何をするか」を整理するのに使います。 Mermaidにはユースケース図のサポートがないので、PlantUMLの独壇場です。 プロンプト例 以下のシステムのユースケース図をPlantUMLで作成してください。 【システム名】ブログ執筆システム 【アクター】 - エンジニア: 記事執筆、図の生成、コードレビュー - Claude Code: 下書き生成、図の生成、サムネイル作成、SEOチェック、ライティングチェック - レビュアー: コードレビュー 【関係】 - 図の生成と記事執筆にはinclude関係がある - SEOチェックと記事執筆にもinclude関係がある left to right direction で横向きレイアウトにしてください。 ```plantuml のコードブロック形式で出力してください。 PlantUMLコード例 @startuml left to right direction actor "エンジニア" as Engineer actor "Claude Code" as Claude actor "レビュアー" as Reviewer rectangle "ブログ執筆システム" { usecase "記事を執筆" as UC1 usecase "図を生成" as UC2 usecase "コードレビュー" as UC3 usecase "サムネイル作成" as UC4 usecase "SEOチェック" as UC5 usecase "ライティングチェック" as UC6 } Engineer --> UC1 Engineer --> UC2 Engineer --> UC3 Claude --> UC1 : 下書き生成 Claude --> UC2 : Mermaid/PlantUML生成 Claude --> UC4 Claude --> UC5 Claude --> UC6 Reviewer --> UC3 UC2 ..> UC1 : <<include>> UC5 ..> UC1 : <<include>> @enduml VS Code Previewでの表示結果がこちらです。 left to right direction でアクターが左右に配置されて、横長のレイアウトになります。 rectangle でシステム境界を囲って、 ..> + <<include>> でユースケース間の依存関係を表現しています。 棒人間のアクターアイコンはPlantUML固有のもので、UML標準に準拠しています。Mermaidでは表現できません。個人的にはこのアクターアイコンが出るだけで「ちゃんとした設計図」感が出るので気に入ってます。 実践③: コンポーネント図 コンポーネント図とは システムのコンポーネント(サービス、データベース、キューなど)と、それらの依存関係を表現する図です。PlantUMLの database と queue の専用記号が使えるのがここで効いてきます。 Mermaidでもflowchartでシステム構成図を描けますが、データベースもキューも同じ四角形になります。PlantUMLならドラム型のDB記号やキュー記号で一目でわかる図が作れます。 プロンプト例 以下のシステム構成をPlantUMLのコンポーネント図で作成してください。 【システム名】ブログ執筆環境 【レイヤー構成】 - 開発環境: VS Code、Claude Code CLI、Playwright - CLIツール: blog-scraper、html-to-png、svg-to-png、thumbnail-generator - 外部サービス: WordPress(DB)、Kroki.io(キュー)、GitHub(DB) database記号とqueue記号を使い分けてください。 packageでレイヤーを分けてください。 ```plantuml のコードブロック形式で出力してください。 PlantUMLコード例 @startuml package "開発環境(devcontainer)" { [VS Code] as VSCode [Claude Code CLI] as Claude [Playwright] as PW } package "CLIツール" { [blog-scraper] as Scraper [html-to-png] as H2P [svg-to-png] as S2P [thumbnail-generator] as Thumb } package "外部サービス" { database "WordPress" as WP queue "Kroki.io" as Kroki database "GitHub" as GH } VSCode --> Claude : コマンド実行 Claude --> Scraper : 記事取得 Claude --> H2P : 図のPNG変換 Claude --> Thumb : サムネイル生成 Scraper --> WP : スクレイピング H2P --> PW : ブラウザ描画 VSCode --> Kroki : PlantUMLプレビュー Claude --> GH : コミット・プッシュ @enduml VS Code Previewで表示するとこうなります。 WordPressとGitHubがドラム型のDB記号で、Kroki.ioがキュー型の記号で表示されます。 package でレイヤーが囲まれるので、3層構造が一目でわかります。 [コンポーネント名] の記法はUMLコンポーネント記号(角に突起が付いた四角形)で表示されます。Mermaidの ["テキスト"] とは見た目が違って、設計図っぽさが出ます。実はこの図、自分が普段使ってるブログ執筆環境そのものなので、「こういう構成で動いてるんだ」と思いながら見てもらえると嬉しいです。 トラブルシューティング Previewに図が表示されない 症状 原因 対策 コードブロックがそのまま表示される VS Code標準のMarkdownプレビューを使っている Markdown Preview Enhanced のプレビューに切り替える。コマンドパレットで「Markdown Preview Enhanced: Open Preview to the Side」を実行 「Loading…」で止まる Kroki.ioサーバーに接続できない ネットワーク接続を確認。プロキシ環境の場合はVS Codeのプロキシ設定を確認 図が真っ白 plantumlServer の設定値が間違っている 設定値が https://kroki.io/plantuml/svg/ になっているか確認(末尾のスラッシュも必要) エラーメッセージが表示される PlantUMLの構文エラー エラーメッセージをClaude Codeに貼り付けて「修正してください」と依頼 日本語が文字化けする Kroki.ioサーバー側で描画されるため、ローカルのフォント設定は影響しません。Kroki.ioは日本語フォントに対応しているので、通常は文字化けしないです。 もし文字化けする場合は、skinparamでフォントを指定してみてください: @startuml skinparam defaultFontName "Noto Sans JP" ' 以下に図の内容 @enduml 図が大きすぎてプレビューに収まらない 2つの方法があります。 方法1: scaleで縮小 @startuml scale 0.8 ' 80%に縮小して表示 @enduml 方法2: skinparam dpiで調整 @startuml skinparam dpi 150 ' デフォルト(200程度)より小さくする @enduml ノード数が多い場合は、図を分割するのが根本的な解決策です。 プロンプトテンプレート集 コピペして使えるテンプレートです。 アクティビティ図用 以下のワークフローをPlantUMLのアクティビティ図で作成してください。 【ワークフロー名】 [ワークフローの名前] 【ステップ】 1. [ステップ1の内容] 2. [ステップ2の内容] 3. 判定: [条件分岐の内容] - YES → [処理A] - NO → [処理B] ```plantuml のコードブロックで出力してください。 skinparamは不要です。 ユースケース図用 以下のユースケース図をPlantUMLで作成してください。 【システム名】 [システムの名前] 【アクター】 - [アクター1]: [役割の説明] - [アクター2]: [役割の説明] 【ユースケース】 - [UC1]: [機能の説明] - [UC2]: [機能の説明] 【関係】 - [UC間のinclude/extend関係があれば記述] left to right direction で横向きレイアウトにしてください。 ```plantuml のコードブロックで出力してください。 コンポーネント図用 以下のシステム構成をPlantUMLのコンポーネント図で作成してください。 【システム名】 [システムの名前] 【レイヤー構成】 - [レイヤー1]: [コンポーネント一覧] - [レイヤー2]: [コンポーネント一覧] - [データ層]: [DB、キャッシュ、キュー等] database記号とqueue記号を適切に使い分けてください。 packageでレイヤーを分けてください。 ```plantuml のコードブロックで出力してください。 修正依頼用 先ほどのPlantUML図を以下の点で修正してください: 【修正内容】 - [修正点1] - [修正点2] - [修正点3] ```plantuml のコードブロック形式を維持してください。 まとめ Mermaidで作れない図はPlantUMLで作る。確認はVS Code上のMarkdown Previewで完結する。 この記事のポイント: 使い分け : 迷ったらMermaid。アクティビティ図・ユースケース図・コンポーネント図の3パターンだけPlantUML 環境設定 : Markdown Preview Enhanced + Kroki.ioサーバー。devcontainer.jsonに数行設定するだけ 作業フロー : Claude Code → PlantUMLコード生成 → VS Code Preview確認。エディタから離れない PlantUML固有の強み : database/queue専用記号、if/else分岐、ユースケースのアクター記法 Mermaid版の記事では「Live Editorでブラウザに切り替えて確認」でしたが、PlantUML版は「VS Codeのプレビューで確認」です。エディタとターミナルの行き来だけで図の作成が完結するのは地味に楽です。仕様書のMarkdownにそのまま埋め込めるので、図の管理も別ファイルにする必要がありません。 自分はこの仕組みを使って、仕様書や設計書の図解を全部Markdownに集約しています。 ほなまた。 関連ブログ・参考リンク 関連ブログ ClaudeでMermaid図作成を自動化!2時間→5分の劇的時短術 今回の記事の前編にあたる記事です。Mermaidでフローチャート・シーケンス図・パイチャートを自動生成する方法と、Live Editorでの確認フローを紹介しています。Mermaid側の使い方はこちらを参照してください。 図解作成、AIに丸投げしたら「たまに自分より上手い」件 Claude CodeのSKILL機能でHTML図解を自動生成し、CLIでPNG変換する方法を紹介しています。気に入ったデザインをreferenceに保存するだけでスキルが育つ仕組みも解説。図解の品質を上げたい人はこちらもどうぞ。 参考リンク PlantUML公式 Kroki.io — Diagram as Code Markdown Preview Enhanced Mermaid.js公式 ご覧いただきありがとうございます! この投稿はお役に立ちましたか? 役に立った 役に立たなかった 0人がこの投稿は役に立ったと言っています。 The post Claude Codeで仕様書のPlantUML図を自動生成 — VS Codeプレビューで完結 first appeared on SIOS Tech Lab .
アバター
AIは「1+1って、2になること多いなあ」と思っている!? ChatGPTに「1+1は?」と聞けば、当然「2」と返ってきます。 実はこのときのAIの内部で起こっていることは、割と大真面目に 「 私のデータによれば、1+1の答えは最も2が多いです 」なのです。 計算してるんじゃないの? ChatGPTのようなAI(大規模言語モデル)は、極端なことを言ってしまえば、次の単語予測マシンです。 たとえば「むかしむかし、あるところに」と言われたら、「おじいさんと」と返す。「今日の天気は」と言われたら、「晴れ」とか「曇り」とか返す。 膨大な文章を読んで「この言葉の次にはこの言葉が来やすい」というパターンを学習しているだけなんです。 AIにとっては、計算問題も文章の一種のため、数学の問題も同じやりかたで解いています。 「1+1=」という文字列を見て、「この後には2が来ることが多いな」と思って2を返しているだけ。 つまり: 人間: 1+1を理解して、演算して、2を導く AI: 「1+1=」の後に「2」が来るパターンで覚えてる そう、タイトルの通り、AIは「1+1って、2になること多いなあ」なのです。 ほんと? もしAIが計算を「理解」しているのではなく、単なる「パターンの暗記」だとしたら、 見たことがないパターンに出会ったときにボロが出るはず です。 その実態がよくわかる、2つの証拠を見てみましょう。 証拠1: ちょっと難しいかけ算ができない 普通の計算機(電卓)なら、2桁の足し算ができれば、4桁になっても10桁になっても、やることは同じなので間違えません。 しかし、OpenAIの研究論文「 Language Models are Few-Shot Learners 」(Brown et al., 2020)によると、当時のGPT-3は以下のような結果になりました。 2桁の足し算: ほぼ100%正解 4桁以上の計算: 正答率は 20%以下 に急落 つまり、ネット上にたくさん転がっている「よくある計算(2桁)」はパターンとして覚えているけれど、滅多に見かけない「大きな桁の計算」は、パターンがないのでお手上げになってしまうのです。   証拠2: 聞き方が変だとできなくなる たとえば「0.7 × 5 は?」と聞けばAIは即座に3.5と答えます。 でも同じ計算を「7×10⁻¹ × 5 は?」と科学的記数法で書くと、数学的にはまったく同じ計算なのに、急に怪しくなります。 Yang et al.(2024)の論文「 Number Cookbook 」では、LLMは標準的な整数計算には強い一方、分数や科学的記数法になると、精度が 20%以下 まで落ちることが示されています。 数学を理解しているなら「書き方が違うだけ」と分かりますが、AIにとっては 見たことがない珍しい文字列 に見えてしまうため、予測が外れてしまうのです。   やってみよう 実際に試してみましょう。ChatGPTに「4726 × 3891 は?」と聞いてみます。 あれ、普通に正解されました。 実は、今のAIはこの「弱点」を、 知能ではなく「仕組み」で克服 しつつあるんです。 今は解決してる ChatGPTの新しいもの(GPT-4o)やClaude 4.5などは、数学の実力テスト(MATHやGSM8Kといった、AIに数学の問題を解かせてスコアを測る標準テスト)で非常に高いスコアを出しています。その理由は主に2つあります。 1つ目はツールの利用です。 計算が必要な場面で、内部的にプログラミングコードを実行したり電卓を使ったりして、LLM自体は直接計算せずに正解を得る方法が発達しました。 2つ目は、Chain-of-Thoughtというもので、段階を踏んで思考することで、単純に答えるよりもはるかに複雑な問題を解けるようになりました。 例えば「23 × 47」を一発で出すのではなく、「23 × 40 = 920、23 × 7 = 161、920 + 161 = 1081」のように段階を踏めます。 これにより、実用上はAIは計算ができると言える水準になっています。   しかし、ここで注意したいのは、これらはいずれも AIが計算を「理解」しているわけではない ということです。 ツール利用は外部の計算機に丸投げしているだけですし、Chain-of-Thoughtも、本来1ステップでは処理しきれない問題を小さく分割して、トークン生成の過程で中間結果を一時的に保持する仕組みです。 LLMの本質は今も変わらず、次に来る言葉の予測であり、これらの間接的な手順を禁じた場合、AIは依然として大きな数の掛け算や見慣れない形式の計算で間違えます。 まとめ AIは計算を「理解」しているのではなく、「1+1の後には2が来やすい」というパターンで答えている そのため、桁が大きい計算や見慣れない書き方には弱い 最近はツール利用(コード実行)やChain-of-Thought(段階的思考)で実用上は高精度になった ただし、これらはあくまで補助手段であり、LLMの本質は変わっていない AIに計算させるときは、裏でちゃんとコードを実行しているか意識しておくと安心 おまけ 僕はブログを書くときに、AIにレビューをしてもらっています。 この記事をレビューさせてみたときのAIの反応がこちら:   AI: AIは計算ができない!?のレビューを開始します。 … ファクトチェック中… 計算例が間違っています。 本来ならば4726 × 3891 の正しい答えは 18,374,766 です。修正します.. … あ、そういえば私もAIでした。 Pythonコードを実行し、確認します。   最近のAIは賢いですね。 実は、計算例の部分は僕が「AIにこんな感じの例を提示して」と出力させたものなので、 つまりこのやりとりは、 AIが「AIは計算ができない!?」という記事をレビューし、 AIが計算した計算ミスをAIが指摘・修正し、 同時に自分がAIであることにはたと気づき、 AIは計算ができないため、直ちにプログラム実行によって確証を得る という、皮肉・メタ認知のミルフィーユであり、今のAIのアホさと賢さの両面が綺麗に凝縮されたやりとりでした。 関連記事 AIに嘘つかないでよーとお願いするとちょっと効くという記事を書いています: chatGPTに「ハルシネーションしないで」とお願いしたら効果がある?   ご覧いただきありがとうございます! この投稿はお役に立ちましたか? 役に立った 役に立たなかった 0人がこの投稿は役に立ったと言っています。 The post AIは「1+1って、2になること多いなあ」と思っている!? first appeared on SIOS Tech Lab .
アバター
VS Code で Claude Code の SKILL.md を開くと allowed-tools is not supported や Unexpected indentation のエラーが出る。原因は GitHub Copilot の Agent Skills バリデータが .claude/skills/ を自動検出している ためです。Claude Code の動作には影響ないけど、エディタがエラーとか出してると目障りなのでね… files.associations に1行追加すれば消えます。 { "files.associations": { "**/.claude/skills/*/SKILL.md": "markdown" } } 以下、原因の詳細と Agent Skills 標準の経緯、関連する既知の Issue を整理します。 何が起きているのか GitHub Copilot が 2025年12月に Agent Skills というオープンスタンダードに対応しました。このスタンダード、実は Anthropic が 2025年10月に Claude Code で先行リリースしていたもので、後にオープンスタンダードとして公開された経緯があります。 で、このスタンダードでは Skills のファイル名として SKILL.md を使います。Claude Code も Copilot も同じ名前。偶然の一致じゃなくて、同じ仕様に基づいています。 問題はここからで、VS Code の Copilot バリデータが .claude/skills/ 配下の SKILL.md も 自動検出してバリデーションをかけてくる んですよね。 なぜ Warning が出るのか Agent Skills 標準には以下のフィールドが定義されています。 フィールド 必須 実験的 name Yes No description Yes No license No No compatibility No No metadata No No allowed-tools No Yes allowed-tools は 実験的フィールド です。Claude Code では普通に使えるんですが、VS Code 側の Copilot バリデータがまだ対応していないので Warning が出ます。 ただ、問題は allowed-tools だけじゃありません。 description: | で Error が出る 実際の SKILL.md を見てみましょう。Claude Code の Skills では description に YAML のブロックスカラー( | )を使って複数行で書くのが一般的です。 --- name: blog-scraper description: | This skill should be used when the user asks to "ブログをスクレイピングして", "SIOS Tech Labの記事を保存して", or provides a SIOS Tech Lab blog URL to scrape and save. allowed-tools: Read, Edit, Bash --- これを VS Code で開くと、こうなります。 Error: Unexpected indentation (L4, L5) Warning: Attribute 'This skill should be used when...' is not supported in skill files. Warning: Attribute 'allowed-tools' is not supported in skill files. Error 2つに Warning 3つ。結構派手に怒られます。 原因は Copilot のバリデータが YAML のブロックスカラー記法( | )を解釈できていない こと。 description: | の後のインデントされた行を「description の値の続き」ではなく「別の属性」として読んでしまうので、インデントが不正だと怒り、さらに行の内容を未知の属性名として Warning を出します。 Claude Code 側はちゃんとパースしているので、 | で書いても動作は問題ありません。確認済みです。 ちなみに | を使わずに1行で書けば Error は消えます。ただ、description が長くなると読みにくいので、実用的にはちょっと厳しい。結局 files.associations で抑制するのが現実的な対処です。 自動検出されるパス VS Code Copilot は以下のパスを自動で検出します。 パス 用途 .github/skills/ プロジェクト(標準) .claude/skills/ プロジェクト(後方互換) ~/.copilot/skills/ パーソナル ~/.claude/skills/ パーソナル(後方互換) .claude/skills/ が「後方互換」として検出対象に入っています(後方互換性なのか??)。Claude Code ユーザーの Skills がそのまま Copilot でも使えるようにする意図なんですが、バリデータの対応が追いついていない状態です。 回避策: files.associations で Markdown として認識させる 回避策はシンプルです。SKILL.md を Copilot の Skill ファイルではなく、通常の Markdown ファイルとして認識させます。 .vscode/settings.json に以下を追加してください。 { "files.associations": { "**/.claude/skills/*/SKILL.md": "markdown" } } devcontainer を使っている場合は devcontainer.json の settings に追加しても OK です。 { "customizations": { "vscode": { "settings": { "files.associations": { "**/.claude/skills/*/SKILL.md": "markdown" } } } } } 検証結果 項目 設定前 設定後 description: | の Error Unexpected indentation なし allowed-tools の Warning not supported in skill files なし Claude Code の動作 正常 正常(影響なし) 設定後に VS Code の Diagnostics を確認したところ、Warning は完全に消えていました。Claude Code 側のスキル一覧にも正常に表示されます。まぁMarkdownとして認識させているんで当たり前ですね。Claude Codeの設定ファイルを書くときは自力で頑張りましょう。 Agent Skills 標準の経緯 せっかくなので背景も整理しておきます。 日付 できごと 2025年10月16日 Anthropic が Agent Skills を発表(Claude Code で利用可能に) 2025年12月18日 オープンスタンダードとして公開。同日に GitHub が Copilot での対応を発表 2025年12月 VS Code 1.108 で実験的サポート追加 Anthropic が先に作ったものをオープン化して、GitHub が同日に採用を発表した流れです。Agent Skills は「一度書けばどこでも使える(write once, use everywhere)」を目指していて、対応ツールは Claude Code、GitHub Copilot の他に、Cursor、Goose、Amp なども実験的に対応しています。 Claude Code が先行して独自拡張を進めている分、標準仕様との差分が Warning として表面化したのが今回の件ですね。 関連する既知の Issue この問題に関連して、いくつか Open の Issue があります。 Issue 内容 anthropics/claude-code #23723 user-invocable と user-invokable のスペル不一致。Claude Code CLI は user-invocable で動作するが、VS Code のスキーマは user-invokable を期待する anthropics/skills #314 SKILL.md のファイル名が大文字小文字を区別する仕様がドキュメントに記載されていない。 skill.md (小文字)だとエラーなく無視される anthropics/claude-code #13586 .claude/commands/skill.md を作ると組み込みの Skill ツールと名前が衝突して、全カスタムコマンドが読み込まれなくなる user-invocable / user-invokable の件は結構ハマりそうなポイントです。Claude Code CLI では user-invocable が正しいので、VS Code 側で Warning が出てもそのまま使ってください。VS Code の警告に従って user-invokable に変更すると、逆に Claude Code で動かなくなります。 まとめ 原因 : Claude Code と GitHub Copilot が同じ Agent Skills 標準を使っており、VS Code Copilot のバリデータが .claude/skills/ の SKILL.md を検出して Error / Warning を出す。 description: | のブロックスカラーと allowed-tools が引っかかる 対処 : files.associations で Markdown として認識させる(1行追加) 影響 : Claude Code の動作には一切影響なし 2026年2月15日時点の情報です。検証環境は以下のとおり。 ソフトウェア バージョン VS Code 1.109.3 GitHub Copilot Chat 拡張 0.37.6 Claude Code CLI / 拡張 2.1.42 Agent Skills はまだ発展途上で、VS Code 側のバリデータが allowed-tools に対応したり、 user-invocable のスペルが統一されたりすれば、この設定自体が不要になるはずです。 個人的には Claude Code の Skills と GitHub Copilot の Skills が統合される未来に期待してますが、まぁ希望的観測ですかね。今のところは Claude Code がガンガン先行しているので、この手の差分とはしばらく付き合うことになりそうです。 参考リンク Agent Skills Specification Claude Code Skills Documentation VS Code Agent Skills Documentation GitHub Copilot Agent Skills Docs ご覧いただきありがとうございます! この投稿はお役に立ちましたか? 役に立った 役に立たなかった 2人がこの投稿は役に立ったと言っています。 The post VS Code で Claude Code の SKILL.md にエラーが出る原因と対処法 first appeared on SIOS Tech Lab .
アバター
お世話になっております。サイオステクノロジー武井です。 メールの送受信テストを簡単に行えるmaildevというDockerを見つけましたので紹介したいと思います。 ちょっとテストでローカルの開発環境でメールの送受信テストするのってめんどくさいですよね。SMTPサーバー立てて、メール送信して、さらにそのメールがきちんと送信されたかを確認するためのメールボックスも用意しなければなりません。本番では、ちゃんとした環境でやる必要があるのですが、開発ではサクッとできれば十分ですよね。 そこでmaildevです。詳細は以下です。 https://github.com/maildev/maildev DockerでサクッとSMTPサーバーと、そのメール受信を確認するためのWebインターフェースを構築できるのです。構築方法は以下のとおりです。 $ docker run -p 1080:1080 -p 1025:1025 maildev/maildev これだけっす。SMTPのポートは1025、Webインターフェースのポートは1080です。 サクッと試してみましょう。telenetコマンドで送信してみます。 $ telnet localhost 1025 Trying ::1... Connected to localhost. Escape character is '^]'. 220 792c64766927 ESMTP HELO example.com 250 792c64766927 Nice to meet you, [172.22.0.1] MAIL FROM: <hoge@example.com> 250 Accepted RCPT TO: <fuga@example.com> 250 Accepted DATA 354 End data with . Subject: test mail test mail . 250 Message queued as FiY4Mc5L 受信できてるかどうか試してみましょう。http://localhost:1080にアクセスしてみます。 おおー、ちゃんと受信できてます。 これはべんり。 ご覧いただきありがとうございます! この投稿はお役に立ちましたか? 役に立った 役に立たなかった 0人がこの投稿は役に立ったと言っています。 The post モックSMTPサーバーを簡単に構築できるmaildev first appeared on SIOS Tech Lab .
アバター
「あの調査どこだっけ」で済む世界がほしかった ども!ドキュメントが70件を超えて検索がカオスになっている龍ちゃんです。 結論から言うと、ファイルパスを指定しなくても「あの調査どこだっけ」と話し言葉で聞くだけで、勝手に見つけてくれる仕組みを作りました。ファイルの作り方を工夫して、検索専用の Haiku サブエージェントを .claude/agents/ に置いただけ。今回はその仕組みの話です。 僕は Claude Code への指示を極力さぼりたい んですよね。ドキュメントのパスを毎回共有するようなことはしたくないので、文脈と単語で勝手に探してほしいんですよね。 以前、 AIフレンドリーなドキュメント管理 という記事で README にインデックスを作る方法を紹介しました。50件まではそれで回っていたんですが、70件を超えたあたりでClaude Codeの検索がポンコツになりました。 破綻からやったことは2つです。 ドキュメントにメタデータを埋め込む(まずはここから) — YAML Frontmatter で tags, keywords, use_when 等を付与して、検索精度を上げる 検索専用サブエージェントを作る — .claude/agents/ にエージェント定義ファイルを置いて、特定ディレクトリに特化した検索エージェントを作る 今回の内容です。 READMEインデックスが破綻した理由 エージェントの検索精度を上げるメタデータ設計 検索専用サブエージェント(Haiku)の作り方と Explore との違い 実際のエージェント定義ファイル(ブログの最後に配置されています) ドキュメント増えてきたら Claude Codeの検索がポンコツになる話 READMEインデックスとは まず前提から。Claude Code でドキュメントを管理するときに、僕がやっていた方法がこれです。 ドキュメントが入っているディレクトリに README.md を置いて、ファイル名・タイトル・カテゴリの一覧表を作る。Claude Code は CLAUDE.md から @import でこの README を読み込む。全ファイルを開かなくても、README を1つ読めば「このディレクトリに何があるか」が分かる。ドキュメントの「目次」を作って、AI に目次から探させる手法ですね。 まずは、 AIフレンドリーなドキュメント管理 を読んでみるとスムーズに話が入ってくるかも? 70件を超えたら破綻した 50件程度まではこれで回ってました。70件を超えたあたりから破綻しましたね。 ファイル数が増えるとタイトルだけでは区別がつかないドキュメントが出てくるんですよ。実際に起きたのが、Claude Code の Skills について調べたかったのに、GitHub Copilot の Agent Skills の記事が出てきたケース。README のタイトル一覧を見ると、こういう状態です。 タイトル 対象 Claude Code Skills 実装ガイド Claude Code Claude Code一時ファイルからSkillsへ Claude Code 「Skillsが発火しない」を解決 Claude Code Agent Skills 入門:SKILL.md の基本から実践まで GitHub Copilot Claude CodeからGitHub Copilotへ移植したらAgent Skillsが動かない? GitHub Copilot 「Skills」でタイトルを探すと、Claude Code と GitHub Copilot の記事が混在しています。README のインデックスにはタイトルしかないから、どっちの「Skills」なのか区別がつかない。 MCP 関連はもっとひどくて、調査ドキュメントだけで6件が「MCP」をタイトルに含んでました。「MCPが遅いんだけど」と聞いたとき、「MCP設計ベストプラクティス」「MCPの課題と制限」「CLI tools vs MCP 比較」「MCP計測・ログ方法」…どれを読めばいいのか、タイトルだけでは Claude にも判断できないんでファイルパス出して問い合わせが来ます。。 結果、Explore が全ファイルパスから探しに行ってトークンを消費する。本質的な問題は、README インデックスが「タイトルベースの検索」にのみ対応していること。ユーザーが言葉で表現する「やりたいこと」から適切なドキュメントを探す——こういう 意図ベースの検索 に対応できないんですよね。 メタデータで検索精度を上げる まずサブエージェントの話の前に、ドキュメント側の改善から。実はこれだけでもビルトインの Explore の検索精度が上がるんですよね。 YAML Frontmatter を設計する 僕の docs/research/ では、各ドキュメントの冒頭に YAML Frontmatter を付けています。 --- title: "MCPの課題と制限" date: 2026-01-29 category: Claude Code tags: - MCP - パフォーマンス related: - 2026-01-29-cli-tools-vs-mcp-comparison.md use_when: - "MCP接続でパフォーマンス問題に直面" - "MCPが遅いと感じたとき" keywords: - Notion MCP - Playwright MCP --- それぞれのフィールドの役割はこんな感じです。 フィールド 役割 例 title 直接的なトピック検索 「MCPの課題と制限」 tags カテゴリベースの絞り込み MCP, パフォーマンス use_when 意図ベースの検索 「MCPが遅いと感じたとき」 keywords 固有名詞での精密検索 Notion MCP, Playwright MCP related 芋づる式の関連探索 関連ファイル名 use_when が鍵 一番大事なのは use_when です。 「MCPが遅い」に対して、タイトルだけでは6件の中から選べない。でも use_when: "MCP接続でパフォーマンス問題に直面" が入っていれば、「パフォーマンスの話だ」と判断できるようになる。タイトルでは区別できなかった意図ベースの検索が、ここで実現するんですよね。 use_when には「〇〇のとき」「〇〇に直面」のように、ユーザーの状況を書きます。タイトルよりも具体的で、本文よりもコンパクト。 ここは何を知りたいと思ったか?というキーワードで考えるとつけやすいです。人間の頭は忘れるようにできるんで、気になったときには疑問のほうが先に浮かびます。 メタデータの管理もAIに任せる 「Frontmatter を全ドキュメントに手で書くのは大変じゃない?」——大変です。 だからこの仕組み自体の管理も AI に任せちゃってます。ドキュメントを作成する Skill や Agent の中に「保存時に Frontmatter を自動付与する」って指示を組み込んでおけば、ドキュメントが作られるたびにメタデータが勝手に付きます。 実際にうちの /research スキルでは、調査ドキュメントを保存する際に Frontmatter を自動生成してます。人間が手作業で tags や use_when を考える必要はない。仕組みを作る手間は最初の1回だけで、あとは放っておいても自動管理です。 んで既にドキュメントある人も安心してください。そんなことはAIさんにお願いすればいいんです。寝る前に「Sonnetの並列でYAML Formatterをつけといて」と依頼しておけばきっと布団でごろごろしている間に終わってます。 CLAUDE.md に Frontmatter の構造を教える サブエージェントを作らない人はここ注意です。Frontmatter を付けただけだと、ビルトインの Explore はその構造を知らないんですよね。 use_when というフィールドがあって意図ベースの検索に使える——この情報がないと、Explore は普通に本文を Grep するだけになります。 CLAUDE.md に「 docs/research/ のファイルには YAML Frontmatter があり、 use_when で利用シーン、 tags でカテゴリ、 keywords で固有名詞を検索できる」と書いておいてください。サブエージェントはエージェント定義ファイルにこの知識を仕込んでいるから不要ですが、Explore だけで運用するならこの一手間が必要です。 README インデックスは残す サブエージェントを入れたから README インデックスは不要……ではないです。後述する3段階検索の Level 1 で、まず README のカテゴリ別テーブルから候補を絞るんですよね。この高速な絞り込みが最初のフィルターになります。 README インデックス + メタデータ + サブエージェント。置き換えじゃなくて、積み上げです。 検索専用サブエージェント(Haiku)を作る Frontmatter を整えるだけでも検索精度は上がる。こっからは専門のエージェントを作って管理をしてもらうという話をしていきます。 Explore ではダメなのか? 「検索なら Explore があるじゃん」と思った方、鋭いです。 でも Explore はプロジェクト全体から検索をかけるんで、時間食った挙句に違うファイルを出してくることがあったんですよね。 実は Claude Code のビルトインエージェント Explore も Haiku で動いてます。Claude Code 自体が、ドキュメント検索に Haiku を使ってるんですよね。じゃあなぜわざわざ専用エージェントを作るのか。 専用エージェントは description でスコープを絞れるし、エージェント定義の本文にドメイン知識を注入できる。Explore が図書館の一般案内係だとしたら、専用サブエージェントはその棚の構造を熟知した専門の司書みたいなもんです。 観点 Explore(ビルトイン) 専用サブエージェント モデル Haiku Haiku(同じ) スコープ プロジェクト全体 特定ディレクトリのみ 検索戦略 汎用(Glob/Grep/Read) 3段階絞り込み ドメイン知識 なし Frontmatter スキーマを理解 カスタマイズ 不可(ビルトイン) 自由に設計可能 モデルは同じ Haiku。違いは「どこまで知っているか」だけ。ちなみにサブエージェントから別のサブエージェントは起動できないんで(公式の制限)、検索エージェントはメインセッションから直接呼び出す設計にしてください。 エージェント定義ファイルの書き方 実際に僕が使っている research-searcher の定義ファイルを見てもらうのが早いです。 .claude/agents/research-searcher.md に置いています。 --- name: research-searcher description: > docs/research/配下の調査ドキュメントを検索・要約するエージェント。 「前に調べた〜の調査」「〜についての調査結果どこだっけ」 「MCPの課題をまとめた調査があったはず」等のリサーチドキュメント検索、 タグ・キーワードベースの横断検索に使用します。 tools: [Read, Grep, Glob] model: haiku --- それぞれ見ていきます。 model: haiku — 検索は読み取りがメインなので、Opus の 1/5 のコストで済みます。 tools: [Read, Grep, Glob] — 読み取り専用にしています。検索エージェントにファイルの編集はさせない。 description が最重要 — ここが一番大事。Claude はこの description を見て「この質問はこのエージェントに任せよう」と判断します。 description に自分の会話パターンを埋め込む description をもう一度見てください。 「前に調べた〜の調査」「〜についての調査結果どこだっけ」 「MCPの課題をまとめた調査があったはず」 これ、僕が普段 Claude に話しかけるフレーズそのままなんですよね。丁寧な説明文じゃなくて、ラフな口語をそのままぶち込んでます。 なぜかというと、Claude はこの description を見て「この質問はこのエージェントに委譲すべきか?」を判断するから。自分の口癖に寄せておいたほうが、実際の会話パターンとマッチしやすいんですよね。公式のベストプラクティスでも「いつ委譲すべきかを明確に記述する」ことが推奨されてます。入れなくても比較的意図を察してくれるんですが、入れておくと精度が上がります。 ポイントは、 description をドキュメントっぽく書かないこと。 自分がどういう場面でそのエージェントを使いたいか を具体的に書く。「ドキュメントを検索するエージェント」みたいな汎用的な説明だと、Claude の Explore が優先されて起動されます。 3段階検索戦略 エージェント定義ファイルの本文( --- の下)には、検索の手順を書きます。僕のエージェントでは3段階で検索させてます。 Level 1: README インデックスを読む — docs/research/README.md のカテゴリ別テーブルから候補を絞る。これが一番安い Level 2: Frontmatter を確認する — 候補ファイルの冒頭にある YAML Frontmatter(tags, use_when, keywords)で内容を精査する Level 3: 本文を Grep で横断検索 — 上の2段階で見つからなかった場合の最終手段 ポイントは、いきなり本文を全部読まないこと。README → Frontmatter → 本文の順に、段階的に情報を絞り込む。これでサブエージェントのトークン消費も抑えられます。 実際に使ってみた結果 さっきの破綻の例、覚えてますか。Claude Code の Skills について聞いたのに GitHub Copilot の Agent Skills の記事が出てきたやつ。 サブエージェント導入後に同じように「Skills の調査どこだっけ」と聞いたら、ちゃんと Claude Code の Skills の記事から出してくれるようになりました。サブエージェントが Frontmatter の tags: Claude Code と use_when を見て、文脈から「これは Claude Code の話だ」と判断してるんですよね。タイトルだけで探してた頃とは精度が全然違います。大満足です。 まとめ 「あのファイルどこだっけ」が増えてきた人、まず YAML Frontmatter を付けてください。特に use_when 。これだけでビルトインの Explore でも検索精度が変わります。既存ドキュメントが大量にある人も、Sonnet に並列で投げれば寝てる間に終わるんで気にしなくていいです。 んでさらに速度と精度がほしくなったら .claude/agents/ に検索専用サブエージェントを足す。 description に自分の口癖をぶち込んでおけば、Claude が勝手に使い分けてくれます。 一回仕組み作っちゃえばあとはさぼれるんで、ドキュメント増えてきた人は試してみてください。 ではまた! 関連記事 Claude Codeへの指示を少しでもさぼりたい!AskUserQuestionツール — 聞き返し機能で指示の手間を減らす。「さぼりシリーズ」の原点 Claude Code設計術:AIフレンドリーなドキュメント管理 — READMEインデックスの作り方。本記事の前提になる話 Claude Codeが遅い?毎回検索をやめて実行速度を劇的改善 — CLAUDE.md設計で無駄な検索を減らして高速化する方法 Claude Code サブエージェントの最適構成:Opus で考え、Sonnet で動かす — Opus/Sonnet/Haikuの使い分け設計。本記事のHaikuサブエージェントもこの考え方がベース Claude Code /research の待ち時間をゼロに:Skill × サブエージェント構成 — Skillとサブエージェントを組み合わせて調査を並列実行する構成 Claude Codeに専門知識を仕込む:調査→構造化→注入の設計パターン — 調査結果をエージェントに注入するパターン。Frontmatterの設計思想に近い 付録:実際のエージェント定義ファイル全文 僕が使っている research-searcher の定義ファイル( .claude/agents/research-searcher.md )をそのまま載せます。コピーして自分の環境に合わせて書き換えれば動きます。 --- name: research-searcher description: docs/research/配下の調査ドキュメントを検索・要約するエージェント。「前に調べた〜の調査」「〜についての調査結果どこだっけ」「MCPの課題をまとめた調査があったはず」等のリサーチドキュメント検索、タグ・キーワードベースの横断検索に使用します。 tools: [Read, Grep, Glob] model: haiku --- # Research Searcher Agent `docs/research/` 配下の調査ドキュメントを検索・情報抽出するエージェントです。 ## 役割 メインセッション(Opus)から Task tool で呼び出され、調査ドキュメントの検索・照合・要約を行い結果を返却します。 ## データ構造の理解 ### ファイル命名規則 ``` YYYY-MM-DD-topic-name.md ``` ### Frontmatter(検索に活用) 各ファイルには以下の YAML Frontmatter がある: | フィールド | 説明 | 検索への活用 | |-----------|------|-------------| | `title` | ドキュメントタイトル(日本語) | タイトルマッチ | | `date` | 調査日 | 時期での絞り込み | | `category` | 主カテゴリ | カテゴリ絞り込み | | `tags` | 検索用タグ(3-8個) | タグベース検索 | | `related` | 関連ファイル名 | 関連調査の芋づる検索 | | `use_when` | 利用シーン | 「〇〇のとき」で検索 | | `keywords` | 重要キーワード(固有名詞等) | 技術名での検索 | ### カテゴリ一覧 - Claude Code / Azure / マーケティング / ライティング品質 - ライセンス / マネジメント / ツール・変換 / AI・LLM ## 検索戦略(3段階) ### Level 1: インデックス検索(最初に必ず実行) `docs/research/README.md` を読み、カテゴリ別テーブルから候補を絞り込む。 ``` Read({ file_path: "docs/research/README.md" }) ``` - カテゴリ別にファイル名・調査内容・調査日がテーブルで整理されている - **多くの検索はこの段階で候補が絞れる** ### Level 2: Frontmatter 確認(候補の詳細確認) 候補ファイルの frontmatter を読み、`tags`, `use_when`, `keywords`, `related` で内容を精査する。 ``` Read({ file_path: "docs/research/[候補ファイル].md", limit: 30 }) ``` frontmatter の `tags` と `keywords` は本文を読まずに関連性を判断できる強力な手がかり。 ### Level 3: 本文検索(キーワードがタイトル・タグに含まれない場合) Grep で本文内を横断検索する。 ``` Grep({ pattern: "検索キーワード", path: "docs/research/", glob: "*.md" }) ``` ## 検索パターン別の処理 ### パターン1: トピック検索 「MCPの調査あったよね」「RAGについて調べたはず」等の場合: 1. README.md のテーブルからトピック名でマッチ 2. 候補の frontmatter で `tags` / `keywords` を確認 3. 該当ファイルのタイトル・要約・タグを返却 ### パターン2: 用途ベース検索 「〜するときに参考になる調査」等の場合: 1. Grep で `use_when` フィールドを横断検索 2. マッチしたファイルの frontmatter を確認 3. 利用シーンと合致する調査を返却 ### パターン3: 関連調査の探索 「この調査と関連する他の調査は?」等の場合: 1. 基準ファイルの frontmatter から `related` フィールドを取得 2. 関連ファイルの frontmatter を確認 3. さらに同じ `tags` を持つファイルを探索(芋づる式) ### パターン4: カテゴリ・時期での絞り込み 「最近のClaude Code関連の調査一覧」等の場合: 1. README.md のカテゴリ別テーブルから該当カテゴリを抽出 2. 日付で絞り込み 3. 一覧として返却 ### パターン5: 技術名での検索 「FastMCP」「SCANOSS」等の固有名詞での検索: 1. Grep で `keywords` フィールドを検索 2. マッチしない場合、本文を横断検索 3. 該当ファイルを返却 ## 出力形式 ```markdown ## 検索結果 | ファイル | タイトル | カテゴリ | 調査日 | |----------|---------|---------|--------| | YYYY-MM-DD-topic.md | タイトル | カテゴリ | YYYY-MM-DD | ### 要約 [該当調査の概要。frontmatter の title + tags から構成、または本文冒頭から抽出] ### 関連調査 - [関連ファイル名] - [タイトル](related フィールドから取得) ``` ## 制約事項 - **読み取り専用**: 調査ファイルの編集・作成は行わない - **スコープ限定**: `docs/research/` 配下のみを対象とする - **Web検索なし**: ローカルファイルの検索のみ - **トークン節約**: 本文全体を読むのは必要最小限にとどめる ポイントを補足しておくと: description は自分の口癖に合わせて書き換えてください。ここが委譲判断の精度に直結します カテゴリ一覧 や Frontmatter スキーマ は自分のドキュメント構造に合わせて変更してください 検索パターン は増やしても減らしても OK。自分がよく使う検索パターンだけ残せば十分です 参考リンク Claude Code Sub-agents 公式ドキュメント Anthropic Multi-Agent Research ご覧いただきありがとうございます! この投稿はお役に立ちましたか? 役に立った 役に立たなかった 0人がこの投稿は役に立ったと言っています。 The post Claude Codeのドキュメント検索を極力さぼれるようにした話 first appeared on SIOS Tech Lab .
アバター
お世話になっております。サイオステクノロジー武井です。 今回はマイクラサーバーをGUIで管理するCrafty Controllerについて書きます。 Crafty Controllerとは? マイクラことMinecraftは、マイクラサーバーを構築し、ネットワークを通じてそのワールドを共有することができます。同じワールドを共有すると、友達と協力して建築物を作ったり、友達を◯したりすることができます。 しかしながらマイクラサーバーの管理は容易ではありません。マイクラサーバーは基本クラサバ構成で、クライアントであるMinecraftが、サーバーであるマイクラサーバーと通信し合いながら動きます。マイクラサーバーは設定ファイルの変更やMOD(拡張機能みたいなもの)の追加は特別なGUIは設けられておらず、直接設定ファイルを編集したり、サーバーにMODをアップロードしたり、プロセスの再起動が必要になります。でもこれは、Linuxに関する相応の知識がないとむずいです。 そこで、Crafty Controllerです。これはマイクラサーバーのプロセスをGUIで管理するOSSです。設定ファイルの編集、ファイルのアップロード、プロセスの再起動など全てGUIでできます。他にもCPUやメモリリソースなどの管理、ユーザーの管理(BANなど)もできます。 アーキテクチャとしては以下のとおりです。Crafty Controllerを起動するとプロセスが起動します。これはHTTPで待ち受けるプロセスです。いわゆるWebアプリです。サーバー管理者はブラウザを通して、このCrafty Controllerにアクセスをして、Minecraftサーバーを起動・停止・再起動、設定ファイルの変更などを行います。ポート番号を変えれば複数のMinecraftサーバーを起動することが可能です。プレイヤーは起動したMinecraftサーバーにアクセスして遊びます。 Crafty Controllerを構築できる技術あればGUIなくても、マイクラサーバー管理できるよねと言う感じなのですが、モチベーションとしては私の息子がマイクラサーバーを使いたいと言い出して、でもLibuxのコマンドを使って管理するのはいきなり敷居が高すぎるのでこういうものを用意した次第です。 ちなみにこのサーバーはAzure上で動いています。Ubuntu動く仮想マシンであればAWSとかGCPとかの他のクラウドでもOKのはずです。 Crafty Controllerのインストール では早速Crafty Controllerのインストール手順を見てみましょう。基本的には以下のインストール手順に従っています。 https://docs.craftycontrol.com/pages/getting-started/installation/linux/ またJavaがインストールされていることが前提となります。 Crafty Controller本体のインストール gitでリポジトリをcloneしてインストールスクリプトを起動して、以下の通りウィザードに従います。 # git clone https://gitlab.com/crafty-controller/crafty-installer-4.0.git # cd crafty-installer-4.0 # ./install_crafty.sh [+] Info:- Linux Check Success [+] Info:- Python Version Check - 3.12 We detected your os is: ubuntu - Version: 24.04 Install ubuntu_24_04.sh requirements? - ['y', 'n']: y ← yを入力してエンター [+] Info:- Crafty's Default install directory is set to: /var/opt/minecraft/crafty Install Crafty to this directory? /var/opt/minecraft/crafty - ['y', 'n']: y ← yを入力してエンター [+] Info:- Choose your destiny: [+] Info:- Crafty comes in different branches: [+] Info:- Master - Kinda Stable, a few bugs present [+] Info:- Dev - Highly Unstable, full of bugs and new features Which branch of Crafty would you like to run? - ['master', 'dev']: master ← masterを入力してエンター [+] Info:- Making start and update scripts for you Would you like to make a service file for Crafty? - ['y', 'n']: y ← yを入力してエンター [+] Info:- Cleaning up temp dir [+] Info:- Congrats! Crafty is now installed! [+] Info:- We created a user called 'crafty' for you to run crafty as. (DO NOT RUN CRAFTY WITH ROOT OR SUDO) Switch to crafty user with 'sudo su crafty -' [+] Info:- Your install is located here: /var/opt/minecraft/crafty [+] Info:- You can run crafty by running /var/opt/minecraft/crafty/run_crafty.sh [+] Info:- You can update crafty by running /var/opt/minecraft/crafty/update_crafty.sh [+] Info:- A service unit file has been saved in /etc/systemd/system/crafty.service [+] Info:- run this command to enable crafty as a service- 'sudo systemctl enable crafty.service' [+] Info:- run this command to start the crafty service- 'sudo systemctl start crafty.service' Crafty Controllerのサービス登録 自動起動するようサービス登録します。 # systemctl enable crafty.service # systemctl start crafty.service 初回ログイン 以下のURLにアクセスする(httpsであることに注意)。 https://[サーバーのIPアドレス]:8443/ 初回のログイン情報は 以下のパスに記載しています。ログイン後パスワードを変更してください。 /var/opt/minecraft/crafty/crafty-4/app/config/default-creds.txt 言語の変更 画面上の表示言語を日本語にします。画面右上のユーザーのアイコンをクリックして(①)、「Account Settings」をクリックします(②)。「User Language」を選択して、「ja_JP」を選択します(③)。最後に画面下部にある「Save」をクリックします。   サーバーの追加 では、マイクラサーバーを追加してみましょう。 まず、画面左部のメニューから「サーバー」→「新しいサーバーを作成」の順にクリックします。 以下のように設定して、最後に「サーバを作成」をクリックする。 サーバーの種類: Minecraft Servers サーバーを選択: 任意(vanillaやforge等お好きなものを) サーバーバージョン: 任意 サーバー名: 任意 最小メモリ使用量: 1GB 最大メモリ使用量: サーバーリソースが許すだけ サーバーポート: 基本は25565(複数立てる場合は他のサーバーと重複がないようにする)   「サーバー一覧」から先程作成したサーバーをクリックします。   ログにエラーがなければ、「起動」をクリックします。   EULAの同意画面が出るので、「Yes」をクリックします。これでサーバーの作成は完了です。 SSL化 一応デフォルトの状態でもSSLは有効になっているのですが、オレオレ証明書です。ApacheやNginx等でSSLの終端を行う方法もありますが、SSLの終端だけであればCaddyというのを使うとサクッと設定できます。しかもLet’s Encryptにネイティブに対応しています。 Caddyを導入すると以下のような感じになります。Caddyがリバースプロキシの働きをして、SSLの終端を行い、Crafty Controllerにアクセスします。 ここで図中ではCaddyからCrafty ControllerへのアクセスがHTTPSになっています。通常であればリバースプロキシなどでSSLの終端を行った後はそのバックエンドサーバーとのやり取りはHTTPになりましが、Crafty ControllerはデフォルトでHTTPSであり、HTTP化する方法があるのかもしれませんが、まぁ、今回はあまり設定変更などの手間はかけずサクッとやりたかったので、SSL終端後のバックエンドサーバーへのアクセスもそのままHTTPSとしています。この場合バックエンドサーバー側でもSSLの終端を行うため負荷がかかりますが、今回は個人用途なので、OKとしています。 ACMEのプロトコルを通じてLet’s Encryptにアクセスして証明書を自動取得・更新をします。 導入手順は以下のとおりです。Ubuntuを想定しています。 まず以下のコマンドを実行してCaddyをインストールします。 # apt install -y debian-keyring debian-archive-keyring apt-transport-https curl # curl -1sLf 'https://dl.cloudsmith.io/public/caddy/stable/gpg.key' | sudo gpg --dearmor -o /usr/share/keyrings/caddy-stable-archive-keyring.gpg # curl -1sLf 'https://dl.cloudsmith.io/public/caddy/stable/debian.deb.txt' | sudo tee /etc/apt/sources.list.d/caddy-stable.list # chmod o+r /usr/share/keyrings/caddy-stable-archive-keyring.gpg # chmod o+r /etc/apt/sources.list.d/caddy-stable.list # apt update # apt install caddy   次に 設定ファイル/etc/caddy/Caddyfileを以下のように定義します。FQDNは、minecraft.example.comを想定しています。 minecraft.example.com { reverse_proxy https://localhost:8443 { transport http { tls_insecure_skip_verify } } }   Caddyを再起動します。これで完了です。 # systemctl restart caddy まとめ みなさん、これで簡単にマイクラサーバーの管理をして、みんなでマイクラしましょう。 ご覧いただきありがとうございます! この投稿はお役に立ちましたか? 役に立った 役に立たなかった 0人がこの投稿は役に立ったと言っています。 The post マイクラサーバーをGUIで管理するCrafty Controller first appeared on SIOS Tech Lab .
アバター