<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/">
  <channel>
    <title>Coding AI on AI2CORE - AI技術ブログ</title>
    <link>https://www.ai2core.com/categories/coding-ai/</link>
    <description>Recent content in Coding AI on AI2CORE - AI技術ブログ</description>
    <generator>Hugo -- 0.146.4</generator>
    <language>ja</language>
    <lastBuildDate>Fri, 20 Feb 2026 08:00:00 +0900</lastBuildDate>
    <atom:link href="https://www.ai2core.com/categories/coding-ai/index.xml" rel="self" type="application/rss+xml" />
    <item>
      <title>GitHub Copilot Workspace活用術：仕様書から実装まで一気通貫</title>
      <link>https://www.ai2core.com/posts/2026-02-20-copilot-workspace/</link>
      <pubDate>Fri, 20 Feb 2026 08:00:00 +0900</pubDate>
      <guid>https://www.ai2core.com/posts/2026-02-20-copilot-workspace/</guid>
      <description>Copilot Workspaceを使って、IssueからPR作成までを自動化するフロー。</description>
      <content:encoded><![CDATA[<h1 id="github-copilot-workspace活用術仕様書から実装まで一気通貫">GitHub Copilot Workspace活用術：仕様書から実装まで一気通貫</h1>
<h2 id="はじめに">はじめに</h2>
<p>ソフトウェア開発の現場にいる皆さん、日々の業務フローを思い返してみてください。</p>
<ol>
<li>GitHub Issue や Jira のチケットで仕様を確認する。</li>
<li>内容を理解し、ローカルで新しいブランチを作成する。</li>
<li>関連ファイルを特定し、エディタで開く。</li>
<li>仕様に沿ってコードを書き、修正する。</li>
<li>動作確認のためのテストコードを記述する。</li>
<li>ローカルでテストを実行し、問題ないことを確認する。</li>
<li>変更をコミットし、リモートにプッシュする。</li>
<li>ブラウザで GitHub を開き、Pull Request (PR) を作成する。</li>
</ol>
<p>この一連の流れは、私たちエンジニアにとって日常茶飯事です。しかし、このプロセスには多くのコンテキストスイッチ（思考の切り替え）が含まれており、特にプロジェクトの初期段階や、新しいコードベースに触れる際には、仕様の理解や関連ファイルの特定といった「準備運動」に多くの時間が費やされます。</p>
<p>「Issue の内容を理解したら、あとはAIが自動でコードを書いてPRまで作ってくれたら最高なのに…」</p>
<p>そんな未来の夢物語が、<strong>GitHub Copilot Workspace</strong> の登場によって、現実のものとなりつつあります。この記事では、GitHub がテクニカルプレビューとして公開した Copilot Workspace を徹底的に解説し、Issue（仕様書）を起点として、AIと共に実装計画を立て、コードを生成し、Pull Request を作成するまでの一気通貫の開発フローを実践的なハンズオン形式で紹介します。</p>
<p>この記事を読み終える頃には、あなたは Copilot Workspace の強力な機能を理解し、自身の開発プロセスを劇的に効率化させるための具体的なイメージを描けるようになっているでしょう。</p>
<hr>
<h2 id="なぜ今copilot-workspaceが重要なのか">なぜ今、Copilot Workspaceが重要なのか？</h2>
<p>GitHub Copilot が登場し、私たちのコーディング体験は大きく変わりました。関数名やコメントから意図を汲み取り、驚くほど的確なコードを補完してくれる Copilot は、もはや手放せない相棒となっているエンジニアも多いでしょう。その後、Copilot Chat が登場し、エディタ内で対話形式でコードに関する質問やリファクタリングの相談ができるようになりました。</p>
<p>しかし、これまでの Copilot は、あくまで「コーディング」という実装フェーズに特化した支援ツールでした。開発プロセス全体を見渡すと、実装の前には「仕様の理解」「設計」「実装計画」といった上流工程が存在し、実装の後には「テスト」「PR作成」「レビュー」といった下流工程が存在します。</p>
<p>ここに、現代の開発プロセスが抱える根深い課題があります。</p>
<ul>
<li><strong>コンテキストスイッチのオーバーヘッド:</strong> Issue、設計ドキュメント、エディタ、ターミナル、ブラウザ… 開発者は複数のツールやウィンドウを絶えず行き来する必要があり、そのたびに集中力が削がれます。</li>
<li><strong>定型作業の繰り返し:</strong> ブランチ作成、ボイラープレートコードの記述、基本的なテストケースの作成など、創造的とは言えない定型作業に多くの時間が奪われています。</li>
<li><strong>オンボーディングの壁:</strong> 新しいメンバーがプロジェクトに参加した際、広大なコードベースのどこから手をつければ良いのかを把握するのは非常に困難です。</li>
</ul>
<p>GitHub Copilot Workspace は、これらの課題を解決するために生まれました。それは単なるコード補完ツールではありません。<strong>Issue を起点として、開発タスクの全体像をAIが把握し、人間と対話しながら「仕様の明確化」「実装計画の立案」「コード生成」「テスト」までを半自動的に実行する、いわば「AI搭載の開発環境」</strong> なのです。</p>
<p>Copilot Workspace は、開発プロセスの上流から下流までをシームレスに繋ぎ、エンジニアを煩雑な作業から解放します。これにより、エンジニアはより創造的で、本質的な価値を生み出す「設計」や「アーキテクチャの検討」「複雑なビジネスロジックの実装」に集中できるようになるのです。これは、開発の生産性を根底から覆すポテンシャルを秘めた、大きなパラダイムシフトと言えるでしょう。</p>
<hr>
<h2 id="copilot-workspaceによる開発フロー徹底解説">Copilot Workspaceによる開発フロー徹底解説</h2>
<p>それでは、実際に Copilot Workspace を使って Issue から PR 作成までを駆け抜けるプロセスを、具体的なハンズオン形式で見ていきましょう。</p>
<h3 id="copilot-workspace-の全体像">Copilot Workspace の全体像</h3>
<p>Workspace のフローは、大きく分けて以下の3つのステップで構成されています。この概念を理解することが、Workspace を使いこなすための鍵となります。</p>
<pre tabindex="0"><code class="language-mermaid" data-lang="mermaid">graph TD;
    A[📝 GitHub Issue] --&gt; B(🚀 Copilot Workspaceを起動);
    B --&gt; C{1. Spec&lt;br&gt;(仕様の確認・編集)};
    C -- AIと対話し仕様を洗練 --&gt; D{2. Plan&lt;br&gt;(実行計画の生成・編集)};
    D -- 計画に基づき実行 --&gt; E{3. Implementation&lt;br&gt;(コードの自動生成・修正)};
    E -- 人間によるレビュー・微修正 --&gt; F[✅ Pull Request作成];
</code></pre><ol>
<li><strong>Spec (仕様):</strong> Workspace はまず Issue の内容を読み込み、タスクの目的や要件を自然言語でまとめた「仕様」を生成します。開発者はこの仕様を確認し、AI とのチャットを通じて内容をより正確かつ詳細なものに洗練させていきます。</li>
<li><strong>Plan (計画):</strong> 洗練された仕様に基づき、AI は「どのファイルを新規作成するか」「どのファイルをどう変更するか」「どのコマンドを実行するか」といった具体的な「実行計画」を立案します。この計画はステップバイステップで表示され、開発者は内容を確認・編集できます。</li>
<li><strong>Implementation (実装):</strong> 開発者が計画を承認すると、Workspace は計画に沿ってファイルの作成、コードの生成・編集、コマンドの実行などを自動で行います。生成されたコードの差分（diff）は即座に確認でき、必要に応じて Workspace 内のエディタやターミナルで直接修正を加えることが可能です。</li>
</ol>
<p>この**「仕様定義 → 計画立案 → 実装」**という反復的なプロセスこそが、Copilot Workspace の中核です。</p>
<h3 id="実践issueからpr作成までのハンズオン">実践！IssueからPR作成までのハンズオン</h3>
<p>今回は、簡単な REST API を提供する Node.js (Express) プロジェクトを例に、新しいエンドポイントを追加するタスクを Workspace で実行してみましょう。</p>
<p><strong>前提:</strong></p>
<ul>
<li>GitHub Copilot Workspace のテクニカルプレビューにアクセスできること。</li>
<li>Node.js と Express で作られたシンプルな Web API のリポジトリが存在すること。</li>
</ul>
<h4 id="step-0-課題となる-issue-の準備">Step 0: 課題となる Issue の準備</h4>
<p>まずは、開発の起点となる Issue を作成します。AI が理解しやすいように、具体的かつ明確に記述することがポイントです。</p>
<p><strong>Issue Title:</strong> <code>feat: GET /api/v1/users エンドポイントを追加</code></p>
<p><strong>Issue Body:</strong></p>
<div class="highlight"><div style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">
<table style="border-spacing:0;padding:0;margin:0;border:0;"><tr><td style="vertical-align:top;padding:0;margin:0;border:0;">
<pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 1
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 2
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 3
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 4
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 5
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 6
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 7
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 8
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 9
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">10
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">11
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">12
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">13
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">14
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">15
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">16
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">17
</span></code></pre></td>
<td style="vertical-align:top;padding:0;margin:0;border:0;;width:100%">
<pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-markdown" data-lang="markdown"><span style="display:flex;"><span><span style="color:#75715e">### 概要
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span>ユーザーの一覧を取得するための新しいAPIエンドポイント <span style="color:#e6db74">`GET /api/v1/users`</span> を追加します。
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#75715e">### 背景
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span>クライアントアプリケーションがユーザー情報を一覧表示するために、このAPIが必要です。
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#75715e">### 受け入れ条件
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span><span style="color:#66d9ef">-</span> HTTP GETリクエストを <span style="color:#e6db74">`/api/v1/users`</span> パスで受け付けること。
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">-</span> レスポンスはJSON形式であること。
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">-</span> レスポンスボディは、<span style="color:#e6db74">`data`</span> というキーを持つオブジェクトであること。
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">-</span> <span style="color:#e6db74">`data`</span> の値は、以下の構造を持つユーザーオブジェクトの配列であること。
</span></span><span style="display:flex;"><span>  <span style="color:#66d9ef">-</span> <span style="color:#e6db74">`id`</span> (number)
</span></span><span style="display:flex;"><span>  <span style="color:#66d9ef">-</span> <span style="color:#e6db74">`name`</span> (string)
</span></span><span style="display:flex;"><span>  <span style="color:#66d9ef">-</span> <span style="color:#e6db74">`email`</span> (string)
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">-</span> 現状、データベース連携は不要。モックデータとして3人分のユーザー情報を返すこと。
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">-</span> エラーハンドリングは考慮しなくてよい。
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">-</span> 既存のルーティングファイル (<span style="color:#e6db74">`src/routes/index.js`</span>) に新しいルートを追加すること。
</span></span></code></pre></td></tr></table>
</div>
</div><h4 id="step-1-workspace-の起動">Step 1: Workspace の起動</h4>
<p>作成した Issue ページにアクセスすると、Copilot のアイコンと共に「Open in Workspace」というボタンが表示されます（プレビュー有効時）。これをクリックして Workspace を起動します。</p>
<p><em>(画像はイメージです)</em></p>
<h4 id="step-2-spec---仕様の定義と洗練">Step 2: &ldquo;Spec&rdquo; - 仕様の定義と洗練</h4>
<p>Workspace が起動すると、AI が Issue の内容を解析し、以下のような「Spec」を自動生成します。</p>
<blockquote>
<p><strong>Initial Specification</strong></p>
<p>The goal is to add a new API endpoint <code>GET /api/v1/users</code>.
This endpoint should return a mocked list of users in a specific JSON format.</p>
<p><strong>Acceptance Criteria:</strong></p>
<ul>
<li>The endpoint must handle GET requests to <code>/api/v1/users</code>.</li>
<li>The response should be a JSON object with a <code>data</code> key.</li>
<li>The <code>data</code> key should contain an array of user objects.</li>
<li>Each user object must have <code>id</code>, <code>name</code>, and <code>email</code>.</li>
<li>The implementation should use mock data for three users.</li>
<li>The new route should be added to the existing file <code>src/routes/index.js</code>.</li>
</ul></blockquote>
<p>この時点で、AI がタスクを正しく理解していることが分かります。もし、何か補足したい情報があれば、下部のチャットボックスから AI に指示を出します。</p>
<p>例えば、返すモックデータに具体的な名前を指定したい場合、以下のようにチャットします。</p>
<p><strong>あなた:</strong></p>
<blockquote>
<p><code>Use the following names for the mock data: Alice, Bob, and Charlie.</code></p></blockquote>
<p>すると、AI はこの指示を理解し、Spec を更新します。この対話を通じて、実装に入る前に AI との認識合わせを完璧に行うことができます。</p>
<h4 id="step-3-plan---実行計画の立案">Step 3: &ldquo;Plan&rdquo; - 実行計画の立案</h4>
<p>Spec が固まったら、AI はそれを実現するための具体的な「Plan」を作成します。</p>
<blockquote>
<p><strong>Execution Plan</strong></p>
<p>I will perform the following steps to implement the feature:</p>
<ol>
<li>
<p><strong>Modify file <code>src/routes/index.js</code></strong>: I will add a new route handler for <code>GET /api/v1/users</code>. This handler will define the mock user data and send it as a JSON response in the required format.</p>
</li>
<li>
<p><strong>Create file <code>tests/users.test.js</code></strong>: To ensure the new endpoint works correctly, I will create a new test file. This test will use a library like <code>supertest</code> to make a request to the new endpoint and assert that the response status is 200 and the body matches the expected structure.</p>
</li>
</ol></blockquote>
<p>この計画は非常に理にかなっています。実装ファイルの変更だけでなく、その動作を保証するためのテストファイルの作成まで提案してくれている点は素晴らしいです。もし、テストが不要な場合や、別のファイルにロジックを分割したい場合は、この Plan を手動で編集したり、AI に修正を依頼したりすることも可能です。</p>
<h4 id="step-4-implementation---aiによる自動実装">Step 4: &ldquo;Implementation&rdquo; - AIによる自動実装</h4>
<p>Plan に納得したら、「Run」ボタンをクリックします。すると、Workspace が計画に沿ってコードの生成とファイルの作成を自動的に開始します。処理が完了すると、変更内容が差分（diff）形式で表示されます。</p>
<p><strong><code>src/routes/index.js</code> の変更差分:</strong></p>
<div class="highlight"><div style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">
<table style="border-spacing:0;padding:0;margin:0;border:0;"><tr><td style="vertical-align:top;padding:0;margin:0;border:0;">
<pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 1
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 2
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 3
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 4
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 5
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 6
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 7
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 8
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 9
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">10
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">11
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">12
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">13
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">14
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">15
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">16
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">17
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">18
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">19
</span></code></pre></td>
<td style="vertical-align:top;padding:0;margin:0;border:0;;width:100%">
<pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-diff" data-lang="diff"><span style="display:flex;"><span>  const express = require(&#39;express&#39;);
</span></span><span style="display:flex;"><span>  const router = express.Router();
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>  /* GET home page. */
</span></span><span style="display:flex;"><span>  router.get(&#39;/&#39;, function(req, res, next) {
</span></span><span style="display:flex;"><span>    res.json({ title: &#39;Express&#39; });
</span></span><span style="display:flex;"><span>  });
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#a6e22e">+ router.get(&#39;/api/v1/users&#39;, (req, res) =&gt; {
</span></span></span><span style="display:flex;"><span><span style="color:#a6e22e">+   const mockUsers = [
</span></span></span><span style="display:flex;"><span><span style="color:#a6e22e">+     { id: 1, name: &#39;Alice&#39;, email: &#39;alice@example.com&#39; },
</span></span></span><span style="display:flex;"><span><span style="color:#a6e22e">+     { id: 2, name: &#39;Bob&#39;, email: &#39;bob@example.com&#39; },
</span></span></span><span style="display:flex;"><span><span style="color:#a6e22e">+     { id: 3, name: &#39;Charlie&#39;, email: &#39;charlie@example.com&#39; },
</span></span></span><span style="display:flex;"><span><span style="color:#a6e22e">+   ];
</span></span></span><span style="display:flex;"><span><span style="color:#a6e22e">+
</span></span></span><span style="display:flex;"><span><span style="color:#a6e22e">+   res.status(200).json({ data: mockUsers });
</span></span></span><span style="display:flex;"><span><span style="color:#a6e22e">+ });
</span></span></span><span style="display:flex;"><span><span style="color:#a6e22e">+
</span></span></span><span style="display:flex;"><span><span style="color:#a6e22e"></span>  module.exports = router;
</span></span></code></pre></td></tr></table>
</div>
</div><p><strong><code>tests/users.test.js</code> の新規作成:</strong></p>
<div class="highlight"><div style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">
<table style="border-spacing:0;padding:0;margin:0;border:0;"><tr><td style="vertical-align:top;padding:0;margin:0;border:0;">
<pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 1
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 2
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 3
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 4
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 5
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 6
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 7
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 8
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 9
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">10
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">11
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">12
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">13
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">14
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">15
</span></code></pre></td>
<td style="vertical-align:top;padding:0;margin:0;border:0;;width:100%">
<pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-javascript" data-lang="javascript"><span style="display:flex;"><span><span style="color:#66d9ef">const</span> <span style="color:#a6e22e">request</span> <span style="color:#f92672">=</span> <span style="color:#a6e22e">require</span>(<span style="color:#e6db74">&#39;supertest&#39;</span>);
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">const</span> <span style="color:#a6e22e">app</span> <span style="color:#f92672">=</span> <span style="color:#a6e22e">require</span>(<span style="color:#e6db74">&#39;../src/app&#39;</span>); <span style="color:#75715e">// Express app instance
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span>
</span></span><span style="display:flex;"><span><span style="color:#a6e22e">describe</span>(<span style="color:#e6db74">&#39;GET /api/v1/users&#39;</span>, () =&gt; {
</span></span><span style="display:flex;"><span>  <span style="color:#a6e22e">it</span>(<span style="color:#e6db74">&#39;should return a list of users&#39;</span>, <span style="color:#66d9ef">async</span> () =&gt; {
</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">const</span> <span style="color:#a6e22e">res</span> <span style="color:#f92672">=</span> <span style="color:#66d9ef">await</span> <span style="color:#a6e22e">request</span>(<span style="color:#a6e22e">app</span>).<span style="color:#a6e22e">get</span>(<span style="color:#e6db74">&#39;/api/v1/users&#39;</span>);
</span></span><span style="display:flex;"><span>    <span style="color:#a6e22e">expect</span>(<span style="color:#a6e22e">res</span>.<span style="color:#a6e22e">statusCode</span>).<span style="color:#a6e22e">toEqual</span>(<span style="color:#ae81ff">200</span>);
</span></span><span style="display:flex;"><span>    <span style="color:#a6e22e">expect</span>(<span style="color:#a6e22e">res</span>.<span style="color:#a6e22e">body</span>).<span style="color:#a6e22e">toHaveProperty</span>(<span style="color:#e6db74">&#39;data&#39;</span>);
</span></span><span style="display:flex;"><span>    <span style="color:#a6e22e">expect</span>(Array.<span style="color:#a6e22e">isArray</span>(<span style="color:#a6e22e">res</span>.<span style="color:#a6e22e">body</span>.<span style="color:#a6e22e">data</span>)).<span style="color:#a6e22e">toBe</span>(<span style="color:#66d9ef">true</span>);
</span></span><span style="display:flex;"><span>    <span style="color:#a6e22e">expect</span>(<span style="color:#a6e22e">res</span>.<span style="color:#a6e22e">body</span>.<span style="color:#a6e22e">data</span>.<span style="color:#a6e22e">length</span>).<span style="color:#a6e22e">toBe</span>(<span style="color:#ae81ff">3</span>);
</span></span><span style="display:flex;"><span>    <span style="color:#a6e22e">expect</span>(<span style="color:#a6e22e">res</span>.<span style="color:#a6e22e">body</span>.<span style="color:#a6e22e">data</span>[<span style="color:#ae81ff">0</span>]).<span style="color:#a6e22e">toHaveProperty</span>(<span style="color:#e6db74">&#39;id&#39;</span>);
</span></span><span style="display:flex;"><span>    <span style="color:#a6e22e">expect</span>(<span style="color:#a6e22e">res</span>.<span style="color:#a6e22e">body</span>.<span style="color:#a6e22e">data</span>[<span style="color:#ae81ff">0</span>]).<span style="color:#a6e22e">toHaveProperty</span>(<span style="color:#e6db74">&#39;name&#39;</span>);
</span></span><span style="display:flex;"><span>    <span style="color:#a6e22e">expect</span>(<span style="color:#a6e22e">res</span>.<span style="color:#a6e22e">body</span>.<span style="color:#a6e22e">data</span>[<span style="color:#ae81ff">0</span>]).<span style="color:#a6e22e">toHaveProperty</span>(<span style="color:#e6db74">&#39;email&#39;</span>);
</span></span><span style="display:flex;"><span>  });
</span></span><span style="display:flex;"><span>});
</span></span></code></pre></td></tr></table>
</div>
</div><p>生成されたコードは、概ね Issue の要件を満たしています。ここで、Workspace 内に組み込まれたターミナルを開き、テストを実行してみましょう。</p>
<div class="highlight"><div style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">
<table style="border-spacing:0;padding:0;margin:0;border:0;"><tr><td style="vertical-align:top;padding:0;margin:0;border:0;">
<pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 1
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 2
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 3
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 4
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 5
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 6
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 7
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 8
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 9
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">10
</span></code></pre></td>
<td style="vertical-align:top;padding:0;margin:0;border:0;;width:100%">
<pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span>$ npm install
</span></span><span style="display:flex;"><span>$ npm test
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>&gt; tests/users.test.js
</span></span><span style="display:flex;"><span>✓ should <span style="color:#66d9ef">return</span> a list of users <span style="color:#f92672">(</span>5ms<span style="color:#f92672">)</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>Test Suites: <span style="color:#ae81ff">1</span> passed, <span style="color:#ae81ff">1</span> total
</span></span><span style="display:flex;"><span>Tests:       <span style="color:#ae81ff">1</span> passed, <span style="color:#ae81ff">1</span> total
</span></span><span style="display:flex;"><span>Snapshots:   <span style="color:#ae81ff">0</span> total
</span></span><span style="display:flex;"><span>Time:        0.5s
</span></span></code></pre></td></tr></table>
</div>
</div><p>テストが成功しました。もしコードに修正が必要な場合は、Workspace 上のエディタで直接編集できます。例えば、レスポンスコードを <code>201</code> に変えたい場合、エディタで <code>res.status(200)</code> を <code>res.status(201)</code> に書き換えるだけです。</p>
<h4 id="step-5-prの作成">Step 5: PRの作成</h4>
<p>実装とテストに問題がないことを確認したら、画面上部にある「Create Pull Request」ボタンをクリックします。</p>
<p>すると、PR 作成画面に遷移します。驚くべきことに、PR のタイトルと説明文も、AI が Issue とコードの変更内容を基に自動で生成してくれます。</p>
<p><strong>PR Title (自動生成):</strong> <code>feat: Add GET /api/v1/users endpoint</code></p>
<p><strong>PR Body (自動生成):</strong></p>
<blockquote>
<p>This pull request introduces a new endpoint <code>GET /api/v1/users</code> to fetch a list of users.</p>
<p><strong>Changes:</strong></p>
<ul>
<li>Added a new route to <code>src/routes/index.js</code> to handle the request.</li>
<li>The endpoint returns a hardcoded list of three users as mock data.</li>
<li>Added a new test file <code>tests/users.test.js</code> to verify the functionality of the new endpoint.</li>
</ul>
<p>Closes #123 (Issue番号)</p></blockquote>
<p>内容を確認し、必要であれば追記して PR を作成します。これで、Issue の起票から PR のマージ準備まで、ほとんどの作業を GitHub の中で、AI の支援を受けながら完結させることができました。</p>
<hr>
<h2 id="メリットとデメリット">メリットとデメリット</h2>
<p>Copilot Workspace は革命的なツールですが、万能ではありません。そのメリットと、現時点でのデメリットや注意点を冷静に評価してみましょう。</p>
<h3 id="メリット">メリット</h3>
<ul>
<li><strong>圧倒的な生産性向上:</strong> これまで手作業で行っていたブランチ作成、ファイル検索、ボイラープレートの記述、テストの雛形作成、PR の文章作成といった一連の定型作業がほぼ自動化されます。これにより、エンジニアはタスクの本質的な部分に集中できます。</li>
<li><strong>コンテキストスイッチの撲滅:</strong> Issue の確認から PR 作成まで、すべての作業が Workspace という単一の環境で完結します。ツール間を行き来する必要がなくなり、思考の分断が起こりにくくなります。</li>
<li><strong>スムーズなオンボーディング:</strong> 新しいプロジェクトに参加した際、Issue を Workspace で開けば、AI が関連ファイルを特定し、変更計画まで立ててくれます。これにより、コードベースの全体像を把握し、最初の貢献を行うまでの時間を大幅に短縮できます。</li>
<li><strong>設計と実装の分離:</strong> 「Spec」と「Plan」のステップを踏むことで、いきなりコーディングを始めるのではなく、「何を」「どのように」作るのかを明確にしてから実装に進むという、良い開発習慣が自然と身につきます。</li>
</ul>
<h3 id="デメリット--注意点">デメリット / 注意点</h3>
<ul>
<li><strong>AI が生成するコードの品質:</strong> 生成されるコードは常に完璧ではありません。バグを含んでいたり、プロジェクトのコーディング規約に沿っていなかったり、最適な設計でない場合もあります。<strong>最終的な品質を担保するのは、あくまで人間のエンジニアの役割</strong>であり、コードレビューの重要性は変わりません。</li>
<li><strong>複雑なタスクへの対応限界:</strong> 複数のファイルを横断する大規模なリファクタリングや、ドメイン知識が深く要求される複雑なビジネスロジックの実装など、高度な抽象的思考が必要なタスクにはまだ対応しきれない場面があります。</li>
<li><strong>思考停止のリスク:</strong> AI に頼りすぎることで、エンジニア自身が「なぜこの変更が必要なのか」「他にどんな実装方法があるか」といったことを深く考えなくなる危険性があります。Workspace はあくまで「優秀なアシスタント」であり、思考の主体は人間であるべきです。</li>
<li><strong>テクニカルプレビュー段階:</strong> 現在はまだプレビュー版であり、機能が変更されたり、動作が不安定になったりする可能性があります。本番の重要なプロジェクトに全面的に導入するには、今後の動向を注視する必要があります。</li>
</ul>
<hr>
<h2 id="現場で使える実践的なtips">現場で使える実践的なTips</h2>
<p>Copilot Workspace のポテンシャルを最大限に引き出すための、いくつかの実践的なヒントを紹介します。</p>
<h3 id="1-良いissueが良い実装を生む">1. 「良いIssue」が「良い実装」を生む</h3>
<p>Workspace の出発点は Issue です。AI の性能はインプットの質に大きく左右されるため、精度の高い実装を引き出すためには、AI が理解しやすい Issue を書くことが非常に重要です。</p>
<ul>
<li><strong>背景 (Why) を書く:</strong> 「何をするか (What)」だけでなく、「なぜそれが必要なのか (Why)」を記述することで、AI がタスクの文脈をより深く理解し、適切な実装を提案しやすくなります。</li>
<li><strong>受け入れ条件 (Acceptance Criteria) を明確にする:</strong> 「〜であること」という形式で、タスク完了の定義を箇条書きで具体的に示しましょう。これは AI にとっての仕様書そのものになります。</li>
<li><strong>専門用語やファイル名をヒントとして与える:</strong> 「<code>UserService</code> クラスを使ってデータを取得すること」「設定は <code>config/features.json</code> を参照すること」のように、コードベース固有の情報を与えると、AI の計画 (Plan) の精度が劇的に向上します。</li>
</ul>
<h3 id="2-plan-を対話的に育てる">2. &ldquo;Plan&rdquo; を対話的に育てる</h3>
<p>AI が生成した最初の Plan が完璧であることは稀です。Plan を鵜呑みにせず、レビューし、AI との対話を通じて改善していくプロセスが重要です。</p>
<ul>
<li><strong>ステップの分割・追加を指示する:</strong> 「ステップ2を、ロジック部分とルーティング部分の2つに分割して」「テストを実行するステップを最後に追加して」のように、計画をより細かく、より安全に実行できるように指示します。</li>
<li><strong>代替案を尋ねる:</strong> 「この実装方法以外に、もっと良い方法はありますか？」と尋ねることで、自分では思いつかなかったアプローチを AI が提案してくれることがあります。</li>
</ul>
<h3 id="3-ローカル環境とのハイブリッド活用">3. ローカル環境とのハイブリッド活用</h3>
<p>Workspace は強力ですが、全ての作業をそこで完結させる必要はありません。特にデバッグや複雑な修正には、使い慣れたローカルのエディタが適している場合もあります。</p>
<p>Workspace で大枠の実装（80%）を自動生成させ、その後ローカルにブランチをチェックアウトして、細部の調整やデバッグ（残りの20%）を行う、というハイブリッドな使い方が非常に効率的です。</p>
<hr>
<h2 id="まとめ">まとめ</h2>
<p>GitHub Copilot Workspace は、単なるコーディング支援ツールではなく、<strong>開発プロセスそのものを再定義する可能性を秘めたゲームチェンジャー</strong>です。Issue という「要求」から Pull Request という「成果物」までを、AI と人間が協調しながらシームレスに繋ぐことで、開発の生産性と体験を新たな次元へと引き上げます。</p>
<p>もちろん、このツールはまだ発展途上であり、人間のエンジニアによるレビューや設計、最終的な意思決定の重要性が失われることはありません。むしろ、AI をいかにうまく「操縦」し、その能力を最大限に引き出すかが、これからのエンジニアに求められる新しいスキルセットになるでしょう。</p>
<p>私たちの役割は、「一行一行コードを書く作業者」から、<strong>「AI という優秀な部下を持つプロジェクトマネージャー兼アーキテクト」</strong> へと変化していくのかもしれません。</p>
<p>GitHub Copilot Workspace がもたらす未来の開発スタイルは、もうすぐそこまで来ています。ぜひテクニカルプレビューに登録し、この新しい開発体験をいち早くご自身のプロジェクトで試してみてください。きっと、開発の未来を垣間見ることができるはずです。</p>
]]></content:encoded>
      <category>Coding AI</category>
      <category>GitHub Copilot</category>
      <category>Workspace</category>
      <category>DevOps</category>
    </item>
    <item>
      <title>Cursorエディタの新機能を使い倒す！AI時代のコーディング術</title>
      <link>https://www.ai2core.com/posts/2026-02-13-cursor-tips/</link>
      <pubDate>Fri, 13 Feb 2026 12:00:00 +0900</pubDate>
      <guid>https://www.ai2core.com/posts/2026-02-13-cursor-tips/</guid>
      <description>AIネイティブエディタCursorの最新機能と、VS Codeからの移行メリット。</description>
      <content:encoded><![CDATA[<h1 id="cursorエディタの新機能を使い倒すai時代のコーディング術">Cursorエディタの新機能を使い倒す！AI時代のコーディング術</h1>
<h2 id="はじめに">はじめに</h2>
<p>「もっと速く、もっと賢くコーディングしたい」
「GitHub Copilotは便利だけど、もう少し踏み込んだサポートが欲しい」
「新しい技術のキャッチアップに時間がかかりすぎる」</p>
<p>もしあなたがエンジニアとして、このような課題を感じているなら、この記事はあなたのためのものです。AIがコーディングの世界を根底から変えつつある今、私たちは単にコードを書くだけでなく、「AIをいかに使いこなすか」という新しいスキルセットを求められています。</p>
<p>GitHub Copilotが「AIによるコード補完」という新しい常識を作りましたが、その次世代を担う存在として注目されているのが、AIネイティブエディタ<strong>Cursor</strong>です。</p>
<p>Cursorは、単なる補完ツールではありません。あなたのプロジェクト全体を理解し、対話を通じてリファクタリング、デバッグ、ドキュメント生成、さらには複数ファイルにまたがる複雑な機能実装までをサポートしてくれる、まさに「AIペアプログラマー」と呼ぶにふさわしいエディタです。</p>
<p>この記事では、VS Codeをベースに開発されたCursorの基本的な使い方から、最新の強力な機能、そしてVS Code + GitHub Copilotから移行する具体的なメリットまで、現場で即戦力となる実践的なノウハウを余すところなく解説します。AI時代の新しいコーディングスタイルを、Cursorと共に体験してみましょう。</p>
<h2 id="なぜ今cursorなのか-ai時代の開発環境の進化">なぜ今、Cursorなのか？ AI時代の開発環境の進化</h2>
<p>ソフトウェア開発の歴史は、生産性向上のためのツールの進化の歴史でもあります。テキストエディタから始まり、シンタックスハイライト、コード補完、デバッガなどを統合したIDE（統合開発環境）が登場しました。そして、バージョン管理システムとしてGitがデファクトスタンダードとなり、私たちの開発スタイルは大きく変わりました。</p>
<p>そして2021年、GitHub Copilotが登場し、開発の世界に再び大きなパラダイムシフトが訪れます。大規模言語モデル（LLM）を活用し、コメントや文脈からコードを自動生成するCopilotは、多くの開発者に衝撃を与え、瞬く間に普及しました。</p>
<p>しかし、Copilotの登場は始まりに過ぎませんでした。Copilotは主に「補完」という形で開発者をサポートしますが、開発者が抱える課題はそれだけではありません。</p>
<ul>
<li><strong>大規模なリファクタリング:</strong> 複数ファイルにまたがる変数名や関数シグネチャの変更は、依然として骨の折れる作業です。</li>
<li><strong>複雑なバグの調査:</strong> エラーメッセージやスタックトレースを読み解き、原因を特定するには深い知識と経験が必要です。</li>
<li><strong>コードベース全体の理解:</strong> 新しく参画したプロジェクトや、巨大なレガシーコードを理解するには膨大な時間がかかります。</li>
<li><strong>設計から実装への落とし込み:</strong> 「ログイン機能を実装する」といった抽象的な要件から、具体的なファイル構成やコードを書き起こすのは創造的な思考を要します。</li>
</ul>
<p>これらの課題は、単純なコード補完だけでは解決が難しい領域です。ここに、<strong>AIネイティブエディタ</strong>という新しいコンセプトが登場する必然性がありました。</p>
<p>Cursorは、この「Copilotの次」を求める開発者のニーズに応えるために生まれました。エディタのUI/UXの深いレベルでAIを統合し、チャットインターフェースを通じて、より高レベルで双方向的なやり取りを可能にしたのです。VS Codeの強力なエコシステム（拡張機能、設定、キーバインド）をそのまま継承しているため、既存の環境からほぼストレスなく移行できる点も、多くの開発者に受け入れられている大きな理由です。</p>
<p>今、Cursorを学ぶことは、AIを最大限に活用した新しい開発ワークフローを身につけ、来るべきAI時代の開発競争で一歩先を行くための、最も効果的な投資と言えるでしょう。</p>
<h2 id="cursorの核心機能具体的な使い方とコード例">Cursorの核心機能：具体的な使い方とコード例</h2>
<p>Cursorの真価は、その多彩なAI機能にあります。ここでは、基本的な機能から最新の強力な機能まで、具体的なコード例を交えながら徹底的に解説します。</p>
<h3 id="1-すべての基本aiチャット-cmdk">1. すべての基本「AIチャット (Cmd+K)」</h3>
<p>Cursorの最も基本的な機能が、選択したコードに対してAIと対話できるチャット機能です。使い方は簡単。コードを選択し、<code>Cmd+K</code> (Windows/Linuxでは <code>Ctrl+K</code>) を押すだけです。</p>
<h4 id="ケース1-コードの生成と編集">ケース1: コードの生成と編集</h4>
<p>例えば、TypeScriptでユーザー情報を取得する非同期関数を書きたいとします。まずは空のファイルで <code>Cmd+K</code> を押し、次のように指示します。</p>
<p><strong>プロンプト:</strong></p>
<pre tabindex="0"><code>TypeScriptで、ユーザーIDを引数に取り、`https://api.example.com/users/{id}` からユーザー情報を取得する非同期関数 `fetchUser` を作成してください。fetch APIを使い、取得したデータはUser型として返してください。User型も定義してください。エラーハンドリングもお願いします。
</code></pre><p>すると、Cursorは以下のようなコードを生成し、ワンクリックでファイルに挿入してくれます。</p>
<p><strong>生成されたコード:</strong></p>
<div class="highlight"><div style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">
<table style="border-spacing:0;padding:0;margin:0;border:0;"><tr><td style="vertical-align:top;padding:0;margin:0;border:0;">
<pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 1
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 2
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 3
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 4
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 5
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 6
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 7
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 8
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 9
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">10
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">11
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">12
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">13
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">14
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">15
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">16
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">17
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">18
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">19
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">20
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">21
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">22
</span></code></pre></td>
<td style="vertical-align:top;padding:0;margin:0;border:0;;width:100%">
<pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-typescript" data-lang="typescript"><span style="display:flex;"><span><span style="color:#66d9ef">interface</span> <span style="color:#a6e22e">User</span> {
</span></span><span style="display:flex;"><span>  <span style="color:#a6e22e">id</span>: <span style="color:#66d9ef">number</span>;
</span></span><span style="display:flex;"><span>  <span style="color:#a6e22e">name</span>: <span style="color:#66d9ef">string</span>;
</span></span><span style="display:flex;"><span>  <span style="color:#a6e22e">email</span>: <span style="color:#66d9ef">string</span>;
</span></span><span style="display:flex;"><span>  <span style="color:#a6e22e">username</span>: <span style="color:#66d9ef">string</span>;
</span></span><span style="display:flex;"><span>}
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">async</span> <span style="color:#66d9ef">function</span> <span style="color:#a6e22e">fetchUser</span>(<span style="color:#a6e22e">userId</span>: <span style="color:#66d9ef">number</span>)<span style="color:#f92672">:</span> <span style="color:#a6e22e">Promise</span>&lt;<span style="color:#f92672">User</span>&gt; {
</span></span><span style="display:flex;"><span>  <span style="color:#66d9ef">try</span> {
</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">const</span> <span style="color:#a6e22e">response</span> <span style="color:#f92672">=</span> <span style="color:#66d9ef">await</span> <span style="color:#a6e22e">fetch</span>(<span style="color:#e6db74">`https://api.example.com/users/</span><span style="color:#e6db74">${</span><span style="color:#a6e22e">userId</span><span style="color:#e6db74">}</span><span style="color:#e6db74">`</span>);
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">if</span> (<span style="color:#f92672">!</span><span style="color:#a6e22e">response</span>.<span style="color:#a6e22e">ok</span>) {
</span></span><span style="display:flex;"><span>      <span style="color:#66d9ef">throw</span> <span style="color:#66d9ef">new</span> Error(<span style="color:#e6db74">`HTTP error! status: </span><span style="color:#e6db74">${</span><span style="color:#a6e22e">response</span>.<span style="color:#a6e22e">status</span><span style="color:#e6db74">}</span><span style="color:#e6db74">`</span>);
</span></span><span style="display:flex;"><span>    }
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">const</span> <span style="color:#a6e22e">user</span>: <span style="color:#66d9ef">User</span> <span style="color:#f92672">=</span> <span style="color:#66d9ef">await</span> <span style="color:#a6e22e">response</span>.<span style="color:#a6e22e">json</span>();
</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">return</span> <span style="color:#a6e22e">user</span>;
</span></span><span style="display:flex;"><span>  } <span style="color:#66d9ef">catch</span> (<span style="color:#a6e22e">error</span>) {
</span></span><span style="display:flex;"><span>    <span style="color:#a6e22e">console</span>.<span style="color:#a6e22e">error</span>(<span style="color:#e6db74">&#39;Failed to fetch user:&#39;</span>, <span style="color:#a6e22e">error</span>);
</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">throw</span> <span style="color:#a6e22e">error</span>; <span style="color:#75715e">// or handle it gracefully
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span>  }
</span></span><span style="display:flex;"><span>}
</span></span></code></pre></td></tr></table>
</div>
</div><h4 id="ケース2-リファクタリング">ケース2: リファクタリング</h4>
<p>次に、既存のコードをリファクタリングしてみましょう。以下のような、少し冗長なコードがあるとします。</p>
<p><strong>Before:</strong></p>
<div class="highlight"><div style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">
<table style="border-spacing:0;padding:0;margin:0;border:0;"><tr><td style="vertical-align:top;padding:0;margin:0;border:0;">
<pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 1
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 2
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 3
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 4
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 5
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 6
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 7
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 8
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 9
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">10
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">11
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">12
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">13
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">14
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">15
</span></code></pre></td>
<td style="vertical-align:top;padding:0;margin:0;border:0;;width:100%">
<pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-javascript" data-lang="javascript"><span style="display:flex;"><span><span style="color:#66d9ef">function</span> <span style="color:#a6e22e">getUserProfile</span>(<span style="color:#a6e22e">user</span>) {
</span></span><span style="display:flex;"><span>  <span style="color:#66d9ef">if</span> (<span style="color:#a6e22e">user</span>) {
</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">if</span> (<span style="color:#a6e22e">user</span>.<span style="color:#a6e22e">profile</span>) {
</span></span><span style="display:flex;"><span>      <span style="color:#66d9ef">if</span> (<span style="color:#a6e22e">user</span>.<span style="color:#a6e22e">profile</span>.<span style="color:#a6e22e">name</span>) {
</span></span><span style="display:flex;"><span>        <span style="color:#66d9ef">return</span> <span style="color:#a6e22e">user</span>.<span style="color:#a6e22e">profile</span>.<span style="color:#a6e22e">name</span>;
</span></span><span style="display:flex;"><span>      } <span style="color:#66d9ef">else</span> {
</span></span><span style="display:flex;"><span>        <span style="color:#66d9ef">return</span> <span style="color:#e6db74">&#39;No name&#39;</span>;
</span></span><span style="display:flex;"><span>      }
</span></span><span style="display:flex;"><span>    } <span style="color:#66d9ef">else</span> {
</span></span><span style="display:flex;"><span>      <span style="color:#66d9ef">return</span> <span style="color:#e6db74">&#39;No profile&#39;</span>;
</span></span><span style="display:flex;"><span>    }
</span></span><span style="display:flex;"><span>  } <span style="color:#66d9ef">else</span> {
</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">return</span> <span style="color:#e6db74">&#39;No user&#39;</span>;
</span></span><span style="display:flex;"><span>  }
</span></span><span style="display:flex;"><span>}
</span></span></code></pre></td></tr></table>
</div>
</div><p>この関数を選択して <code>Cmd+K</code> を押し、プロンプトを入力します。</p>
<p><strong>プロンプト:</strong></p>
<pre tabindex="0"><code>このコードを、Optional Chaining (?.) と Nullish Coalescing (??) を使ってリファクタリングしてください。
</code></pre><p><strong>After (生成されたコード):</strong></p>
<div class="highlight"><div style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">
<table style="border-spacing:0;padding:0;margin:0;border:0;"><tr><td style="vertical-align:top;padding:0;margin:0;border:0;">
<pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">1
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">2
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">3
</span></code></pre></td>
<td style="vertical-align:top;padding:0;margin:0;border:0;;width:100%">
<pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-javascript" data-lang="javascript"><span style="display:flex;"><span><span style="color:#66d9ef">function</span> <span style="color:#a6e22e">getUserProfile</span>(<span style="color:#a6e22e">user</span>) {
</span></span><span style="display:flex;"><span>  <span style="color:#66d9ef">return</span> <span style="color:#a6e22e">user</span><span style="color:#f92672">?</span>.<span style="color:#a6e22e">profile</span><span style="color:#f92672">?</span>.<span style="color:#a6e22e">name</span> <span style="color:#f92672">??</span> <span style="color:#e6db74">&#39;No name&#39;</span>;
</span></span><span style="display:flex;"><span>}
</span></span></code></pre></td></tr></table>
</div>
</div><p>※プロンプト次第では <code>'No user'</code> や <code>'No profile'</code> のケースも考慮した、より丁寧なコードを提案させることも可能です。</p>
<p>このように、対話形式で瞬時にコードの改善が可能です。</p>
<h3 id="2-コードベース全体を理解するを使ったチャット">2. コードベース全体を理解する「@を使ったチャット」</h3>
<p>Cursorの真骨頂とも言えるのが、コードベース全体をコンテキストとしてAIと対話できる機能です。チャットパネル（<code>Cmd+L</code> または <code>Ctrl+L</code> で開く）で <code>@</code> をタイプすると、ファイル名やシンボル（関数名、クラス名など）を補完してくれます。</p>
<p>これにより、AIはあなたが指定したファイルや関数の内容を正確に理解した上で回答を生成します。</p>
<p><strong>シナリオ:</strong> あなたはECサイトのプロジェクトに新しく参加しました。決済処理の流れを理解したいと考えています。</p>
<p><strong>プロンプト:</strong></p>
<pre tabindex="0"><code>@src/services/paymentService.ts と @src/controllers/orderController.ts の内容を参考にして、ユーザーが商品をカートに入れてから決済が完了するまでの大まかな処理フローを教えてください。特に、`processPayment` 関数がどのように呼び出されているかに注目して説明してください。
</code></pre><p>AIは指定された2つのファイルを読み込み、以下のように回答してくれます。</p>
<p><strong>AIの回答（例）:</strong></p>
<pre tabindex="0"><code>承知しました。`paymentService.ts` と `orderController.ts` を分析した結果、決済フローは以下のようになっていると推測されます。

1.  **注文作成 (`orderController.ts`):**
    *   ユーザーがチェックアウトボタンを押すと、フロントエンドから `/api/orders` のようなエンドポイントにリクエストが送られます。
    *   `orderController.ts` 内の `createOrder` ハンドラがリクエストを受け取ります。
    *   このハンドラは、カート情報から注文オブジェクトを作成し、データベースに保存します。

2.  **決済処理の呼び出し (`orderController.ts` -&gt; `paymentService.ts`):**
    *   `createOrder` ハンドラの最後で、`paymentService.ts` に定義されている `processPayment` 関数を呼び出します。
    *   この時、引数として注文IDと合計金額を渡しています。

3.  **決済実行 (`paymentService.ts`):**
    *   `processPayment` 関数は、外部の決済ゲートウェイ（例: Stripe）のAPIを呼び出します。
    *   決済が成功すると、決済IDを返し、注文ステータスを「支払い済み」に更新します。
    *   失敗した場合は、エラーをスローし、`orderController` 側でトランザクションがロールバックされます。

このように、`@`機能を使うことで、複数のファイルにまたがる複雑なロジックも、人に質問するような感覚で素早く理解できます。

### 3. AIによる自動デバッグ「エラーメッセージを貼り付け」

開発中に遭遇する厄介なエラーメッセージ。もう一人で悩む必要はありません。ターミナルに出力されたエラーメッセージやスタックトレースをコピーし、チャットパネルに貼り付けて質問するだけで、AIが原因と解決策を提案してくれます。

**シナリオ:** Node.jsアプリケーションを実行したら、以下のようなエラーが出ました。
</code></pre><p>Error: Cannot find module &rsquo;express'
Require stack:</p>
<ul>
<li>/Users/user/my-project/app.js
at Function.Module._resolveFilename (node:internal/modules/cjs/loader:933:15)
at Function.Module._load (node:internal/modules/cjs/loader:778:27)
at Module.require (node:internal/modules/cjs/loader:1005:19)
at require (node:internal/modules/cjs/helpers:102:18)
at Object.<!-- raw HTML omitted --> (/Users/user/my-project/app.js:1:17)
&hellip;</li>
</ul>
<pre tabindex="0"><code>
**プロンプト:**
</code></pre><p>このエラーの原因と解決方法を教えてください。
@package.json</p>
<pre tabindex="0"><code>`@package.json` を含めることで、プロジェクトの依存関係もコンテキストに加えます。

**AIの回答（例）:**
</code></pre><p>このエラー <code>Error: Cannot find module 'express'</code> は、Node.jsが <code>express</code> モジュールを見つけられないことを示しています。原因は主に2つ考えられます。</p>
<ol>
<li>
<p><strong><code>express</code> がインストールされていない:</strong>
<code>package.json</code> を確認しましたが、<code>dependencies</code> または <code>devDependencies</code> に <code>express</code> が記載されていません。</p>
</li>
<li>
<p><strong><code>node_modules</code> が存在しない、または破損している:</strong>
<code>package.json</code> に記載があっても、<code>npm install</code> を実行していない可能性があります。</p>
</li>
</ol>
<p><strong>解決策:</strong>
以下のコマンドをターミナルで実行してください。</p>
<div class="highlight"><div style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">
<table style="border-spacing:0;padding:0;margin:0;border:0;"><tr><td style="vertical-align:top;padding:0;margin:0;border:0;">
<pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">1
</span></code></pre></td>
<td style="vertical-align:top;padding:0;margin:0;border:0;;width:100%">
<pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span>npm install express
</span></span></code></pre></td></tr></table>
</div>
</div><p>これにより <code>express</code> パッケージがインストールされ、<code>package.json</code> にも依存関係が追加されます。その後、再度アプリケーションを実行してみてください。</p>
<pre tabindex="0"><code>
このように、非常に具体的で実行可能な解決策を提示してくれます。

### 4. 複数ファイルを一括生成・編集「Code Generation (Cmd+Shift+L)」

これはCursorの最新機能の中でも特に強力なものです。単一のプロンプトで、複数の新しいファイルを作成したり、既存のファイルを横断的に編集したりできます。

**シナリオ:** React + Expressで簡単なTodoアプリに、「Todoの編集機能」を追加したい。

`Cmd+Shift+L` を押して、Code Generationモードに入り、以下のプロンプトを入力します。

**プロンプト:**
</code></pre><p>ReactのTodoアプリに編集機能を追加します。以下の変更を加えてください。</p>
<ol>
<li>
<p><code>@src/components/TodoItem.jsx</code> に、編集ボタンと編集フォームを追加します。編集ボタンを押すと、テキストがinputに変わり、Enterキーで更新を確定できるようにしてください。更新処理は <code>handleUpdateTodo</code> という名前で親コンポーネントからpropsで受け取ります。</p>
</li>
<li>
<p><code>@src/App.jsx</code> に、<code>handleUpdateTodo</code> 関数を実装してください。この関数はidと新しいテキストを受け取り、todosステートを更新します。</p>
</li>
<li>
<p><code>@server/index.js</code> (Expressサーバー) に、Todoを更新するための <code>PUT /api/todos/:id</code> エンドポイントを追加してください。</p>
</li>
</ol>
<pre tabindex="0"><code>
このプロンプトを実行すると、Cursorは変更が必要な3つのファイルを特定し、それぞれの変更差分（diff）を並べて表示します。

```diff
--- a/src/components/TodoItem.jsx
+++ b/src/components/TodoItem.jsx
// ... (編集モードの状態管理と、編集用inputを追加するコード)

--- a/src/App.jsx
+++ b/src/App.jsx
// ... (handleUpdateTodo関数の実装を追加するコード)

--- a/server/index.js
+++ b/server/index.js
// ... (app.put(&#39;/api/todos/:id&#39;, ...) の実装を追加するコード)
</code></pre><p>内容を確認し、「Apply」ボタンを押すだけで、3つのファイルすべてに一括で変更が適用されます。この機能は、新しい機能の追加や大規模なAPIの変更など、複数のファイルに影響が及ぶタスクの生産性を劇的に向上させます。</p>
<h2 id="メリットとデメリットvs-code--copilotとの比較">メリットとデメリット：VS Code + Copilotとの比較</h2>
<p>Cursorの導入を検討する上で、既存の環境（特にVS Code + GitHub Copilot）との比較は欠かせません。</p>
<table>
  <thead>
      <tr>
          <th style="text-align: left">機能/観点</th>
          <th style="text-align: left">Cursor</th>
          <th style="text-align: left">VS Code + GitHub Copilot</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td style="text-align: left"><strong>AI統合レベル</strong></td>
          <td style="text-align: left"><strong>深い</strong> (エディタUIに密結合)</td>
          <td style="text-align: left"><strong>浅い</strong> (拡張機能として提供)</td>
      </tr>
      <tr>
          <td style="text-align: left"><strong>主なAI機能</strong></td>
          <td style="text-align: left">対話、リファクタリング、デバッグ、複数ファイル編集、コードベース全体の理解</td>
          <td style="text-align: left">コード補完、チャット（Copilot Chat）</td>
      </tr>
      <tr>
          <td style="text-align: left"><strong>コンテキスト認識</strong></td>
          <td style="text-align: left"><strong>非常に高い</strong> (<code>@</code>でファイル/シンボルを指定可能)</td>
          <td style="text-align: left">限定的（開いているファイルや最近のファイル）</td>
      </tr>
      <tr>
          <td style="text-align: left"><strong>複数ファイル操作</strong></td>
          <td style="text-align: left"><strong>可能</strong> (Code Generation機能)</td>
          <td style="text-align: left">不可（基本は1ファイルずつ）</td>
      </tr>
      <tr>
          <td style="text-align: left"><strong>UI/UX</strong></td>
          <td style="text-align: left">チャットがUIに統合され、インラインでの編集や差分表示がスムーズ</td>
          <td style="text-align: left">補完はインライン、チャットは別パネル。連携はCursorほどシームレスではない</td>
      </tr>
      <tr>
          <td style="text-align: left"><strong>移行コスト</strong></td>
          <td style="text-align: left"><strong>ほぼゼロ</strong> (VS Codeの拡張機能/設定をそのまま利用可能)</td>
          <td style="text-align: left">-</td>
      </tr>
      <tr>
          <td style="text-align: left"><strong>料金</strong></td>
          <td style="text-align: left">無料版あり。Pro版は$20/月 (GPT-4oなど高速モデル利用)</td>
          <td style="text-align: left">Copilotは$10/月。</td>
      </tr>
      <tr>
          <td style="text-align: left"><strong>セキュリティ懸念</strong></td>
          <td style="text-align: left">外部AIにコードを送信（設定で無効化可能）</td>
          <td style="text-align: left">同様</td>
      </tr>
  </tbody>
</table>
<h3 id="cursorのメリット">Cursorのメリット</h3>
<ol>
<li>
<p><strong>コンテキスト認識能力の高さ:</strong> <code>@</code>機能により、AIに「どの情報を見てほしいか」を明示的に伝えられる点が最大の強みです。これにより、AIの回答精度が劇的に向上し、大規模プロジェクトでも的確なサポートを受けられます。</p>
</li>
<li>
<p><strong>タスク実行能力の高さ:</strong> 単なるコード生成に留まらず、「リファクタリング」「デバッグ」「機能追加」といった、より高レベルなタスクを依頼できます。特に<code>Cmd+Shift+L</code>による複数ファイル操作は、Copilotにはない強力な機能です。</p>
</li>
<li>
<p><strong>シームレスなVS Code体験:</strong> 使い慣れたキーバインド、テーマ、そして何百もの拡張機能がそのまま動作します。学習コストをほとんどかけずに、AIの恩恵だけを追加できるのは非常に大きな利点です。</p>
</li>
</ol>
<h3 id="cursorのデメリットと注意点">Cursorのデメリットと注意点</h3>
<ol>
<li>
<p><strong>有料プランの必要性:</strong> 無料版でも基本的な機能は使えますが、GPT-4oのような最新かつ高速なモデルを快適に使うには、Proプラン（月額$20）への加入が推奨されます。これはGitHub Copilot（月額$10）よりも高価です。</p>
</li>
<li>
<p><strong>ネットワーク依存:</strong> 全てのAI機能はクラウド上のモデルを利用するため、オフライン環境では使用できません。</p>
</li>
<li>
<p><strong>セキュリティとプライバシー:</strong> 企業によっては、ソースコードを外部のAIサービスに送信することを禁止している場合があります。Cursorはプライバシーポリシーを公開しており、プライベートなコードはモデルのトレーニングには使用しないと明言していますが、導入前には必ず所属組織のセキュリティポリシーを確認する必要があります。（設定で、ローカルファイルからの情報送信を一部制限するオプションもあります）</p>
</li>
</ol>
<p>結論として、<strong>GitHub Copilotは優れた「オートコンプリート」</strong> であり、<strong>Cursorはより能動的な「AIアシスタント」</strong> と言えるでしょう。単純なコード補完で満足しているならCopilotで十分かもしれませんが、AIと対話し、より複雑なタスクを任せたいのであれば、Cursorへの移行は生産性を飛躍させる価値が十分にあります。</p>
<h2 id="現場で使える実践的なtips">現場で使える実践的なTips</h2>
<p>Cursorを最大限に活用するためには、いくつかのコツがあります。ここでは、明日からすぐに使える実践的なTipsを紹介します。</p>
<h3 id="1-効果的なプロンプトの技術">1. 効果的なプロンプトの技術</h3>
<p>AIの性能はプロンプトの質に大きく左右されます。以下の点を意識するだけで、生成されるコードの質が格段に上がります。</p>
<ul>
<li><strong>役割を与える (Act as&hellip;)</strong>: 「あなたは経験豊富なReactエンジニアです」「あなたはセキュリティ専門家です」のように、AIに役割を与えることで、その分野に特化した回答が得られやすくなります。</li>
<li><strong>コンテキストを豊富に与える</strong>: <code>@</code>で関連ファイルを指定するだけでなく、前提となる技術スタック、コーディング規約、達成したい目標などを具体的に記述します。</li>
<li><strong>出力形式を指定する</strong>: 「Markdown形式で表にして」「JSDocコメントを付けて」「テストコードはJestを使って」のように、希望するアウトプットの形式を明確に指示します。</li>
<li><strong>ステップ・バイ・ステップで考えさせる</strong>: 複雑なタスクを依頼する際は、「まず、必要なコンポーネントをリストアップしてください。次に、それぞれのpropsを設計してください。最後に、コードを生成してください」のように、思考のプロセスを段階的に指示すると、より精度の高い結果が得られます。</li>
</ul>
<h3 id="2-レガシーコードのリファクタリングに活用する">2. レガシーコードのリファクタリングに活用する</h3>
<p>ドキュメントが少なく、複雑に絡み合ったレガシーコードの改善は、Cursorの得意分野です。</p>
<ul>
<li><strong>コードの要約:</strong> 巨大な関数を選択し、「この関数の役割を箇条書きで説明して」と依頼するだけで、処理内容を素早く把握できます。</li>
<li><strong>責務の分離:</strong> 「この関数は責務が多すぎます。関心の分離の原則に基づいて、複数の関数に分割してください」と依頼すれば、リファクタリングの第一歩を自動化できます。</li>
<li><strong>テストコードの生成:</strong> 既存のコードに対して「この関数のためのユニットテストをJestで書いてください。正常系と異常系の両方をカバーしてください」と依頼することで、安全にリファクタリングを進めるためのテストハーネスを効率的に作成できます。</li>
</ul>
<h3 id="3-新しい言語フレームワークの学習ツールとして使う">3. 新しい言語・フレームワークの学習ツールとして使う</h3>
<p>新しい技術を学ぶ際、公式ドキュメントとサンプルコードを行き来するのは大変です。Cursorを使えば、エディタ内で対話しながら学習を進められます。</p>
<ul>
<li><strong>サンプルコードの解説:</strong> Webからコピーしてきたコードを選択し、「このコードが何をしているのか、一行ずつ詳しく解説してください」と質問します。</li>
<li><strong>文法の比較:</strong> 「Pythonのリスト内包表記に似たことを、JavaScriptの配列メソッドで行うにはどうすればいいですか？」といった、言語間の比較質問も有効です。</li>
<li><strong>「お作法」を学ぶ:</strong> 「SvelteKitの流儀に従って、APIエンドポイントを作成するコードを書いてください」のように、フレームワーク特有のベストプラクティスに沿ったコードを生成させることができます。</li>
</ul>
<h3 id="4-コードレビューの補助として使う">4. コードレビューの補助として使う</h3>
<p>人間の目だけでは見逃しがちな問題を、AIに指摘させることも可能です。プルリクエストの対象コードをチャットに貼り付け、以下のようなプロンプトを試してみましょう。</p>
<ul>
<li>「このコードの潜在的なバグやエッジケースを指摘してください。」</li>
<li>「パフォーマンス上のボトルネックになりそうな箇所はありますか？」</li>
<li>「より可読性の高いコードにするための改善案を提案してください。」</li>
</ul>
<p>AIの指摘が常に正しいとは限りませんが、レビューの新たな視点を提供し、議論のきっかけを生むことで、コードの品質向上に貢献します。</p>
<h2 id="まとめ">まとめ</h2>
<p>本記事では、AIネイティブエディタCursorの強力な機能と、それがもたらす新しいコーディングスタイルについて、具体的な例を交えながら深掘りしてきました。</p>
<p>Cursorは、もはや単なる「便利なツール」の域を超え、開発者の思考プロセスそのものを拡張する存在になりつつあります。</p>
<ul>
<li><strong>対話によるコーディング (Cmd+K):</strong> アイデアを自然言語で伝え、瞬時にコードに変換する。</li>
<li><strong>プロジェクト全体の把握 (@チャット):</strong> 巨大なコードベースを前にしても、AIをガイドとして迷うことなく進む。</li>
<li><strong>複雑なタスクの自動化 (Cmd+Shift+L):</strong> 複数ファイルにまたがる変更も、AIに任せて一瞬で完了させる。</li>
</ul>
<p>VS Codeの資産を完全に引き継ぎながら、これほどまでにディープなAI統合を実現したCursorは、AI時代の開発環境の一つの完成形と言えるかもしれません。もちろん、AIは万能ではなく、最終的な判断は常に開発者自身に委ねられています。しかし、面倒で時間のかかる作業をAIに任せることで、私たちはより創造的で、本質的な問題解決に集中できるようになるはずです。</p>
<p>もしあなたがまだCursorを試していないのであれば、ぜひこの機会にインストールし、その実力を体感してみてください。あなたのコーディングライフが、今日から劇的に変わるかもしれません。AIと共にコードを書く未来は、もうすぐそこまで来ています。</p>
]]></content:encoded>
      <category>Coding AI</category>
      <category>Cursor</category>
      <category>VS Code</category>
      <category>Editor</category>
    </item>
    <item>
      <title>【完全解剖】Claude Codeで「SKILLS」が発動する仕組み：裏側で何が起きているのか？</title>
      <link>https://www.ai2core.com/posts/2026-02-13-claude-skills-mechanism/</link>
      <pubDate>Fri, 13 Feb 2026 10:20:00 +0900</pubDate>
      <guid>https://www.ai2core.com/posts/2026-02-13-claude-skills-mechanism/</guid>
      <description>Claude Codeがツール（SKILLS）を認識し、実行するまでの内部プロセスを徹底解説。MCPの仕組みからカスタムスキルのデバッグまで。</description>
      <content:encoded><![CDATA[<h2 id="魔法の裏側を知りたくないですか">「魔法」の裏側を知りたくないですか？</h2>
<p>Claude Codeに「このファイルのバグを直して」と言うと、勝手にファイルを読み、修正し、保存してくれます。
また、「天気を教えて」と言えば、外部APIを叩いて答えてくれます。</p>
<p>まるで魔法のようですが、裏側では<strong>非常に論理的なプロセス</strong>が動いています。</p>
<p>本記事では、エンジニア向けに**「Claude CodeでSKILLS（スキル）が発動する仕組み」**を徹底的に解剖します。</p>
<p>ここを理解すれば、あなたはClaude Codeを「ただ使う人」から「自在に操る人（ツール開発者）」になれます。</p>
<h2 id="1-全体像発動までの4ステップ">1. 全体像：発動までの4ステップ</h2>
<p>Claude Codeがスキルを実行する時、内部では以下の4段階のプロセスが走っています。</p>
<ol>
<li><strong>ツール定義の読み込み (Tool Definition)</strong></li>
<li><strong>意図の検出 (Intent Detection)</strong></li>
<li><strong>引数の生成 (Argument Generation)</strong></li>
<li><strong>実行と結果のフィードバック (Execution &amp; Feedback)</strong></li>
</ol>
<p>それぞれ詳しく見ていきましょう。</p>
<h3 id="step-1-ツール定義の読み込み">Step 1. ツール定義の読み込み</h3>
<p>Claude Codeが起動する時、設定ファイルや <strong>MCP (Model Context Protocol)</strong> サーバーから、「自分は何ができるか」というリストを読み込みます。</p>
<div class="highlight"><div style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">
<table style="border-spacing:0;padding:0;margin:0;border:0;"><tr><td style="vertical-align:top;padding:0;margin:0;border:0;">
<pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 1
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 2
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 3
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 4
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 5
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 6
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 7
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 8
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 9
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">10
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">11
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">12
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">13
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">14
</span></code></pre></td>
<td style="vertical-align:top;padding:0;margin:0;border:0;;width:100%">
<pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-json" data-lang="json"><span style="display:flex;"><span>{
</span></span><span style="display:flex;"><span>  <span style="color:#f92672">&#34;name&#34;</span>: <span style="color:#e6db74">&#34;read_file&#34;</span>,
</span></span><span style="display:flex;"><span>  <span style="color:#f92672">&#34;description&#34;</span>: <span style="color:#e6db74">&#34;指定されたパスのファイルを読み込む&#34;</span>,
</span></span><span style="display:flex;"><span>  <span style="color:#f92672">&#34;parameters&#34;</span>: {
</span></span><span style="display:flex;"><span>    <span style="color:#f92672">&#34;type&#34;</span>: <span style="color:#e6db74">&#34;object&#34;</span>,
</span></span><span style="display:flex;"><span>    <span style="color:#f92672">&#34;properties&#34;</span>: {
</span></span><span style="display:flex;"><span>      <span style="color:#f92672">&#34;path&#34;</span>: {
</span></span><span style="display:flex;"><span>        <span style="color:#f92672">&#34;type&#34;</span>: <span style="color:#e6db74">&#34;string&#34;</span>,
</span></span><span style="display:flex;"><span>        <span style="color:#f92672">&#34;description&#34;</span>: <span style="color:#e6db74">&#34;読み込むファイルの絶対パスまたは相対パス&#34;</span>
</span></span><span style="display:flex;"><span>      }
</span></span><span style="display:flex;"><span>    },
</span></span><span style="display:flex;"><span>    <span style="color:#f92672">&#34;required&#34;</span>: [<span style="color:#e6db74">&#34;path&#34;</span>]
</span></span><span style="display:flex;"><span>  }
</span></span><span style="display:flex;"><span>}
</span></span></code></pre></td></tr></table>
</div>
</div><h3 id="step-2-意図の検出-intent-detection">Step 2. 意図の検出 (Intent Detection)</h3>
<p>ユーザーが「<code>src/main.py</code> の中身が見たい」と発言したとします。</p>
<p>Claudeの脳内（推論プロセス）では、以下のような思考が行われます。</p>
<blockquote>
<p>ユーザーはファイルの中身を知りたがっている。
私の持っている道具リストの中に、それを叶えるものはあるか？
&hellip;あった。<code>read_file</code> だ。
この道具を使おう。</p></blockquote>
<p>これが <strong>Function Calling（関数呼び出し）</strong> のトリガーです。</p>
<h3 id="step-3-引数の生成-argument-generation">Step 3. 引数の生成 (Argument Generation)</h3>
<p>道具を使うと決めたら、次は「どう使うか」を決めます。</p>
<p>定義書の <code>parameters</code> に従って、必要な情報を会話履歴から抽出します。</p>
<ul>
<li>ユーザーの発言: &ldquo;<code>src/main.py</code> の中身&hellip;&rdquo;</li>
<li>引数 <code>path</code>: <code>&quot;src/main.py&quot;</code></li>
</ul>
<p>Claudeは以下のような特殊なトークン（またはJSON）を出力します。</p>
<pre tabindex="0"><code>&lt;tool_use&gt;
  &lt;name&gt;read_file&lt;/name&gt;
  &lt;parameters&gt;
    {&#34;path&#34;: &#34;src/main.py&#34;}
  &lt;/parameters&gt;
&lt;/tool_use&gt;
</code></pre><h3 id="step-4-実行と結果のフィードバック">Step 4. 実行と結果のフィードバック</h3>
<p>ここが重要です。<strong>Claude自身がファイルを読むわけではありません。</strong></p>
<p>Claudeが出力した上記のJSONを、<strong>Claude Codeのランタイム（実行環境）</strong> が受け取ります。
そして、PythonやNode.jsで書かれた実際のプログラム（<code>open()</code> 関数など）が実行されます。</p>
<p>実行結果（ファイルの中身）は、再びテキストとしてClaudeに返されます。</p>
<pre tabindex="0"><code>&lt;tool_result&gt;
  import os
  print(&#34;Hello World&#34;)
&lt;/tool_result&gt;
</code></pre><p>これを見て初めて、Claudeは「ファイルの中身はこうなっていました」とユーザーに回答できるのです。</p>
<h2 id="2-mcp-model-context-protocol-とは">2. MCP (Model Context Protocol) とは？</h2>
<p>最近話題の <strong>MCP</strong> は、この「ツールの渡し方」を標準化した規格です。</p>
<p>これまで、Claudeに独自のツールを追加するには、複雑な設定が必要でした。
しかしMCPを使えば、<strong>「MCPサーバー」</strong> を立ち上げるだけで、Claude Codeが勝手にツールを認識してくれます。</p>
<h3 id="仕組み">仕組み</h3>
<ol>
<li><strong>MCPサーバー</strong>: ツール（関数）の実装を持つプロセス。</li>
<li><strong>MCPクライアント</strong>: Claude Code本体。</li>
</ol>
<p>クライアントとサーバーが通信し、「使えるツール一覧」と「実行リクエスト」をやり取りします。
これにより、ローカルのデータベース操作や、社内APIへのアクセスが安全かつ簡単に実装できるようになりました。</p>
<h2 id="まとめ">まとめ</h2>
<p>Claude Codeの「SKILLS」は、魔法ではありません。
<strong>「定義を読む」→「選ぶ」→「JSONを作る」→「実行結果を読む」</strong> という、非常に泥臭いテキスト処理のループです。</p>
<p>しかし、この仕組みを理解していれば、あなたはClaude Codeを
「ただの話し相手」から
<strong>「手足となって働く最強のパートナー」</strong> に進化させることができます。</p>
<p>ぜひ、自分だけのカスタムスキルを作ってみてください。</p>
]]></content:encoded>
      <category>Coding AI</category>
      <category>Claude Code</category>
      <category>MCP</category>
      <category>Agent</category>
      <category>Architecture</category>
    </item>
    <item>
      <title>Claude Codeに「自分専用スキル」を追加する方法（MCP活用術）</title>
      <link>https://www.ai2core.com/posts/2026-02-12-claude-code-skills/</link>
      <pubDate>Thu, 12 Feb 2026 16:30:00 +0900</pubDate>
      <guid>https://www.ai2core.com/posts/2026-02-12-claude-code-skills/</guid>
      <description>Claude Codeに独自のツールやAPIを連携させ、最強のアシスタントにする方法を解説。</description>
      <content:encoded><![CDATA[<h1 id="claude-codeに自分専用スキルを追加する方法mcp活用術">Claude Codeに「自分専用スキル」を追加する方法（MCP活用術）</h1>
<h2 id="はじめに">はじめに</h2>
<p>Anthropic社のClaude 3、特にコーディング能力に優れた<code>claude-3-opus-20240229</code>モデルは、多くの開発者にとって強力な相棒となりつつあります。コード生成、リファクタリング、デバッグ支援など、その能力は多岐にわたります。</p>
<p>しかし、こんな風に感じたことはありませんか？</p>
<ul>
<li>「Claudeに社内のデータベースへアクセスさせて、最新の売上データを分析させたい…」</li>
<li>「GitHubリポジトリの最新のIssueを要約させたり、新しいチケットをJIRAに起票させたりできたら最高なのに…」</li>
<li>「特定の計算や、自作のコマンドラインツールを実行するよう指示できれば、作業が劇的に効率化されるはずだ…」</li>
</ul>
<p>標準のClaudeは、学習データに含まれる一般的な知識しか持っておらず、あなたの会社のプライベートな情報や、リアルタイムの外部情報にアクセスすることはできません。これまでは、開発者が手動でAPIを叩き、その結果をコピー＆ペーストしてClaudeに与える、という手間のかかる作業が必要でした。</p>
<p>もし、Claudeに**「あなた専用のスキル」**を自由に追加できたらどうでしょう？まるで優秀なアシスタントに新しい能力を教え込むように、独自のツールやAPIと連携させることができたら。</p>
<p>この記事では、Anthropicが提供する**「Tool Use（ツール使用）」機能<strong>を活用し、Claudeをあなただけの最強コーディング・アシスタントへと進化させる具体的な方法を、詳細なコード例とともに解説します。この記事で言う</strong>MCP（Multi-turn Conversational Platform）活用術**とは、まさにこのTool Use機能を駆使して、対話型AIの能力を最大限に引き出す実践的なテクニックを指します。</p>
<p>この記事を読み終える頃には、あなたはClaudeに独自の「スキル」を授け、開発ワークフローを根本から変革する力を手に入れているはずです。</p>
<h2 id="なぜ今tool-useが重要なのか">なぜ今、「Tool Use」が重要なのか？</h2>
<p>LLM（大規模言語モデル）は、単に質問に答えたり文章を生成したりするだけの存在から、外部の世界と対話し、能動的にタスクを実行する**「エージェント」**へと進化しつつあります。その中核をなす技術が、ChatGPTにおける「Function Calling」であり、Claudeにおける「Tool Use」です。</p>
<p>この技術がなぜゲームチェンジャーとなり得るのか、その背景にある課題と合わせて見ていきましょう。</p>
<h3 id="従来のllmが抱えていた課題">従来のLLMが抱えていた課題</h3>
<ol>
<li><strong>知識の陳腐化と非公開情報へのアクセス不可:</strong> LLMの知識は、学習データがカットオフされた時点のものであり、リアルタイムの情報（今日の天気、最新の株価など）を知りません。また、社内DBや個人のファイルなど、インターネット上に公開されていない情報には当然アクセスできません。</li>
<li><strong>手動による連携の非効率性:</strong> 開発者が外部APIから取得したデータをLLMに渡す場合、手動でのコピー＆ペーストが必要でした。このプロセスは手間がかかるだけでなく、ヒューマンエラーの温床にもなります。</li>
<li><strong>プロンプトの複雑化と再現性の低さ:</strong> 複雑なタスクを指示しようとすると、プロンプトが非常に長大かつ複雑になりがちです。「まずこのAPIを叩いてJSONを取得し、その中の<code>items</code>配列をループして、各<code>name</code>と<code>price</code>を抽出し、マークダウンのテーブル形式で出力して…」といった詳細な手順を毎回プロンプトに記述するのは現実的ではありません。</li>
</ol>
<h3 id="tool-useがもたらす解決策">「Tool Use」がもたらす解決策</h3>
<p>ClaudeのTool Use機能は、これらの課題をエレガントに解決します。その仕組みは、LLMと開発者が協調して動作するフレームワークです。</p>
<p><strong>Tool Useの基本的なフロー</strong></p>
<pre tabindex="0"><code class="language-mermaid" data-lang="mermaid">sequenceDiagram
    participant User as ユーザー
    participant App as 開発者のアプリケーション
    participant Claude as Claude
    participant Tool as 外部ツール/API

    User-&gt;&gt;App: 「東京の天気は？」
    App-&gt;&gt;Claude: ユーザーの質問と利用可能なツール定義を渡す
    Claude-&gt;&gt;Claude: 質問を解釈し、「get_weather」ツールが使えると判断
    Claude-&gt;&gt;App: 「get_weather(city=&#39;Tokyo&#39;)」を実行してほしい、とJSON形式で要求
    App-&gt;&gt;Tool: 実際に天気APIを呼び出す
    Tool--&gt;&gt;App: 天気データ（JSON）を返す
    App-&gt;&gt;Claude: ツール実行結果（天気データ）を渡す
    Claude-&gt;&gt;Claude: 実行結果を解釈し、自然言語の回答を生成
    Claude-&gt;&gt;App: 「東京の天気は晴れです。」
    App-&gt;&gt;User: 最終的な回答を表示
</code></pre><p>このフローが示すように、Tool Useは以下の役割分担によって成り立っています。</p>
<ul>
<li><strong>Claudeの役割:</strong> ユーザーの意図を汲み取り、どのツールを、どのような引数で使うべきかを判断し、JSON形式で開発者に伝達する。そして、ツールの実行結果を受け取り、それを基に最終的な回答を生成する。</li>
<li><strong>開発者の役割:</strong> Claudeが利用可能な「スキル」（ツール）の仕様を定義し、Claudeからツール実行の要求を受け取ったら、実際にそのツール（関数やAPIコール）を実行し、結果をClaudeに返す。</li>
</ul>
<p>これにより、LLMは思考や判断に集中し、実際の「行動」は開発者が用意した信頼性の高いコードが担う、という強力な分業体制が実現します。これは、LLMを単なる「知識ベース」から、具体的なタスクをこなす「実行エンジン」へと昇華させる、きわめて重要なパラダイムシフトなのです。</p>
<h2 id="具体的な実装方法claudeに天気を尋ねるスキルを追加する">具体的な実装方法：Claudeに天気を尋ねるスキルを追加する</h2>
<p>それでは、実際に手を動かして、Claudeに「天気を尋ねるスキル」を追加してみましょう。ここではPython用のAnthropic SDKを使用します。</p>
<h3 id="step-1-準備">Step 1: 準備</h3>
<p>まず、必要なライブラリをインストールし、APIキーを設定します。</p>
<div class="highlight"><div style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">
<table style="border-spacing:0;padding:0;margin:0;border:0;"><tr><td style="vertical-align:top;padding:0;margin:0;border:0;">
<pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">1
</span></code></pre></td>
<td style="vertical-align:top;padding:0;margin:0;border:0;;width:100%">
<pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span>pip install anthropic
</span></span></code></pre></td></tr></table>
</div>
</div><p>APIキーは環境変数に設定しておくのが一般的です。</p>
<div class="highlight"><div style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">
<table style="border-spacing:0;padding:0;margin:0;border:0;"><tr><td style="vertical-align:top;padding:0;margin:0;border:0;">
<pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">1
</span></code></pre></td>
<td style="vertical-align:top;padding:0;margin:0;border:0;;width:100%">
<pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span>export ANTHROPIC_API_KEY<span style="color:#f92672">=</span><span style="color:#e6db74">&#34;YOUR_ANTHROPIC_API_KEY&#34;</span>
</span></span></code></pre></td></tr></table>
</div>
</div><h3 id="step-2-スキルツールの定義">Step 2: 「スキル」（ツール）の定義</h3>
<p>最初に、Claudeに「こんなツールが使えますよ」と教えるための定義を作成します。今回は、特定の都市の天気を取得する<code>get_weather</code>というツールを定義しましょう。</p>
<p>このツール定義は、Claudeがツールの機能、目的、そして必要な引数を理解するために非常に重要です。</p>
<div class="highlight"><div style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">
<table style="border-spacing:0;padding:0;margin:0;border:0;"><tr><td style="vertical-align:top;padding:0;margin:0;border:0;">
<pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 1
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 2
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 3
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 4
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 5
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 6
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 7
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 8
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 9
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">10
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">11
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">12
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">13
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">14
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">15
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">16
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">17
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">18
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">19
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">20
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">21
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">22
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">23
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">24
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">25
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">26
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">27
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">28
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">29
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">30
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">31
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">32
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">33
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">34
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">35
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">36
</span></code></pre></td>
<td style="vertical-align:top;padding:0;margin:0;border:0;;width:100%">
<pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-python" data-lang="python"><span style="display:flex;"><span><span style="color:#f92672">import</span> anthropic
</span></span><span style="display:flex;"><span><span style="color:#f92672">import</span> json
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#75715e"># Anthropicクライアントの初期化</span>
</span></span><span style="display:flex;"><span>client <span style="color:#f92672">=</span> anthropic<span style="color:#f92672">.</span>Anthropic()
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#75715e"># --- ここからがツールの定義 ---</span>
</span></span><span style="display:flex;"><span>tools <span style="color:#f92672">=</span> [
</span></span><span style="display:flex;"><span>    {
</span></span><span style="display:flex;"><span>        <span style="color:#e6db74">&#34;name&#34;</span>: <span style="color:#e6db74">&#34;get_weather&#34;</span>,
</span></span><span style="display:flex;"><span>        <span style="color:#e6db74">&#34;description&#34;</span>: <span style="color:#e6db74">&#34;特定の都市の現在の天気を取得します。ユーザーが天気について尋ねた場合に使用します。&#34;</span>,
</span></span><span style="display:flex;"><span>        <span style="color:#e6db74">&#34;input_schema&#34;</span>: {
</span></span><span style="display:flex;"><span>            <span style="color:#e6db74">&#34;type&#34;</span>: <span style="color:#e6db74">&#34;object&#34;</span>,
</span></span><span style="display:flex;"><span>            <span style="color:#e6db74">&#34;properties&#34;</span>: {
</span></span><span style="display:flex;"><span>                <span style="color:#e6db74">&#34;city&#34;</span>: {
</span></span><span style="display:flex;"><span>                    <span style="color:#e6db74">&#34;type&#34;</span>: <span style="color:#e6db74">&#34;string&#34;</span>,
</span></span><span style="display:flex;"><span>                    <span style="color:#e6db74">&#34;description&#34;</span>: <span style="color:#e6db74">&#34;天気を知りたい都市名。例: &#39;東京&#39;, &#39;サンフランシスコ&#39;&#34;</span>
</span></span><span style="display:flex;"><span>                }
</span></span><span style="display:flex;"><span>            },
</span></span><span style="display:flex;"><span>            <span style="color:#e6db74">&#34;required&#34;</span>: [<span style="color:#e6db74">&#34;city&#34;</span>]
</span></span><span style="display:flex;"><span>        }
</span></span><span style="display:flex;"><span>    }
</span></span><span style="display:flex;"><span>]
</span></span><span style="display:flex;"><span><span style="color:#75715e"># --- ここまでがツールの定義 ---</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#75715e"># 開発者側で実際にツールを実行する関数を定義</span>
</span></span><span style="display:flex;"><span><span style="color:#75715e"># (この例では実際のAPIは叩かず、ダミーデータを返す)</span>
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">def</span> <span style="color:#a6e22e">get_weather</span>(city: str):
</span></span><span style="display:flex;"><span>    <span style="color:#e6db74">&#34;&#34;&#34;指定された都市の天気を取得する（ダミー関数）&#34;&#34;&#34;</span>
</span></span><span style="display:flex;"><span>    print(<span style="color:#e6db74">f</span><span style="color:#e6db74">&#34;--- ツール実行: get_weather(city=&#39;</span><span style="color:#e6db74">{</span>city<span style="color:#e6db74">}</span><span style="color:#e6db74">&#39;) ---&#34;</span>)
</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">if</span> <span style="color:#e6db74">&#34;東京&#34;</span> <span style="color:#f92672">in</span> city:
</span></span><span style="display:flex;"><span>        <span style="color:#66d9ef">return</span> json<span style="color:#f92672">.</span>dumps({<span style="color:#e6db74">&#34;city&#34;</span>: <span style="color:#e6db74">&#34;東京&#34;</span>, <span style="color:#e6db74">&#34;temperature&#34;</span>: <span style="color:#ae81ff">25</span>, <span style="color:#e6db74">&#34;weather&#34;</span>: <span style="color:#e6db74">&#34;晴れ&#34;</span>})
</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">elif</span> <span style="color:#e6db74">&#34;大阪&#34;</span> <span style="color:#f92672">in</span> city:
</span></span><span style="display:flex;"><span>        <span style="color:#66d9ef">return</span> json<span style="color:#f92672">.</span>dumps({<span style="color:#e6db74">&#34;city&#34;</span>: <span style="color:#e6db74">&#34;大阪&#34;</span>, <span style="color:#e6db74">&#34;temperature&#34;</span>: <span style="color:#ae81ff">22</span>, <span style="color:#e6db74">&#34;weather&#34;</span>: <span style="color:#e6db74">&#34;くもり&#34;</span>})
</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">else</span>:
</span></span><span style="display:flex;"><span>        <span style="color:#66d9ef">return</span> json<span style="color:#f92672">.</span>dumps({<span style="color:#e6db74">&#34;city&#34;</span>: city, <span style="color:#e6db74">&#34;temperature&#34;</span>: <span style="color:#e6db74">&#34;不明&#34;</span>, <span style="color:#e6db74">&#34;weather&#34;</span>: <span style="color:#e6db74">&#34;不明&#34;</span>})
</span></span></code></pre></td></tr></table>
</div>
</div><p>ここで重要なのは<code>tools</code>リストの中身です。</p>
<ul>
<li><code>name</code>: ツールの名前です。Claudeがどのツールを呼び出すか指定するのに使います。</li>
<li><code>description</code>: <strong>最も重要な要素の一つです。</strong> Claudeはこの説明を読んで、いつ、何のためにこのツールを使うべきかを判断します。具体的で分かりやすい説明を心がけましょう。</li>
<li><code>input_schema</code>: ツールが必要とする引数をJSON Schema形式で定義します。これにより、Claudeは正しい引数名とデータ型でツールを呼び出そうとします。</li>
</ul>
<h3 id="step-3-claudeにツール使用を促すリクエストを送信">Step 3: Claudeにツール使用を促すリクエストを送信</h3>
<p>次に、ユーザーからの質問と、先ほど定義したツールリストをClaudeに渡します。</p>
<div class="highlight"><div style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">
<table style="border-spacing:0;padding:0;margin:0;border:0;"><tr><td style="vertical-align:top;padding:0;margin:0;border:0;">
<pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 1
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 2
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 3
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 4
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 5
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 6
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 7
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 8
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 9
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">10
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">11
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">12
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">13
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">14
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">15
</span></code></pre></td>
<td style="vertical-align:top;padding:0;margin:0;border:0;;width:100%">
<pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-python" data-lang="python"><span style="display:flex;"><span><span style="color:#75715e"># ユーザーからの質問</span>
</span></span><span style="display:flex;"><span>user_message <span style="color:#f92672">=</span> <span style="color:#e6db74">&#34;今日の東京の天気はどうですか？&#34;</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>print(<span style="color:#e6db74">f</span><span style="color:#e6db74">&#34;ユーザー: </span><span style="color:#e6db74">{</span>user_message<span style="color:#e6db74">}</span><span style="color:#e6db74">&#34;</span>)
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#75715e"># Claudeに最初のメッセージを送信</span>
</span></span><span style="display:flex;"><span>response <span style="color:#f92672">=</span> client<span style="color:#f92672">.</span>messages<span style="color:#f92672">.</span>create(
</span></span><span style="display:flex;"><span>    model<span style="color:#f92672">=</span><span style="color:#e6db74">&#34;claude-3-opus-20240229&#34;</span>,
</span></span><span style="display:flex;"><span>    max_tokens<span style="color:#f92672">=</span><span style="color:#ae81ff">1024</span>,
</span></span><span style="display:flex;"><span>    messages<span style="color:#f92672">=</span>[{<span style="color:#e6db74">&#34;role&#34;</span>: <span style="color:#e6db74">&#34;user&#34;</span>, <span style="color:#e6db74">&#34;content&#34;</span>: user_message}],
</span></span><span style="display:flex;"><span>    tools<span style="color:#f92672">=</span>tools, <span style="color:#75715e"># ここで定義したツールを渡す</span>
</span></span><span style="display:flex;"><span>)
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>print(<span style="color:#e6db74">&#34;</span><span style="color:#ae81ff">\n</span><span style="color:#e6db74">--- Claudeからの初回応答 ---&#34;</span>)
</span></span><span style="display:flex;"><span>print(response)
</span></span></code></pre></td></tr></table>
</div>
</div><p>このコードを実行すると、Claudeからの応答は通常のテキストではなく、ツールを使用するべきだという特別な形式で返ってきます。</p>
<h3 id="step-4-claudeからの応答ツール使用要求を処理する">Step 4: Claudeからの応答（ツール使用要求）を処理する</h3>
<p><code>response</code>の中身を確認してみましょう。特に<code>stop_reason</code>と<code>content</code>に注目です。</p>
<pre tabindex="0"><code># responseの出力例
Message(
    id=&#39;...&#39;,
    content=[
        ToolUseBlock(
            id=&#39;toolu_01A09q90e9QyqG7LLVf9i4t4&#39;,  # ツール使用ごとのユニークID
            input={&#39;city&#39;: &#39;東京&#39;},
            name=&#39;get_weather&#39;,
            type=&#39;tool_use&#39;
        )
    ],
    model=&#39;claude-3-opus-20240229&#39;,
    role=&#39;assistant&#39;,
    stop_reason=&#39;tool_use&#39;, # 停止理由が &#39;tool_use&#39; になっている！
    stop_sequence=None,
    type=&#39;message&#39;,
    usage=Usage(input_tokens=..., output_tokens=...)
)
</code></pre><p><code>stop_reason</code>が<code>'tool_use'</code>になっているのが分かります。これは、「私は会話を一旦停止します。なぜなら、あなたが定義したツールを使いたいからです」というClaudeからの合図です。</p>
<p><code>content</code>リストには、<code>ToolUseBlock</code>オブジェクトが含まれており、どのツール（<code>name</code>）を、どの引数（<code>input</code>）で呼び出してほしいかが具体的に示されています。</p>
<p>この情報を使って、実際にツールを実行します。</p>
<div class="highlight"><div style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">
<table style="border-spacing:0;padding:0;margin:0;border:0;"><tr><td style="vertical-align:top;padding:0;margin:0;border:0;">
<pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 1
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 2
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 3
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 4
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 5
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 6
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 7
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 8
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 9
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">10
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">11
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">12
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">13
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">14
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">15
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">16
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">17
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">18
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">19
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">20
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">21
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">22
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">23
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">24
</span></code></pre></td>
<td style="vertical-align:top;padding:0;margin:0;border:0;;width:100%">
<pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-python" data-lang="python"><span style="display:flex;"><span><span style="color:#75715e"># 会話の履歴を保持するリスト</span>
</span></span><span style="display:flex;"><span>conversation_history <span style="color:#f92672">=</span> [{<span style="color:#e6db74">&#34;role&#34;</span>: <span style="color:#e6db74">&#34;user&#34;</span>, <span style="color:#e6db74">&#34;content&#34;</span>: user_message}]
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#75715e"># Claudeの応答を履歴に追加</span>
</span></span><span style="display:flex;"><span>assistant_response_content <span style="color:#f92672">=</span> response<span style="color:#f92672">.</span>content
</span></span><span style="display:flex;"><span>conversation_history<span style="color:#f92672">.</span>append({<span style="color:#e6db74">&#34;role&#34;</span>: <span style="color:#e6db74">&#34;assistant&#34;</span>, <span style="color:#e6db74">&#34;content&#34;</span>: assistant_response_content})
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#75715e"># ツール使用要求があるかチェック</span>
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">if</span> response<span style="color:#f92672">.</span>stop_reason <span style="color:#f92672">==</span> <span style="color:#e6db74">&#34;tool_use&#34;</span>:
</span></span><span style="display:flex;"><span>    tool_use <span style="color:#f92672">=</span> next((block <span style="color:#66d9ef">for</span> block <span style="color:#f92672">in</span> response<span style="color:#f92672">.</span>content <span style="color:#66d9ef">if</span> block<span style="color:#f92672">.</span>type <span style="color:#f92672">==</span> <span style="color:#e6db74">&#34;tool_use&#34;</span>), <span style="color:#66d9ef">None</span>)
</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">if</span> tool_use:
</span></span><span style="display:flex;"><span>        tool_name <span style="color:#f92672">=</span> tool_use<span style="color:#f92672">.</span>name
</span></span><span style="display:flex;"><span>        tool_input <span style="color:#f92672">=</span> tool_use<span style="color:#f92672">.</span>input
</span></span><span style="display:flex;"><span>        tool_use_id <span style="color:#f92672">=</span> tool_use<span style="color:#f92672">.</span>id
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>        print(<span style="color:#e6db74">f</span><span style="color:#e6db74">&#34;</span><span style="color:#ae81ff">\n</span><span style="color:#e6db74">--- Claudeがツール &#39;</span><span style="color:#e6db74">{</span>tool_name<span style="color:#e6db74">}</span><span style="color:#e6db74">&#39; の使用を要求 ---&#34;</span>)
</span></span><span style="display:flex;"><span>        print(<span style="color:#e6db74">f</span><span style="color:#e6db74">&#34;引数: </span><span style="color:#e6db74">{</span>tool_input<span style="color:#e6db74">}</span><span style="color:#e6db74">&#34;</span>)
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>        <span style="color:#75715e"># ツール名に応じて適切な関数を実行</span>
</span></span><span style="display:flex;"><span>        <span style="color:#66d9ef">if</span> tool_name <span style="color:#f92672">==</span> <span style="color:#e6db74">&#34;get_weather&#34;</span>:
</span></span><span style="display:flex;"><span>            tool_result <span style="color:#f92672">=</span> get_weather(city<span style="color:#f92672">=</span>tool_input[<span style="color:#e6db74">&#34;city&#34;</span>])
</span></span><span style="display:flex;"><span>        <span style="color:#66d9ef">else</span>:
</span></span><span style="display:flex;"><span>            <span style="color:#75715e"># 未知のツールが要求された場合のエラーハンドリング</span>
</span></span><span style="display:flex;"><span>            tool_result <span style="color:#f92672">=</span> json<span style="color:#f92672">.</span>dumps({<span style="color:#e6db74">&#34;error&#34;</span>: <span style="color:#e6db74">f</span><span style="color:#e6db74">&#34;Unknown tool: </span><span style="color:#e6db74">{</span>tool_name<span style="color:#e6db74">}</span><span style="color:#e6db74">&#34;</span>})
</span></span></code></pre></td></tr></table>
</div>
</div><h3 id="step-5-ツール実行結果をclaudeに返す">Step 5: ツール実行結果をClaudeに返す</h3>
<p>ツールを実行したら、その結果をClaudeにフィードバックする必要があります。これにより、Claudeは次のステップに進むことができます。</p>
<p>結果を返す際は、「どのツール実行要求に対する結果なのか」を明確にするために、Step 4で取得した<code>tool_use_id</code>を使います。</p>
<div class="highlight"><div style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">
<table style="border-spacing:0;padding:0;margin:0;border:0;"><tr><td style="vertical-align:top;padding:0;margin:0;border:0;">
<pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 1
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 2
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 3
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 4
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 5
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 6
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 7
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 8
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 9
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">10
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">11
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">12
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">13
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">14
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">15
</span></code></pre></td>
<td style="vertical-align:top;padding:0;margin:0;border:0;;width:100%">
<pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-python" data-lang="python"><span style="display:flex;"><span>        print(<span style="color:#e6db74">f</span><span style="color:#e6db74">&#34;ツール実行結果: </span><span style="color:#e6db74">{</span>tool_result<span style="color:#e6db74">}</span><span style="color:#e6db74">&#34;</span>)
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>        <span style="color:#75715e"># ツール実行結果を会話履歴に追加</span>
</span></span><span style="display:flex;"><span>        conversation_history<span style="color:#f92672">.</span>append(
</span></span><span style="display:flex;"><span>            {
</span></span><span style="display:flex;"><span>                <span style="color:#e6db74">&#34;role&#34;</span>: <span style="color:#e6db74">&#34;user&#34;</span>,
</span></span><span style="display:flex;"><span>                <span style="color:#e6db74">&#34;content&#34;</span>: [
</span></span><span style="display:flex;"><span>                    {
</span></span><span style="display:flex;"><span>                        <span style="color:#e6db74">&#34;type&#34;</span>: <span style="color:#e6db74">&#34;tool_result&#34;</span>,
</span></span><span style="display:flex;"><span>                        <span style="color:#e6db74">&#34;tool_use_id&#34;</span>: tool_use_id,
</span></span><span style="display:flex;"><span>                        <span style="color:#e6db74">&#34;content&#34;</span>: tool_result,
</span></span><span style="display:flex;"><span>                    }
</span></span><span style="display:flex;"><span>                ],
</span></span><span style="display:flex;"><span>            }
</span></span><span style="display:flex;"><span>        )
</span></span></code></pre></td></tr></table>
</div>
</div><h3 id="step-6-claudeからの最終的な回答を得る">Step 6: Claudeからの最終的な回答を得る</h3>
<p>最後に、ツール実行結果を含む更新された会話履歴を、再度Claudeに送信します。</p>
<div class="highlight"><div style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">
<table style="border-spacing:0;padding:0;margin:0;border:0;"><tr><td style="vertical-align:top;padding:0;margin:0;border:0;">
<pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 1
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 2
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 3
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 4
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 5
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 6
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 7
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 8
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 9
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">10
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">11
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">12
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">13
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">14
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">15
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">16
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">17
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">18
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">19
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">20
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">21
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">22
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">23
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">24
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">25
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">26
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">27
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">28
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">29
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">30
</span></code></pre></td>
<td style="vertical-align:top;padding:0;margin:0;border:0;;width:100%">
<pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-python" data-lang="python"><span style="display:flex;"><span>        print(<span style="color:#e6db74">&#34;</span><span style="color:#ae81ff">\n</span><span style="color:#e6db74">--- ツール実行結果をClaudeに送信し、最終回答を要求 ---&#34;</span>)
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>        <span style="color:#75715e"># ツール実行結果を踏まえた最終的な応答をClaudeに生成させる</span>
</span></span><span style="display:flex;"><span>        final_response <span style="color:#f92672">=</span> client<span style="color:#f92672">.</span>messages<span style="color:#f92672">.</span>create(
</span></span><span style="display:flex;"><span>            model<span style="color:#f92672">=</span><span style="color:#e6db74">&#34;claude-3-opus-20240229&#34;</span>,
</span></span><span style="display:flex;"><span>            max_tokens<span style="color:#f92672">=</span><span style="color:#ae81ff">2048</span>,
</span></span><span style="display:flex;"><span>            messages<span style="color:#f92672">=</span>conversation_history, <span style="color:#75715e"># 更新された会話履歴を渡す</span>
</span></span><span style="display:flex;"><span>            tools<span style="color:#f92672">=</span>tools,
</span></span><span style="display:flex;"><span>        )
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>        print(<span style="color:#e6db74">&#34;</span><span style="color:#ae81ff">\n</span><span style="color:#e6db74">--- Claudeからの最終回答 ---&#34;</span>)
</span></span><span style="display:flex;"><span>        final_answer <span style="color:#f92672">=</span> final_response<span style="color:#f92672">.</span>content[<span style="color:#ae81ff">0</span>]<span style="color:#f92672">.</span>text
</span></span><span style="display:flex;"><span>        print(final_answer)
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#75715e"># 実行結果の例:</span>
</span></span><span style="display:flex;"><span><span style="color:#75715e">#</span>
</span></span><span style="display:flex;"><span><span style="color:#75715e"># ユーザー: 今日の東京の天気はどうですか？</span>
</span></span><span style="display:flex;"><span><span style="color:#75715e">#</span>
</span></span><span style="display:flex;"><span><span style="color:#75715e"># --- Claudeからの初回応答 ---</span>
</span></span><span style="display:flex;"><span><span style="color:#75715e"># ... (ToolUseBlockを含むMessageオブジェクト) ...</span>
</span></span><span style="display:flex;"><span><span style="color:#75715e">#</span>
</span></span><span style="display:flex;"><span><span style="color:#75715e"># --- Claudeがツール &#39;get_weather&#39; の使用を要求 ---</span>
</span></span><span style="display:flex;"><span><span style="color:#75715e"># 引数: {&#39;city&#39;: &#39;東京&#39;}</span>
</span></span><span style="display:flex;"><span><span style="color:#75715e"># --- ツール実行: get_weather(city=&#39;東京&#39;) ---</span>
</span></span><span style="display:flex;"><span><span style="color:#75715e"># ツール実行結果: {&#34;city&#34;: &#34;東京&#34;, &#34;temperature&#34;: 25, &#34;weather&#34;: &#34;晴れ&#34;}</span>
</span></span><span style="display:flex;"><span><span style="color:#75715e">#</span>
</span></span><span style="display:flex;"><span><span style="color:#75715e"># --- ツール実行結果をClaudeに送信し、最終回答を要求 ---</span>
</span></span><span style="display:flex;"><span><span style="color:#75715e">#</span>
</span></span><span style="display:flex;"><span><span style="color:#75715e"># --- Claudeからの最終回答 ---</span>
</span></span><span style="display:flex;"><span><span style="color:#75715e"># 東京の今日の天気は晴れで、気温は25度です。</span>
</span></span></code></pre></td></tr></table>
</div>
</div><p>見事にClaudeが外部ツール（今回はダミー関数）と連携し、ユーザーの質問に答えることができました。これがTool Useの基本的な流れです。</p>
<h2 id="メリットとデメリット">メリットとデメリット</h2>
<p>この強力なTool Use機能ですが、もちろん良い点ばかりではありません。導入を検討する上で、メリットとデメリットを正しく理解しておくことが重要です。</p>
<h3 id="メリット">メリット</h3>
<ol>
<li><strong>無限の拡張性:</strong> Claudeの能力を、事実上無限に拡張できます。社内API、外部のSaaS、ローカルのスクリプト実行、データベース操作など、APIや関数として呼び出せるものなら何でも連携可能です。</li>
<li><strong>タスクの自動化と生産性向上:</strong> JIRAチケットの作成、GitHubのIssue要約、デプロイメントのキックなど、これまで手作業で行っていた定型的なタスクを自然言語の指示で自動化でき、開発者の生産性を劇的に向上させます。</li>
<li><strong>対話の自然さ:</strong> ユーザーはツールの存在やAPIの仕様を意識する必要がありません。ただ自然言語で「〜して」と頼むだけで、裏側で適切なツールが呼び出されます。</li>
<li><strong>信頼性の向上:</strong> LLM単体では事実に基づかない回答（ハルシネーション）を生成することがありますが、Tool Useを使えば、信頼できる情報源（APIの実行結果など）に基づいた回答を生成させることができます。</li>
<li><strong>プロンプトの抽象化:</strong> 複雑な手順を長々とプロンプトに書く代わりに、それらを一つのツールとしてカプセル化できます。プロンプトは簡潔になり、メンテナンス性も向上します。</li>
</ol>
<h3 id="デメリット">デメリット</h3>
<ol>
<li><strong>実装コスト:</strong> ツール定義の作成、API連携ロジックの実装、エラーハンドリングなど、開発者側でのコーディングが必要です。手軽に試せるものではなく、システムへの組み込みには設計と実装のコストがかかります。</li>
<li><strong>APIコストの増加:</strong> 一つの質問応答フローの中で、ClaudeのAPIを複数回（ツール使用判断で1回、最終回答生成で1回）呼び出すことになります。これにより、APIの利用料金が増加する可能性があります。</li>
<li><strong>レイテンシの増加:</strong> ツール実行（特に外部APIの呼び出し）には時間がかかるため、応答全体のレイテンシは長くなる傾向にあります。ユーザー体験を損なわないよう、パフォーマンスへの配慮が必要です。</li>
<li><strong>セキュリティリスク:</strong> データベースの更新やファイルの削除など、破壊的な操作を伴うツールを連携させる場合は、細心の注意が必要です。Claudeに意図しない操作を実行させないよう、厳格な権限管理、入力値のサニタイズ、実行前の人間による確認ステップなどを設けるべきです。</li>
</ol>
<h2 id="現場で使える実践的なtips">現場で使える実践的なTips</h2>
<p>基本的な使い方をマスターしたところで、より実践的なシナリオでTool Useを使いこなすためのヒントをいくつか紹介します。</p>
<h3 id="1-良いツール設計の原則descriptionが命">1. 良いツール設計の原則：<code>description</code>が命</h3>
<p>Claudeがツールを正しく使いこなせるかどうかは、ツールの<code>description</code>（説明文）の品質に大きく依存します。</p>
<p><strong>悪い例 ❌:</strong>
<code>&quot;description&quot;: &quot;DBからデータを取得する&quot;</code>
→ これでは、いつ、何のデータを、どのように取得するのかが全く分かりません。</p>
<p><strong>良い例 ✅:</strong>
<code>&quot;description&quot;: &quot;指定されたSQLクエリを読み取り専用の分析データベースで実行し、結果をJSON形式で返します。主に売上データやユーザー行動ログの集計・分析に使用します。データの更新や削除はできません。&quot;</code>
→ この説明により、Claudeは「売上分析の依頼が来たらこのツールを使おう」「SQLを生成して引数に渡せばいいんだな」「データを書き換えることはできないな」といったことを正確に理解できます。</p>
<p><strong>引数の説明も同様に重要です。</strong> ユーザーが曖昧な指示をした際に、Claudeがどの情報を追加でヒアリングすべきかの判断材料になります。</p>
<h3 id="2-堅牢なエラーハンドリング">2. 堅牢なエラーハンドリング</h3>
<p>ツールの実行は常に成功するとは限りません。APIがタイムアウトしたり、データベース接続に失敗したり、不正な引数が渡されたりすることもあります。</p>
<p>このような場合、エラー情報を適切にClaudeに返すことで、Claudeがユーザーに対して状況を説明したり、リトライを促したりできるようになります。</p>
<div class="highlight"><div style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">
<table style="border-spacing:0;padding:0;margin:0;border:0;"><tr><td style="vertical-align:top;padding:0;margin:0;border:0;">
<pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 1
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 2
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 3
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 4
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 5
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 6
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 7
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 8
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 9
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">10
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">11
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">12
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">13
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">14
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">15
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">16
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">17
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">18
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">19
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">20
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">21
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">22
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">23
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">24
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">25
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">26
</span></code></pre></td>
<td style="vertical-align:top;padding:0;margin:0;border:0;;width:100%">
<pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-python" data-lang="python"><span style="display:flex;"><span><span style="color:#66d9ef">def</span> <span style="color:#a6e22e">query_database</span>(sql_query: str):
</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">try</span>:
</span></span><span style="display:flex;"><span>        <span style="color:#75715e"># ... データベース接続とクエリ実行のロジック ...</span>
</span></span><span style="display:flex;"><span>        result <span style="color:#f92672">=</span> db<span style="color:#f92672">.</span>execute(sql_query)
</span></span><span style="display:flex;"><span>        <span style="color:#66d9ef">return</span> json<span style="color:#f92672">.</span>dumps({<span style="color:#e6db74">&#34;status&#34;</span>: <span style="color:#e6db74">&#34;success&#34;</span>, <span style="color:#e6db74">&#34;data&#34;</span>: result})
</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">except</span> <span style="color:#a6e22e">Exception</span> <span style="color:#66d9ef">as</span> e:
</span></span><span style="display:flex;"><span>        <span style="color:#75715e"># エラーが発生したら、エラー情報を返す</span>
</span></span><span style="display:flex;"><span>        print(<span style="color:#e6db74">f</span><span style="color:#e6db74">&#34;--- ツール実行エラー: </span><span style="color:#e6db74">{</span>e<span style="color:#e6db74">}</span><span style="color:#e6db74"> ---&#34;</span>)
</span></span><span style="display:flex;"><span>        <span style="color:#66d9ef">return</span> json<span style="color:#f92672">.</span>dumps({
</span></span><span style="display:flex;"><span>            <span style="color:#e6db74">&#34;status&#34;</span>: <span style="color:#e6db74">&#34;error&#34;</span>,
</span></span><span style="display:flex;"><span>            <span style="color:#e6db74">&#34;error_message&#34;</span>: <span style="color:#e6db74">f</span><span style="color:#e6db74">&#34;データベースクエリの実行に失敗しました: </span><span style="color:#e6db74">{</span>str(e)<span style="color:#e6db74">}</span><span style="color:#e6db74">&#34;</span>
</span></span><span style="display:flex;"><span>        })
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#75715e"># ...</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#75715e"># ツール実行結果をClaudeに返す部分</span>
</span></span><span style="display:flex;"><span>tool_result <span style="color:#f92672">=</span> query_database(sql_query<span style="color:#f92672">=</span>tool_input[<span style="color:#e6db74">&#34;sql_query&#34;</span>])
</span></span><span style="display:flex;"><span>conversation_history<span style="color:#f92672">.</span>append({
</span></span><span style="display:flex;"><span>    <span style="color:#e6db74">&#34;role&#34;</span>: <span style="color:#e6db74">&#34;user&#34;</span>,
</span></span><span style="display:flex;"><span>    <span style="color:#e6db74">&#34;content&#34;</span>: [{
</span></span><span style="display:flex;"><span>        <span style="color:#e6db74">&#34;type&#34;</span>: <span style="color:#e6db74">&#34;tool_result&#34;</span>,
</span></span><span style="display:flex;"><span>        <span style="color:#e6db74">&#34;tool_use_id&#34;</span>: tool_use_id,
</span></span><span style="display:flex;"><span>        <span style="color:#e6db74">&#34;content&#34;</span>: tool_result, <span style="color:#75715e"># エラー情報が含まれたJSONをそのまま渡す</span>
</span></span><span style="display:flex;"><span>        <span style="color:#e6db74">&#34;is_error&#34;</span>: <span style="color:#e6db74">&#34;error&#34;</span> <span style="color:#f92672">in</span> json<span style="color:#f92672">.</span>loads(tool_result) <span style="color:#75715e"># (Optional) エラーであることを明示</span>
</span></span><span style="display:flex;"><span>    }]
</span></span><span style="display:flex;"><span>})
</span></span></code></pre></td></tr></table>
</div>
</div><p>こうすることで、Claudeは「データベースクエリの実行に失敗しました。SQLの構文が間違っている可能性があります。クエリを確認してください: <code>SELECT * FRM sales</code>」のように、具体的なフィードバックを返すことができます。</p>
<h3 id="3-複数のツールを組み合わせる思考の連鎖">3. 複数のツールを組み合わせる（思考の連鎖）</h3>
<p>より複雑なタスクでは、複数のツールを段階的に実行する必要があります。</p>
<p><strong>例: 「先月の売上トップだった商品の担当営業に、Slackでお祝いメッセージを送って」</strong></p>
<p>このタスクを達成するには、おそらく2つのツールが必要です。</p>
<ol>
<li><code>get_top_sales_product(month: str)</code>: 指定した月の売上トップ商品と担当者を取得するツール。</li>
<li><code>send_slack_message(user_id: str, message: str)</code>: 指定したユーザーにSlackメッセージを送信するツール。</li>
</ol>
<p>このようなシナリオでは、Claudeは自律的に思考の連鎖（Chain of Thought）を行い、ツールを順番に呼び出します。</p>
<ol>
<li>ユーザーの指示を解釈し、まず<code>get_top_sales_product</code>を呼び出す必要があると判断する。</li>
<li>開発者側でこのツールを実行し、結果（<code>{&quot;product&quot;: &quot;商品A&quot;, &quot;sales_person_id&quot;: &quot;U12345&quot;}</code>）を返す。</li>
<li>Claudeは結果を受け取り、次に<code>send_slack_message</code>を、引数 <code>user_id='U12345'</code>, <code>message='...お祝いメッセージ...'</code> で呼び出す必要があると判断する。</li>
<li>開発者側でSlack送信ツールを実行し、成功した旨を返す。</li>
<li>Claudeはすべてのステップが完了したことを確認し、「先月の売上トップ商品Aの担当者である山田さんに、お祝いのSlackメッセージを送信しました。」と最終報告を行う。</li>
</ol>
<p>このように、複数のツールを適切に設計・定義することで、Claudeをより高度な自律エージェントとして機能させることができます。</p>
<h2 id="まとめ">まとめ</h2>
<p>本記事では、Claudeの「Tool Use」機能を用いて、Claudeに独自の「スキル」を追加し、あなた専用の最強アシスタントへと進化させる方法を解説しました。</p>
<p>Tool Useは、単なる機能追加ではありません。それは、<strong>LLMという強力な「脳」に、あなたの世界のツールやシステムという「手足」を与える</strong>ことに他なりません。これまで分断されていたLLMの対話能力と、既存のソフトウェア資産を繋ぐ、きわめて重要な架け橋です。</p>
<p>今回紹介した基本的なフローと実践的なTipsを参考に、まずは身近なタスクを自動化する簡単なツールから試してみてください。天気予報の取得、簡単な計算、テキストファイルの読み書きなど、小さな成功体験を積み重ねることで、Tool Useの持つ無限の可能性を実感できるはずです。</p>
<p>LLMをワークフローに統合する動きは、今後ますます加速していくでしょう。Tool Useを使いこなし、Claudeを真の「相棒」として活用できるかどうかは、これからの開発者にとって大きなアドバンテージとなります。ぜひ、あなただけの「最強のClaude」を育て上げてみてください。</p>
]]></content:encoded>
      <category>Coding AI</category>
      <category>Claude Code</category>
      <category>MCP</category>
      <category>Customization</category>
    </item>
  </channel>
</rss>
