[Scrap] GitHub Copilot Chat が OSS 化されたので手元で触ってみる

GitHub Copilot Chat が OSS 化されたので、手元で触ってみる

- git clone して npm i を実行
- launch.json から起動
- しようとしたが、エラー
Failed loading extension '/Users/heavenosk/src/github.com/microsoft/vscode-copilot-chat' under development because it is invalid: Extension is not compatible with Code 1.102.0. Extension requires: ^1.103.0-insider.
どうやら VSCode のバージョンの不一致によって動かないらしい。
- 雑に requirement バージョンを変更して起動してみる
- 必要なモジュールが見つからないらしくエラー
Activating extension 'GitHub.copilot-chat' failed: Cannot find module '/Users/heavenosk/src/github.com/microsoft/vscode-copilot-chat/dist/extension' Require stack: - /Applications/Visual Studio Code.app/Contents/Resources/app/out/vs/workbench/api/node/extensionHostProcess.js.
- 一回休み。
- とりあえず VSCode Insider を入れてみる
- VSCode Insider を入れたら起動できた ✅
- 適当に文言を変えて反映されていることを確認

- 概要を知るために Claude Code に調査と記事化を依頼して、風呂に入る

emoji: "🔍"
type: "tech"
topics: ["vscode", "copilot", "typescript", "ai", "extension"]
published: false
title: "VSCode Copilot Chat Extension の内部構造を徹底解剖"はじめに
VSCode Copilot Chat は、GitHub Copilot の AI 機能を VSCode に統合する公式拡張機能です。本記事では、microsoft/vscode-copilot-chat リポジトリの内部構造を詳しく分析し、その設計思想と実装の詳細について解説します。
プロジェクト構造の概要
VSCode Copilot Chat は、大きく以下の 3 つの主要ディレクトリで構成されています:
vscode-copilot-chat/
├── src/
│ ├── extension/ # 拡張機能固有の機能
│ ├── platform/ # プラットフォーム共通のコア機能
│ └── util/ # ユーティリティ関数
├── test/ # テストコード
└── dist/ # ビルド成果物
extension ディレクトリ
拡張機能の主要な機能が実装されているディレクトリです:
- api/: 外部に公開される API
- authentication/: 認証機能
- chat/: チャット機能のコア実装
- commands/: VSCode コマンドの定義
- conversation/: 会話の管理
- intents/: ユーザーの意図を解釈する機能
- prompts/: プロンプトテンプレートと生成
- tools/: AI が使用可能なツール群
platform ディレクトリ
プラットフォーム共通のコア機能が含まれています:
- chat/: チャット関連の共通処理
- configuration/: 設定管理
- endpoint/: API エンドポイント管理
- log/: ロギング機能
- telemetry/: テレメトリ収集
- workspace/: ワークスペース管理
主要なモジュールと機能
1. プロンプトシステム
VSCode Copilot Chat の最も特徴的な部分は、TSX を使用したプロンプト管理システムです。@vscode/prompt-tsx
パッケージを使用して、プロンプトをコンポーネントとして管理しています。
システムプロンプトの例
// AgentPrompt の基本構造
<SystemMessage>
You are an expert AI programming assistant, working with a user in the VS Code editor.<br />
<CopilotIdentityRules />
<SafetyRules />
</SystemMessage>
主要なプロンプトコンポーネント
- DefaultAgentPrompt: エージェントモードの基本プロンプト
- InlineChatEditCodePrompt: インラインチャットでのコード編集プロンプト
- SweBenchAgentPrompt: SWE-bench 評価用の特別なプロンプト
2. ツールシステム
AI が使用可能な 50 種類以上のツールが定義されています:
export const enum ToolName {
ApplyPatch = 'apply_patch',
Codebase = 'semantic_search',
VSCodeAPI = 'get_vscode_api',
RunTests = 'run_tests',
FindFiles = 'file_search',
ReadFile = 'read_file',
RunInTerminal = 'run_in_terminal',
EditFile = 'insert_edit_into_file',
ReplaceString = 'replace_string_in_file',
// ... 他多数
}
各ツールは以下の特徴を持ちます:
- 内部名 (ToolName) と 公開名 (ContributedToolName) の 2 つの名前体系
- JSON スキーマによる入力パラメータの定義
- モデル向けの説明文と人間向けの説明文
3. インテント(意図)システム
ユーザーの要求を適切なハンドラーにルーティングする仕組み:
export const enum Intent {
Agent = 'agent',
EditCode = 'editCode',
Fix = 'fix',
Generate = 'generate',
// ...
}
各インテントは専用のハンドラークラスを持ち、特定のタスクに最適化されたプロンプトとロジックを提供します。
4. 会話管理
会話は Conversation
と Turn
クラスで管理されます:
- Conversation: セッション全体を管理
- Turn: 個々のやり取りを表現
- ChatVariablesCollection: 変数(ファイル参照など)の管理
5. エンドポイント管理
複数の AI モデルをサポートするための抽象化層:
class ChatEndpoint implements IChatEndpoint {
public readonly model: string;
public readonly family: string;
public readonly tokenizer: TokenizerType;
// ...
}
特徴的な実装パターン
1. Dependency Injection
VSCode の InstantiationService を使用した DI パターン:
constructor(
@ILogService private readonly logService: ILogService,
@IConfigurationService private readonly configService: IConfigurationService,
// ...
) {}
2. ストリーミング対応
リアルタイムな応答を実現するためのストリーミング処理:
const processor = await SSEProcessor.create(logService, telemetryService, ...);
const chatCompletions = AsyncIterableObject.map(finishedCompletions, ...);
3. プロンプトの動的生成
ユーザーのコンテキストに応じてプロンプトを動的に生成:
<UserMessage>
<CustomInstructions priority={725} chatVariables={chatVariables} />
<LanguageServerContextPrompt priority={700} document={document} />
<TemporalContext priority={600} context={[document]} />
</UserMessage>
セキュリティとプライバシー
- SafetyRules: 有害なコンテンツの生成を防ぐルール
- テレメトリ: オプトイン/アウト可能な使用状況収集
- 認証: GitHub アカウントによる認証
まとめ
VSCode Copilot Chat は、高度に構造化されたアーキテクチャを持つ拡張機能です。TSX ベースのプロンプト管理、豊富なツールセット、柔軟なインテントシステムなど、AI アシスタントとしての機能を実現するための工夫が随所に見られます。
この設計は、将来の機能拡張や他の AI モデルへの対応を容易にし、開発者にとって使いやすい AI アシスタントを実現するための基盤となっています。
参考リンク

emoji: "🛠️"
type: "tech"
topics: ["vscode", "copilot", "tools", "ai", "function-calling"]
published: false
title: "VSCode Copilot Chat のツールシステム - AI が使える 50 種類以上のツールの仕組み"はじめに
VSCode Copilot Chat では、AI が VSCode の様々な機能にアクセスできる「ツール」システムが実装されています。これにより、単なるコード生成を超えて、ファイルの読み書き、ターミナルでのコマンド実行、テストの実行など、開発者が行う作業の多くを AI が代行できるようになっています。
本記事では、このツールシステムの仕組みと実装について詳しく解説します。
ツールシステムの概要
VSCode Copilot Chat には 50 種類以上のツールが定義されており、AI はこれらを組み合わせて複雑なタスクを実行できます。
ツールの分類
1. ファイル操作系ツール
export const enum ToolName {
ReadFile = 'read_file', // ファイル読み取り
EditFile = 'insert_edit_into_file', // ファイル編集
CreateFile = 'create_file', // ファイル作成
ReplaceString = 'replace_string_in_file', // 文字列置換
ListDirectory = 'list_dir', // ディレクトリ一覧
CreateDirectory = 'create_directory', // ディレクトリ作成
}
2. 検索系ツール
export const enum ToolName {
Codebase = 'semantic_search', // セマンティック検索
FindFiles = 'file_search', // ファイル名検索
FindTextInFiles = 'grep_search', // テキスト検索
SearchWorkspaceSymbols = 'search_workspace_symbols', // シンボル検索
Usages = 'list_code_usages', // 使用箇所検索
}
3. 実行系ツール
export const enum ToolName {
RunInTerminal = 'run_in_terminal', // ターミナルでコマンド実行
RunTests = 'run_tests', // テスト実行
RunTask = 'run_vs_code_task', // VSCode タスク実行
RunNotebookCell = 'run_notebook_cell', // Notebook セル実行
}
4. 情報取得系ツール
export const enum ToolName {
GetErrors = 'get_errors', // エラー情報取得
GetTerminalOutput = 'get_terminal_output', // ターミナル出力取得
GetScmChanges = 'get_changed_files', // Git 変更ファイル取得
VSCodeAPI = 'get_vscode_api', // VSCode API ドキュメント取得
}
ツールの命名体系
興味深いことに、各ツールには 2 つの名前があります:
// 内部名(モデルが使用)
ToolName.ReadFile = 'read_file'
// 公開名(VSCode に登録)
ContributedToolName.ReadFile = 'copilot_readFile'
これらは相互に変換できます:
export function getContributedToolName(name: string | ToolName): string | ContributedToolName {
return toolNameToContributedToolNames.get(name as ToolName) ?? name;
}
export function getToolName(name: string | ContributedToolName): string | ToolName {
return contributedToolNameToToolNames.get(name as ContributedToolName) ?? name;
}
ツールの定義方法
package.json でツールを定義する例:
{
"languageModelTools": [
{
"name": "copilot_searchCodebase",
"toolReferenceName": "codebase",
"displayName": "%copilot.tools.searchCodebase.name%",
"icon": "$(folder)",
"canBeReferencedInPrompt": true,
"userDescription": "%copilot.codebase.tool.description%",
"modelDescription": "Run a natural language search for relevant code...",
"tags": ["codesearch", "vscode_codesearch"],
"inputSchema": {
"type": "object",
"properties": {
"query": {
"type": "string",
"description": "The query to search the codebase for..."
}
},
"required": ["query"]
}
}
]
}
主要な設定項目:
- name: ツールの識別名
- toolReferenceName: ユーザーがチャットで参照する際の名前
- canBeReferencedInPrompt: ユーザーが直接参照できるか
- modelDescription: AI モデル向けの説明
- userDescription: ユーザー向けの説明
- inputSchema: パラメータの JSON スキーマ
ツールの動的な有効化
AI が使用できるツールは、コンテキストに応じて動的に決定されます:
const getTools = (instaService: IInstantiationService, request: vscode.ChatRequest) =>
instaService.invokeFunction(async accessor => {
const allowTools: Record<string, boolean> = {};
// モデルの能力に応じてツールを有効化
const useApplyPatch = !!(modelSupportsApplyPatch(model) && applyPatchConfigEnabled);
allowTools[ToolName.EditFile] = true;
allowTools[ToolName.ReplaceString] = modelSupportsReplaceString(model);
allowTools[ToolName.ApplyPatch] = useApplyPatch;
// テストがある場合のみテスト実行ツールを有効化
allowTools[ToolName.RunTests] = await testService.hasAnyTests();
// タスクがある場合のみタスク実行ツールを有効化
allowTools[ToolName.RunTask] = !!(configurationService.getConfig(ConfigKey.AgentCanRunTasks)
&& tasksService.getTasks().length);
return toolsService.getEnabledTools(request, tool => {
if (typeof allowTools[tool.name] === 'boolean') {
return allowTools[tool.name];
}
return undefined;
});
});
ツール使用に関するプロンプト
AI に対してツールの使い方を指示するプロンプトの例:
<Tag name='toolUseInstructions'>
If the user is requesting a code sample, you can answer it directly without using any tools.<br />
When using a tool, follow the JSON schema very carefully and make sure to include ALL required properties.<br />
No need to ask permission before using a tool.<br />
NEVER say the name of a tool to a user. For example, instead of saying that you'll use the {ToolName.RunInTerminal} tool, say "I'll run the command in a terminal".<br />
{hasReadFileTool && <>
When using the {ToolName.ReadFile} tool, prefer reading a large section over calling the {ToolName.ReadFile} tool many times in sequence.<br />
</>}
{hasTerminalTool && <>
Don't call the {ToolName.RunInTerminal} tool multiple times in parallel. Instead, run one command and wait for the output before running the next command.<br />
</>}
</Tag>
特殊なツールの例
1. Think ツール(思考ツール)
AI が思考プロセスを記録するための特殊なツール:
{
"displayName": "%copilot.tools.think.name%",
"name": "copilot_think",
"modelDescription": `Use this tool to think deeply about the user's request and organize your thoughts.
This tool helps improve response quality by allowing the model to consider the request carefully,
brainstorm solutions, and plan complex tasks...`,
"inputSchema": {
"type": "object",
"properties": {
"thoughts": {
"type": "string",
"description": "Your thoughts about the current task or problem..."
}
}
}
}
2. UpdateUserPreferences ツール
ユーザーの好みを記録するツール:
{hasUpdateUserPreferencesTool && <>
After you have performed the user's task, if the user corrected something you did,
expressed a coding preference, or communicated a fact that you need to remember,
use the {ToolName.UpdateUserPreferences} tool to save their preferences.<br />
</>}
3. 事前実行ツール
コードを変更するツールは、次のリクエスト前に実行される必要があります:
export const prerunTools: ReadonlySet<ToolName> = new Set([
ToolName.EditFile
]);
ツール呼び出しループ
AI は複数のツールを連続して呼び出せます:
protected override getIntentHandlerOptions(request: vscode.ChatRequest): IDefaultIntentRequestHandlerOptions | undefined {
return {
maxToolCallIterations: getRequestedToolCallIterationLimit(request) ??
this.configurationService.getNonExtensionConfig('chat.agent.maxRequests') ??
200, // 最大 200 回のツール呼び出し
temperature: this.configurationService.getConfig(ConfigKey.Internal.AgentTemperature) ?? 0,
overrideRequestLocation: ChatLocation.Agent,
hideRateLimitTimeEstimate: true
};
}
モデル固有の制限
異なる AI モデルには異なるツール制限があります:
// Claude では replace_string を優先的に使用
if (modelMightUseReplaceStringExclusively(model) &&
experimentationService.getTreatmentVariable<boolean>('vscode', 'copilotchat.claudeReplaceStringExclusively')) {
allowTools[ToolName.ReplaceString] = true;
allowTools[ToolName.EditFile] = false;
}
// Gemini では特別な設定
allowTools[ToolName.ReplaceString] = modelSupportsReplaceString(model) ||
!!(model.family.includes('gemini') &&
experimentationService.getTreatmentVariable<boolean>('vscode', 'copilotchat.geminiReplaceString'));
ツールの応答サイズ制限
ツールの応答が大きすぎる場合の制限:
/** Proportion of the prompt token budget any singular textual tool result is allowed to use. */
const MAX_TOOL_RESPONSE_PCT = 0.5;
const maxToolResultLength = Math.floor(
this.promptEndpoint.modelMaxPromptTokens * MAX_TOOL_RESPONSE_PCT
);
まとめ
VSCode Copilot Chat のツールシステムは:
- 豊富なツールセット: 50 種類以上の多様なツール
- 動的な有効化: コンテキストに応じた適切なツール選択
- モデル最適化: AI モデルの特性に合わせたツール設定
- 安全性: 明示的な許可設定による安全な実行
- 拡張性: 新しいツールを簡単に追加可能
このシステムにより、AI は単なるコード生成を超えて、実際の開発作業を幅広くサポートできるようになっています。ツールの組み合わせによって、複雑なタスクも自動化できる可能性を秘めています。
参考リンク

emoji: "🎯"
type: "tech"
topics: ["vscode", "copilot", "prompt", "typescript", "tsx"]
published: false
title: "VSCode Copilot Chat のプロンプトシステム深掘り - TSX でプロンプトを管理する設計"はじめに
前回の記事では VSCode Copilot Chat の全体的な構造を解説しました。今回は、この拡張機能の中でも特に興味深い「プロンプトシステム」について深掘りしていきます。
VSCode Copilot Chat では、AI への指示(プロンプト)を TSX コンポーネントとして管理するという独特なアプローチを採用しています。これにより、プロンプトの再利用性、保守性、型安全性が大幅に向上しています。
@vscode/prompt-tsx とは
VSCode Copilot Chat は @vscode/prompt-tsx
というパッケージを使用してプロンプトを管理しています。これは React の JSX に似た構文でプロンプトを記述できるフレームワークです。
import { PromptElement, SystemMessage, UserMessage } from '@vscode/prompt-tsx';
class MyPrompt extends PromptElement {
render() {
return <>
<SystemMessage>
You are an AI assistant.
</SystemMessage>
<UserMessage>
Help me with coding.
</UserMessage>
</>;
}
}
主要なプロンプトコンポーネント
1. エージェントモードのプロンプト
DefaultAgentPrompt
エージェントモードで使用される基本的なプロンプトです:
export class DefaultAgentPrompt extends PromptElement<DefaultAgentPromptProps> {
async render(state: void, sizing: PromptSizing) {
return <InstructionMessage>
<Tag name='instructions'>
You are a highly sophisticated automated coding agent with expert-level knowledge across many different programming languages and frameworks.<br />
The user will ask a question, or ask you to perform a task, and it may require lots of research to answer correctly. There is a selection of tools that let you perform actions or retrieve helpful context to answer the user's question.<br />
{getKeepGoingReminder(this.props.modelFamily)}
// ... 続く
</Tag>
</InstructionMessage>;
}
}
動的なツール指示
利用可能なツールに応じて、動的に指示を生成します:
{hasTerminalTool && <>
NEVER print out a codeblock with a terminal command to run unless the user asked for it.
Use the {ToolName.RunInTerminal} tool instead.<br />
</>}
{!hasSomeEditTool && <>
You don't currently have any tools available for editing files.
If the user asks you to edit a file, you can ask the user to enable editing tools or print a codeblock with the suggested changes.<br />
</>}
2. インラインチャットのプロンプト
InlineChatEditCodePrompt
コードエディタ内でのインライン編集用プロンプト:
export class InlineChatEditCodePrompt extends PromptElement<InlineChatEditCodePromptProps> {
async render(state: void, sizing: PromptSizing) {
return (
<>
<SystemMessage priority={1000}>
You are an AI programming assistant.<br />
When asked for your name, you must respond with "GitHub Copilot".<br />
You are a world class expert in programming, and especially good at {languageId}.<br />
<LegacySafetyRules />
</SystemMessage>
<HistoryWithInstructions inline={true} historyPriority={700} passPriority history={history}>
<InstructionMessage priority={1000}>
Source code is always contained in ``` blocks.<br />
The user needs help to modify some code.<br />
{data.hasCodeWithoutSelection && <>
The user includes existing code and marks with {data.placeholderText} where the selected code should go.<br />
</>}
</InstructionMessage>
</HistoryWithInstructions>
// ... 続く
</>
);
}
}
3. 特殊用途のプロンプト
Xtab プロンプト(次の編集予測)
開発者の次の編集を予測するための特殊なプロンプト:
export const systemPromptTemplate = `Your role as an AI assistant is to help developers complete their code tasks by assisting in editing specific sections of code marked by the ${CODE_TO_EDIT_START_TAG} and ${CODE_TO_EDIT_END_TAG} tags, while adhering to Microsoft's content policies and avoiding the creation of content that violates copyrights.
You have access to the following information to help you make informed suggestions:
- recently_viewed_code_snippets: These are code snippets that the developer has recently looked at...
- current_file_content: The content of the file the developer is currently working on...
- edit_diff_history: A record of changes made to the code...
- area_around_code_to_edit: The context showing the code surrounding the section to be edited.
- cursor position marked as ${CURSOR_TAG}: Indicates where the developer's cursor is currently located...
`;
要約プロンプト
会話を要約するための専用プロンプト:
class SummaryPrompt {
render() {
return {
messages: [{
role: 'system' as const,
content: `You are an expert at summarizing chat conversations.
Structure your summary using the following format:
TITLE: A brief title for the summary
USER INTENT: The user's goal or intent for the conversation
TASK DESCRIPTION: Main technical goals and user requirements
EXISTING: What has already been accomplished. Include file paths and other direct references.
PENDING: What still needs to be done. Include file paths and other direct references.
CODE STATE: A list of all files discussed or modified. Provide code snippets or diffs that illustrate important context.
RELEVANT CODE/DOCUMENTATION SNIPPETS: Key code or documentation snippets from referenced files or discussions.
OTHER NOTES: Any additional context or information that may be relevant.`
}]
};
}
}
プロンプトの優先度システム
VSCode Copilot Chat では、プロンプトパーツに優先度を設定できます:
<UserMessage priority={900} flexGrow={2} flexReserve={sizing.endpoint.modelMaxPromptTokens / 3}>
<SummarizedDocumentWithSelection
flexGrow={1}
tokenBudget={'usePromptSizingBudget'}
documentData={data}
/>
<Tag name='userPrompt'>
<UserQuery chatVariables={chatVariables} query={query} /><br />
</Tag>
</UserMessage>
- priority: レンダリング順序を制御
- flexGrow: トークン予算の配分比率
- flexReserve: 最低限確保するトークン数
動的なコンテキスト注入
プロンプトには動的にコンテキストを注入できます:
<CustomInstructions priority={725} chatVariables={chatVariables} languageId={languageId} />
<LanguageServerContextPrompt priority={700} document={document} position={context.selection.start} />
<TemporalContext priority={600} context={[document]} location={ChatLocation.Editor} />
これらのコンポーネントは:
- CustomInstructions: ユーザー定義のカスタム指示
- LanguageServerContextPrompt: 言語サーバーからの型情報やシンボル情報
- TemporalContext: 最近の編集履歴
セーフティルール
全てのプロンプトには安全性を確保するためのルールが含まれています:
export class SafetyRules extends PromptElement {
render() {
return <>
Follow Microsoft content policies.<br />
Avoid content that violates copyrights.<br />
Keep your answers short and relevant to the user's query.<br />
{/* ... その他のルール */}
</>;
}
}
プロンプトのキャッシュ戦略
長い会話でのパフォーマンスを向上させるため、キャッシュブレークポイントが使用されています:
{this.props.enableCacheBreakpoints && <cacheBreakpoint type={CacheType} />}
これにより、会話の特定の部分をキャッシュし、再利用できます。
実装のベストプラクティス
1. コンポーネントの分離
各プロンプトコンポーネントは単一責任の原則に従っています:
// 良い例:特定の目的に特化したコンポーネント
class NotebookInstructions extends PromptElement { /* ... */ }
class TerminalInstructions extends PromptElement { /* ... */ }
// 悪い例:全てを1つのコンポーネントに詰め込む
class AllInstructions extends PromptElement { /* ... */ }
2. プロパティによる柔軟性
プロンプトはプロパティを通じて動的に振る舞いを変更できます:
interface AgentPromptProps {
readonly endpoint: IChatEndpoint;
readonly location: ChatLocation;
readonly triggerSummarize?: boolean;
readonly enableCacheBreakpoints?: boolean;
readonly codesearchMode?: boolean;
}
3. 型安全性
TypeScript の型システムを最大限活用:
const hasTerminalTool = !!this.props.availableTools?.find(
tool => tool.name === ToolName.RunInTerminal
);
まとめ
VSCode Copilot Chat のプロンプトシステムは、以下の特徴を持つ革新的な設計です:
- TSX による宣言的な記述: プロンプトを UI コンポーネントのように扱える
- 再利用性: 共通部分をコンポーネント化して再利用
- 型安全性: TypeScript による静的型チェック
- 動的な生成: コンテキストに応じた柔軟なプロンプト生成
- 優先度管理: トークン予算の効率的な配分
この設計により、複雑な AI アシスタントのプロンプト管理が大幅に簡素化され、保守性が向上しています。他の AI アプリケーション開発においても、参考になる設計パターンといえるでしょう。