JavaScriptを有効にしてください

GitHub Copilot Chat のエージェントを更新し隊

 ·   23 分で読めます  ·   Kento

昨年に GitHub Copilot Extension をリリースしました
GitHub Copilot Extensions (Chat Extention?) を自作し隊 – クラウドを勉強し隊

1年近くたって、改善点がたまったので更新してみました

想定される読者

  • GitHub Copilot Extension を作ってみたい方
  • GitHub Copilot Chat を使ってみたい方
  • GitHub Copilot Chat のエージェントを作ってみたい方

GitHub Copilot のエージェントについて

執筆時点で GitHub Copilot でエージェントというと2種類あります
それぞれの違いを整理します

エージェントの種類 説明
GitHub Copilot Chat の参加者 GitHub Copilot Chat の Ask モードで @vscode みたいに使う。チャットの参加者として専門性をもって返事をしてくれる。アドバイザー的なイメージ
GitHub Copilot の Agent モード GitHub Copilot が自律的に行動を起こしてくれる。代わりに手を動かしてくれるイメージ

今回は前者の GitHub Copilot Chat の参加者を更新します

改善したい点

  • プロンプトを見直す
  • チャット履歴を参照できる
  • コンテキスト(開いてるファイルや選択中のテキストなど)を参照できる

ざっくり手順

たぶん1年前にはなかったチュートリアルページを見ながら修正していきます
Tutorial: Build a code tutorial chat participant with the Chat API | Visual Studio Code Extension API

  1. チュートリアルに沿って作成しなおし
  2. プロンプトを見直し
  3. チャット履歴を参照できるようにする
  4. コンテキストを参照できるようにする
  5. 動作確認

1. チュートリアルに沿って作成しなおし

昨年初めて作成したときはよくわからないままコピペしながら作成したので今回はチュートリアルに沿って1から作成しなおしました
途中のチャット参加者名や ID、プロンプトは自分用に修正しています
※最後に完成形のコードを載せているので途中経過として参考にしてください

まだまだ進化は残しています

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
// The module 'vscode' contains the VS Code extensibility API
// Import the module and reference it with the alias vscode in your code below
import * as vscode from 'vscode';

const BASE_PROMPT =
	'GitHub Copilot Agent は、Microsoft Azure のアーキテクチャ構成図を Mermaid 言語で作成するために動作し、ユーザーが指定したサービスやコンポーネントを理解しやすく整理された図として出力できるように支援します。Mermaid の構文に基づき、`graph TD` 形式を使用してサービス間の関係を視覚的に整理し、`subgraph` を活用してリソースグループやネットワークの階層構造を表現します。Azure の主要コンポーネントとして、コンピュート(VM, Azure Functions, App Services)、ストレージ(Blob Storage, SQL Database, Cosmos DB)、ネットワーク(VNet, Load Balancer, Firewall)、アイデンティティ(Azure AD, Managed Identities)、その他(Logic Apps, API Management, Key Vault)をサポートします。ユーザーの要件に適応し、具体的なサービス構成が指定された場合は適切なノードとリンクを作成し、関係性が不明な場合は一般的な接続パターンを提供し、`style` を使用して異なるサービスの視覚的な強調を行います。コードの可読性を重視し、コメントを付与して図の目的や各ノードの役割を説明し、インデントや改行を適切に使い明瞭なコード構造を実現します。これらの指示を含めることで、GitHub Copilot Agent がユーザーの意図に沿った Mermaid 形式の Azure 構成図を生成できるようになります。';

// This method is called when your extension is activated
// Your extension is activated the very first time the command is executed
export function activate(context: vscode.ExtensionContext) {
	// define a chat handler
	const handler: vscode.ChatRequestHandler = async (
		request: vscode.ChatRequest,
		context: vscode.ChatContext,
		stream: vscode.ChatResponseStream,
		token: vscode.CancellationToken
	) => {
		// initialize the prompt
		let prompt = BASE_PROMPT;

		// initialize the messages array with the prompt
		const messages = [vscode.LanguageModelChatMessage.User(prompt)];

		// get all the previous participant messages
		const previousMessages = context.history.filter(
			h => h instanceof vscode.ChatResponseTurn
		);

		// add in the user's message
		messages.push(vscode.LanguageModelChatMessage.User(request.prompt));

		// send the request
		const chatResponse = await request.model.sendRequest(messages, {}, token);

		// stream the response
		for await (const fragment of chatResponse.text) {
			stream.markdown(fragment);
		}

		return;
	};

	// create participant
	const mermaid = vscode.chat.createChatParticipant('mermaid-azure2', handler);

	// add icon to participant
	mermaid.iconPath = vscode.Uri.joinPath(context.extensionUri, 'azure_mermaid.jpg');
}

// This method is called when your extension is deactivated
export function deactivate() { }

2. プロンプトを見直し

Base Prompt はすでに記載していますが、プロンプトの見直しをしました
またこのタイミングでコマンドも追加し、コマンドごとのプロンプトも見直しました

コマンド名 目的
flowchart 構成図を Mermaid の Flowchart で作成する
architecture 構成図を Mermaid の Architecture で作成する
architecture-azureicon 構成図を Mermaid の Architecture で作成する(アイコン付き)

この1年で Mermaid に更新がかかり、Architecture 機能が追加されました
flowchart と Architecture を使い分けるためのコマンドです
また、Architecture ではアイコンを使うことができるようになったので、アイコン付きのコマンドも追加しました

この時点での修正版はこちら

まだ進化を残してます

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
// The module 'vscode' contains the VS Code extensibility API
// Import the module and reference it with the alias vscode in your code below
import * as vscode from 'vscode';

const BASE_PROMPT =
	'GitHub Copilot Agent は、Microsoft Azure のアーキテクチャ構成図を Mermaid 言語で作成するために動作し、ユーザーが指定したサービスやコンポーネントを理解しやすく整理された図として出力できるように支援します。Mermaid の構文に基づき、`graph TD` 形式を使用してサービス間の関係を視覚的に整理し、`subgraph` を活用してリソースグループやネットワークの階層構造を表現します。Azure の主要コンポーネントとして、コンピュート(VM, Azure Functions, App Services)、ストレージ(Blob Storage, SQL Database, Cosmos DB)、ネットワーク(VNet, Load Balancer, Firewall)、アイデンティティ(Azure AD, Managed Identities)、その他(Logic Apps, API Management, Key Vault)をサポートします。ユーザーの要件に適応し、具体的なサービス構成が指定された場合は適切なノードとリンクを作成し、関係性が不明な場合は一般的な接続パターンを提供し、`style` を使用して異なるサービスの視覚的な強調を行います。コードの可読性を重視し、コメントを付与して図の目的や各ノードの役割を説明し、インデントや改行を適切に使い明瞭なコード構造を実現します。これらの指示を含めることで、GitHub Copilot Agent がユーザーの意図に沿った Mermaid 形式の Azure 構成図を生成できるようになります。';

const Flowchart_PROMPT =
	'GitHub Copilot Agent は、Microsoft Azure のアーキテクチャ構成図を Mermaid 言語で作成するために動作し、ユーザーが指定したサービスやコンポーネントを理解しやすく整理された図として出力できるように支援します。Mermaid の構文に基づき、`graph TD` 形式を使用してサービス間の関係を視覚的に整理し、`subgraph` を活用してリソースグループやネットワークの階層構造を表現します。Azure の主要コンポーネントとして、コンピュート(VM, Azure Functions, App Services)、ストレージ(Blob Storage, SQL Database, Cosmos DB)、ネットワーク(VNet, Load Balancer, Firewall, vWAN)、アイデンティティ(Azure AD, Managed Identities)、その他(Logic Apps, API Management, Key Vault)をサポートします。ユーザーの要件に適応し、具体的なサービス構成が指定された場合は適切なノードとリンクを作成し、関係性が不明な場合は一般的な接続パターンを提供し、`style` を使用して異なるサービスの視覚的な強調を行います。ネットワーク系(VNet, Load Balancer, Firewall, vWAN)は緑色、PaaS 系(Azure Functions, App Services, Logic Apps)はオレンジ色、データベース系(Blob Storage, SQL Database, Cosmos DB)は青色、セキュリティ関連(Azure AD, Managed Identities, Key Vault)は赤色とし、その他のコンポーネントには適切な色を設定します。さらに、仮想ネットワークや vWAN などのネットワークリソースに属するサービスは `subgraph` を活用し、適切なグループ化を行うことで可読性と理解しやすさを向上させます。コードの可読性を重視し、コメントを付与して図の目的や各ノードの役割を説明し、インデントや改行を適切に使い明瞭なコード構造を実現します。これらの指示を含めることで、GitHub Copilot Agent がユーザーの意図に沿った、色分けとネットワークリソースのグループ化が施された Mermaid 形式の Azure 構成図を生成できるようになります。';

const Architecture_PROMPT =
	'あなたは経験豊富なクラウドアーキテクトかつMermaid Architecture記法のエキスパートです。https://mermaid.js.org/syntax/architecture.html のドキュメントとサンプル「architecture-beta group api(cloud)[API] service db(database)[Database] in api service disk1(disk)[Storage] in api service disk2(disk)[Storage] in api service server(server)[Server] in api db:L -- R:server disk1:T -- B:server disk2:T -- B:db」の文法(group: "group {group id}({icon name})[{title}]"、service: "service {service id}({icon name})[{title}]"(in {parent id} は任意)、edge: "{serviceId}:{T|B|L|R} {<}?--{>}? {T|B|L|R}:{serviceId}")を厳守し、group や service のidにハイフン(-)を含めず、出力結果の冒頭に必ず ```architecture-beta を含めたGitHub Markdownのコードブロック形式で、group を仮想ネットワークやサブネット、リソースグループに、service を Azure のリソース(Azure Virtual Machines, Azure App Services, Azure SQL Database, Azure Blob Storage, Azure Functions など)に対応させたAzure構成図のMermaidコードとして出力してください。'

const ArchitectureAzureIcon_PROMPT =
	`あなたは経験豊富なクラウドアーキテクトかつMermaid Architecture記法のエキスパートです。https://mermaid.js.org/syntax/architecture.html のドキュメント、サンプル「architecture-beta group api(azure:resource-groups)[API] service db(azure:sql-database)[Database] in api service disk1(azure:storage-accounts)[Storage] in api service disk2(azure:storage-accounts)[Storage] in api service server(azure:virtual-machine)[Server] in api db:L -- R:server disk1:T -- B:server disk2:T -- B:db」および文法(group: "group {group id}({icon name})[{title}]"、service: "service {service id}({icon name})[{title}]" (in {parent id}は任意)、edge: "{serviceId}:{T|B|L|R} {<}?--{>}? {T|B|L|R}:{serviceId}")を厳守し、group や service の id にはハイフン(-)を含めず、さらにオリジナルアイコンとして npm パッケージ「azureiconkento」(https://www.npmjs.com/package/azureiconkento?activeTab=versions)で提供されるアイコン(例: azure:sql-database, azure:storage-accounts, azure:virtual-machine など)を利用するよう指定し、出力結果の冒頭に必ず「architecture-beta」を含めた GitHub Markdown のコードブロック形式で、group を仮想ネットワークやサブネット、リソースグループに、service を Azure Virtual Machines, Azure App Services, Azure SQL Database, Azure Blob Storage, Azure Functions などに対応させた Azure 構成図の Mermaid コードとして出力してください。`

// This method is called when your extension is activated
// Your extension is activated the very first time the command is executed
export function activate(context: vscode.ExtensionContext) {


	// define a chat handler
	const handler: vscode.ChatRequestHandler = async (
		request: vscode.ChatRequest,
		context: vscode.ChatContext,
		stream: vscode.ChatResponseStream,
		token: vscode.CancellationToken
	) => {
		// initialize the prompt
		let prompt = BASE_PROMPT;

		if (request.command === 'flowchart') {
			prompt = Flowchart_PROMPT;
		} else if (request.command === 'architecture') {
			prompt = Architecture_PROMPT;
		} else if (request.command === 'architecture-azureicon') {
			prompt = ArchitectureAzureIcon_PROMPT;
		}

		// initialize the messages array with the prompt
		const messages = [vscode.LanguageModelChatMessage.User(prompt)];

		// get all the previous participant messages
		const previousMessages = context.history.filter(
			h => h instanceof vscode.ChatResponseTurn
		);


		// add in the user's message
		messages.push(vscode.LanguageModelChatMessage.User(request.prompt));

		// send the request
		const chatResponse = await request.model.sendRequest(messages, {}, token);

		// stream the response
		for await (const fragment of chatResponse.text) {
			stream.markdown(fragment);
		}

		return;
	};

	// create participant
	const mermaid = vscode.chat.createChatParticipant('mermaid-azure2', handler);

	// add icon to participant
	mermaid.iconPath = vscode.Uri.joinPath(context.extensionUri, 'azure_mermaid.jpg');
}

// This method is called when your extension is deactivated
export function deactivate() { }

3. チャット履歴を参照できるようにする

過去にリリースしたバージョンの GitHub Copilot Extension では、過去のチャット履歴を参照できませんでした
こんなイメージです

sequenceDiagram
    actor User
	participant Agent
    
    User->>Agent: ハブ&スポークの構成図を書いて
    Agent-->>User: Mermaid での構成図
	Note over Agent,User: graph TD ~~~ハブ スポーク~~~
	User->>Agent: スポークに VM を追加して
	Agent-->>User: Mermaid での構成図
	Note over Agent,User: graph TD ~~~脈絡を無視した構成図~~~

このように、過去のチャット履歴を参照できないため、ユーザーが意図した内容を理解できず、脈絡のない構成図を生成してしまいます
そこで、過去のチャット履歴を参照できるようにしました

チュートリアルにチャット履歴を参照する方法が載っていたのでそのまま丸パクリです

これで終わりだと思うなよ

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
// The module 'vscode' contains the VS Code extensibility API
// Import the module and reference it with the alias vscode in your code below
import * as vscode from 'vscode';

const BASE_PROMPT =
	'GitHub Copilot Agent は、Microsoft Azure のアーキテクチャ構成図を Mermaid 言語で作成するために動作し、ユーザーが指定したサービスやコンポーネントを理解しやすく整理された図として出力できるように支援します。Mermaid の構文に基づき、`graph TD` 形式を使用してサービス間の関係を視覚的に整理し、`subgraph` を活用してリソースグループやネットワークの階層構造を表現します。Azure の主要コンポーネントとして、コンピュート(VM, Azure Functions, App Services)、ストレージ(Blob Storage, SQL Database, Cosmos DB)、ネットワーク(VNet, Load Balancer, Firewall)、アイデンティティ(Azure AD, Managed Identities)、その他(Logic Apps, API Management, Key Vault)をサポートします。ユーザーの要件に適応し、具体的なサービス構成が指定された場合は適切なノードとリンクを作成し、関係性が不明な場合は一般的な接続パターンを提供し、`style` を使用して異なるサービスの視覚的な強調を行います。コードの可読性を重視し、コメントを付与して図の目的や各ノードの役割を説明し、インデントや改行を適切に使い明瞭なコード構造を実現します。これらの指示を含めることで、GitHub Copilot Agent がユーザーの意図に沿った Mermaid 形式の Azure 構成図を生成できるようになります。';

const Flowchart_PROMPT =
	'GitHub Copilot Agent は、Microsoft Azure のアーキテクチャ構成図を Mermaid 言語で作成するために動作し、ユーザーが指定したサービスやコンポーネントを理解しやすく整理された図として出力できるように支援します。Mermaid の構文に基づき、`graph TD` 形式を使用してサービス間の関係を視覚的に整理し、`subgraph` を活用してリソースグループやネットワークの階層構造を表現します。Azure の主要コンポーネントとして、コンピュート(VM, Azure Functions, App Services)、ストレージ(Blob Storage, SQL Database, Cosmos DB)、ネットワーク(VNet, Load Balancer, Firewall, vWAN)、アイデンティティ(Azure AD, Managed Identities)、その他(Logic Apps, API Management, Key Vault)をサポートします。ユーザーの要件に適応し、具体的なサービス構成が指定された場合は適切なノードとリンクを作成し、関係性が不明な場合は一般的な接続パターンを提供し、`style` を使用して異なるサービスの視覚的な強調を行います。ネットワーク系(VNet, Load Balancer, Firewall, vWAN)は緑色、PaaS 系(Azure Functions, App Services, Logic Apps)はオレンジ色、データベース系(Blob Storage, SQL Database, Cosmos DB)は青色、セキュリティ関連(Azure AD, Managed Identities, Key Vault)は赤色とし、その他のコンポーネントには適切な色を設定します。さらに、仮想ネットワークや vWAN などのネットワークリソースに属するサービスは `subgraph` を活用し、適切なグループ化を行うことで可読性と理解しやすさを向上させます。コードの可読性を重視し、コメントを付与して図の目的や各ノードの役割を説明し、インデントや改行を適切に使い明瞭なコード構造を実現します。これらの指示を含めることで、GitHub Copilot Agent がユーザーの意図に沿った、色分けとネットワークリソースのグループ化が施された Mermaid 形式の Azure 構成図を生成できるようになります。';

const Architecture_PROMPT =
	'あなたは経験豊富なクラウドアーキテクトかつMermaid Architecture記法のエキスパートです。https://mermaid.js.org/syntax/architecture.html のドキュメントとサンプル「architecture-beta group api(cloud)[API] service db(database)[Database] in api service disk1(disk)[Storage] in api service disk2(disk)[Storage] in api service server(server)[Server] in api db:L -- R:server disk1:T -- B:server disk2:T -- B:db」の文法(group: "group {group id}({icon name})[{title}]"、service: "service {service id}({icon name})[{title}]"(in {parent id} は任意)、edge: "{serviceId}:{T|B|L|R} {<}?--{>}? {T|B|L|R}:{serviceId}")を厳守し、group や service のidにハイフン(-)を含めず、出力結果の冒頭に必ず ```architecture-beta を含めたGitHub Markdownのコードブロック形式で、group を仮想ネットワークやサブネット、リソースグループに、service を Azure のリソース(Azure Virtual Machines, Azure App Services, Azure SQL Database, Azure Blob Storage, Azure Functions など)に対応させたAzure構成図のMermaidコードとして出力してください。'

const ArchitectureAzureIcon_PROMPT =
	`あなたは経験豊富なクラウドアーキテクトかつMermaid Architecture記法のエキスパートです。https://mermaid.js.org/syntax/architecture.html のドキュメント、サンプル「architecture-beta group api(azure:resource-groups)[API] service db(azure:sql-database)[Database] in api service disk1(azure:storage-accounts)[Storage] in api service disk2(azure:storage-accounts)[Storage] in api service server(azure:virtual-machine)[Server] in api db:L -- R:server disk1:T -- B:server disk2:T -- B:db」および文法(group: "group {group id}({icon name})[{title}]"、service: "service {service id}({icon name})[{title}]" (in {parent id}は任意)、edge: "{serviceId}:{T|B|L|R} {<}?--{>}? {T|B|L|R}:{serviceId}")を厳守し、group や service の id にはハイフン(-)を含めず、さらにオリジナルアイコンとして npm パッケージ「azureiconkento」(https://www.npmjs.com/package/azureiconkento?activeTab=versions)で提供されるアイコン(例: azure:sql-database, azure:storage-accounts, azure:virtual-machine など)を利用するよう指定し、出力結果の冒頭に必ず「architecture-beta」を含めた GitHub Markdown のコードブロック形式で、group を仮想ネットワークやサブネット、リソースグループに、service を Azure Virtual Machines, Azure App Services, Azure SQL Database, Azure Blob Storage, Azure Functions などに対応させた Azure 構成図の Mermaid コードとして出力してください。`

	// This method is called when your extension is activated
// Your extension is activated the very first time the command is executed
export function activate(context: vscode.ExtensionContext) {


	// define a chat handler
	const handler: vscode.ChatRequestHandler = async (
		request: vscode.ChatRequest,
		context: vscode.ChatContext,
		stream: vscode.ChatResponseStream,
		token: vscode.CancellationToken
	) => {
		// initialize the prompt
		let prompt = BASE_PROMPT;

		if (request.command === 'flowchart2') {
			prompt = Flowchart_PROMPT;
		} else if (request.command === 'architecture2') {
			prompt = Architecture_PROMPT;
		} else if (request.command === 'architecture-azureicon') {
			prompt = ArchitectureAzureIcon_PROMPT;
		}

		// initialize the messages array with the prompt
		const messages = [vscode.LanguageModelChatMessage.User(prompt)];


		// get all the previous participant messages
		const previousMessages = context.history.filter(
			h => h instanceof vscode.ChatResponseTurn
		);

		// add the previous messages to the messages array
		previousMessages.forEach(m => {
			let fullMessage = '';
			m.response.forEach(r => {
				const mdPart = r as vscode.ChatResponseMarkdownPart;
				fullMessage += mdPart.value.value;
			});
			messages.push(vscode.LanguageModelChatMessage.Assistant(fullMessage));
		});

		// add in the user's message
		messages.push(vscode.LanguageModelChatMessage.User(request.prompt));

		// send the request
		const chatResponse = await request.model.sendRequest(messages, {}, token);

		// stream the response
		for await (const fragment of chatResponse.text) {
			stream.markdown(fragment);
		}

		return;
	};

	// create participant
	const mermaid = vscode.chat.createChatParticipant('mermaid-azure2', handler);

	// add icon to participant
	mermaid.iconPath = vscode.Uri.joinPath(context.extensionUri, 'azure_mermaid.jpg');
}

// This method is called when your extension is deactivated
export function deactivate() { }

4. コンテキストを参照できるようにする

GitHub Copilot Chat のエージェントは、コンテキストを参照できるようにすることができます
例えば、開いているファイルや選択中のテキストを参照することができます
今までは プロンプトに毎回書いてほしい構成図をお願いする必要がありました

sequenceDiagram
	actor User
	participant Agent
	
	User->>Agent: ハブ&スポークの構成図を書いて。<br/>ハブには FW があって、スポークは 2つあります。<br/>各スポークのそれぞれに VM が~~~
	Agent-->>User: Mermaid での構成図
	Note over Agent,User: graph TD ~~~ハブ スポーク~~~

めちゃくちゃ面倒です。
そこで、これを開いているファイル(Bicep など)を参照して、構成図を生成できるようにしました
この部分はチュートリアルになかったので Copilot と相談しながらテストしてみました
Visual Studio Code 以外でも使う場合にはこの実装方法ではだめだと思いますが、今回は Visual Studio Code での利用のみを想定しているのでこのままいきます

sequenceDiagram
	actor User
	participant Agent
	
	User->>Agent: (コンテキストを指定して)<br/>構成図を書いて
	Agent-->>Agent: ファイルの内容を確認
	Agent-->>User: Mermaid での構成図
	Note over Agent,User: graph TD ~~~ハブ スポーク~~~

これで最後だ

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
// The module 'vscode' contains the VS Code extensibility API
// Import the module and reference it with the alias vscode in your code below
import * as vscode from 'vscode';

import * as path from 'path';               // 追加
/** アクティブなファイルの内容を取得して返す */
function getCurrentFileContext():
    | { fileName: string; content: string }
    | null {
    const editor = vscode.window.activeTextEditor;
    if (editor) {
        const doc = editor.document;
        return { fileName: doc.fileName, content: doc.getText() };
    }
    return null;
}

const BASE_PROMPT =
	'GitHub Copilot Agent は、Microsoft Azure のアーキテクチャ構成図を Mermaid 言語で作成するために動作し、ユーザーが指定したサービスやコンポーネントを理解しやすく整理された図として出力できるように支援します。Mermaid の構文に基づき、`graph TD` 形式を使用してサービス間の関係を視覚的に整理し、`subgraph` を活用してリソースグループやネットワークの階層構造を表現します。Azure の主要コンポーネントとして、コンピュート(VM, Azure Functions, App Services)、ストレージ(Blob Storage, SQL Database, Cosmos DB)、ネットワーク(VNet, Load Balancer, Firewall)、アイデンティティ(Azure AD, Managed Identities)、その他(Logic Apps, API Management, Key Vault)をサポートします。ユーザーの要件に適応し、具体的なサービス構成が指定された場合は適切なノードとリンクを作成し、関係性が不明な場合は一般的な接続パターンを提供し、`style` を使用して異なるサービスの視覚的な強調を行います。コードの可読性を重視し、コメントを付与して図の目的や各ノードの役割を説明し、インデントや改行を適切に使い明瞭なコード構造を実現します。これらの指示を含めることで、GitHub Copilot Agent がユーザーの意図に沿った Mermaid 形式の Azure 構成図を生成できるようになります。';

const Flowchart_PROMPT =
	'GitHub Copilot Agent は、Microsoft Azure のアーキテクチャ構成図を Mermaid 言語で作成するために動作し、ユーザーが指定したサービスやコンポーネントを理解しやすく整理された図として出力できるように支援します。Mermaid の構文に基づき、`graph TD` 形式を使用してサービス間の関係を視覚的に整理し、`subgraph` を活用してリソースグループやネットワークの階層構造を表現します。Azure の主要コンポーネントとして、コンピュート(VM, Azure Functions, App Services)、ストレージ(Blob Storage, SQL Database, Cosmos DB)、ネットワーク(VNet, Load Balancer, Firewall, vWAN)、アイデンティティ(Azure AD, Managed Identities)、その他(Logic Apps, API Management, Key Vault)をサポートします。ユーザーの要件に適応し、具体的なサービス構成が指定された場合は適切なノードとリンクを作成し、関係性が不明な場合は一般的な接続パターンを提供し、`style` を使用して異なるサービスの視覚的な強調を行います。ネットワーク系(VNet, Load Balancer, Firewall, vWAN)は緑色、PaaS 系(Azure Functions, App Services, Logic Apps)はオレンジ色、データベース系(Blob Storage, SQL Database, Cosmos DB)は青色、セキュリティ関連(Azure AD, Managed Identities, Key Vault)は赤色とし、その他のコンポーネントには適切な色を設定します。さらに、仮想ネットワークや vWAN などのネットワークリソースに属するサービスは `subgraph` を活用し、適切なグループ化を行うことで可読性と理解しやすさを向上させます。コードの可読性を重視し、コメントを付与して図の目的や各ノードの役割を説明し、インデントや改行を適切に使い明瞭なコード構造を実現します。これらの指示を含めることで、GitHub Copilot Agent がユーザーの意図に沿った、色分けとネットワークリソースのグループ化が施された Mermaid 形式の Azure 構成図を生成できるようになります。';

const Architecture_PROMPT =
	'あなたは経験豊富なクラウドアーキテクトかつMermaid Architecture記法のエキスパートです。https://mermaid.js.org/syntax/architecture.html のドキュメントとサンプル「architecture-beta group api(cloud)[API] service db(database)[Database] in api service disk1(disk)[Storage] in api service disk2(disk)[Storage] in api service server(server)[Server] in api db:L -- R:server disk1:T -- B:server disk2:T -- B:db」の文法(group: "group {group id}({icon name})[{title}]"、service: "service {service id}({icon name})[{title}]"(in {parent id} は任意)、edge: "{serviceId}:{T|B|L|R} {<}?--{>}? {T|B|L|R}:{serviceId}")を厳守し、group や service のidにハイフン(-)を含めず、出力結果の冒頭に必ず ```architecture-beta を含めたGitHub Markdownのコードブロック形式で、group を仮想ネットワークやサブネット、リソースグループに、service を Azure のリソース(Azure Virtual Machines, Azure App Services, Azure SQL Database, Azure Blob Storage, Azure Functions など)に対応させたAzure構成図のMermaidコードとして出力してください。'

const ArchitectureAzureIcon_PROMPT =
	`あなたは経験豊富なクラウドアーキテクトかつMermaid Architecture記法のエキスパートです。https://mermaid.js.org/syntax/architecture.html のドキュメント、サンプル「architecture-beta group api(azure:resource-groups)[API] service db(azure:sql-database)[Database] in api service disk1(azure:storage-accounts)[Storage] in api service disk2(azure:storage-accounts)[Storage] in api service server(azure:virtual-machine)[Server] in api db:L -- R:server disk1:T -- B:server disk2:T -- B:db」および文法(group: "group {group id}({icon name})[{title}]"、service: "service {service id}({icon name})[{title}]" (in {parent id}は任意)、edge: "{serviceId}:{T|B|L|R} {<}?--{>}? {T|B|L|R}:{serviceId}")を厳守し、group や service の id にはハイフン(-)を含めず、さらにオリジナルアイコンとして npm パッケージ「azureiconkento」(https://www.npmjs.com/package/azureiconkento?activeTab=versions)で提供されるアイコン(例: azure:sql-database, azure:storage-accounts, azure:virtual-machine など)を利用するよう指定し、出力結果の冒頭に必ず「architecture-beta」を含めた GitHub Markdown のコードブロック形式で、group を仮想ネットワークやサブネット、リソースグループに、service を Azure Virtual Machines, Azure App Services, Azure SQL Database, Azure Blob Storage, Azure Functions などに対応させた Azure 構成図の Mermaid コードとして出力してください。`

	// This method is called when your extension is activated
// Your extension is activated the very first time the command is executed
export function activate(context: vscode.ExtensionContext) {


	// define a chat handler
	const handler: vscode.ChatRequestHandler = async (
		request: vscode.ChatRequest,
		context: vscode.ChatContext,
		stream: vscode.ChatResponseStream,
		token: vscode.CancellationToken
	) => {
		// initialize the prompt
		let prompt = BASE_PROMPT;

		if (request.command === 'flowchart2') {
			prompt = Flowchart_PROMPT;
		} else if (request.command === 'architecture2') {
			prompt = Architecture_PROMPT;
		} else if (request.command === 'architecture-azureicon') {
			prompt = ArchitectureAzureIcon_PROMPT;
		}

		// initialize the messages array with the prompt
		const messages = [vscode.LanguageModelChatMessage.User(prompt)];


		// ★ アクティブ・ファイルの内容を追加 ★
        const fileCtx = getCurrentFileContext();
        if (fileCtx) {
            messages.push(
                vscode.LanguageModelChatMessage.User(
                    `現在編集中のファイル ${path.basename(
                        fileCtx.fileName
                    )} の内容です:\n\`\`\`\n${fileCtx.content}\n\`\`\``
                )
            );
        }

		// get all the previous participant messages
		const previousMessages = context.history.filter(
			h => h instanceof vscode.ChatResponseTurn
		);

		// add the previous messages to the messages array
		previousMessages.forEach(m => {
			let fullMessage = '';
			m.response.forEach(r => {
				const mdPart = r as vscode.ChatResponseMarkdownPart;
				fullMessage += mdPart.value.value;
			});
			messages.push(vscode.LanguageModelChatMessage.Assistant(fullMessage));
		});

		// add in the user's message
		messages.push(vscode.LanguageModelChatMessage.User(request.prompt));

		// send the request
		const chatResponse = await request.model.sendRequest(messages, {}, token);

		// stream the response
		for await (const fragment of chatResponse.text) {
			stream.markdown(fragment);
		}

		return;
	};

	// create participant
	const mermaid = vscode.chat.createChatParticipant('mermaid-azure2', handler);

	// add icon to participant
	mermaid.iconPath = vscode.Uri.joinPath(context.extensionUri, 'azure_mermaid.jpg');
}

// This method is called when your extension is deactivated
export function deactivate() { }

5. 動作確認

下記の内容で動作確認を行いました

ハブ&スポークの構成

プロンプト:ハブ&スポークの構成です。ハブには FW があります。スポークは2つでそれぞれに VM があります。

チャット履歴を参照

プロンプト:スポーツにサブネットを追加して、その中に VM を追加してください。またサブネットには NSG を入れてください

チャット履歴を参照 & コマンドでの使い分け

プロンプト:先ほどと同じものを作成してください
少し文法的に正しくない部分がありましたが、概ね正しい構成図を生成してくれました

コンテキストを参照

プロンプト:このファイルでデプロイされる構成図を書いてください

まとめ

GitHub Copilot Extension のチュートリアルを参考にして、Mermaid の Azure 構成図を生成するエージェントを再作成しました
やりたい課題はすべてクリアできたので個人的には大満足です!

参考

共有

Kento
著者
Kento
2020年に新卒で IT 企業に入社. インフラエンジニア(主にクラウド)として活動中