オープンソースのAIコードエディター
マルチエージェント開発の拠点
Web、Insidersエディション、または他のプラットフォーム
VS Codeを使用することで、そのライセンスとプライバシー ステートメントに同意したことになります。
import {
For,
Show,
createMemo,
createSignal,
onCleanup,
onMount,
} from "solid-js";
import { useMail } from "./mail";
import { Item } from "./Item";
const ROW = 56;
const PAGE = 24;
export function MailList() {
const { items, query, load } =
useMail();
const [focus, setFocus] =
createSignal(0);
const [top, setTop] =
createSignal(0);
const visible = createMemo(() => {
const q = query().toLowerCase();
return items()
.filter((m) =>
m.subject
.toLowerCase()
.includes(q),
)
.slice(top(), top() + PAGE);
});
const onKey = (e: KeyboardEvent) => {
if (e.key === "ArrowDown") {
setFocus((i) =>
Math.min(i + 1, PAGE - 1),
);
} else if (e.key === "ArrowUp") {
setFocus((i) =>
Math.max(i - 1, 0),
);
} else if (e.key === "Enter") {
open(visible()[focus()].id);
}
};
onMount(() => {
load();
window.addEventListener(
"keydown",
onKey,
);
onCleanup(() =>
window.removeEventListener(
"keydown",
onKey,
),
);
});
return (
<Show
when={visible().length}
fallback={<Empty />}
>
<For each={visible()}>
{(m, i) => (
<Item
mail={m}
active={i() === focus()}
onOpen={open}
/>
)}
</For>
</Show>
);
}
import type { Email } from "~/types";
interface MailListItemProps {
email: Email;
isSelected: boolean;
onOpen: (id: string) => void;
}
export function MailListItem(props: MailListItemProps) {
return (
<div
role="listitem"
tabindex={0}
onClick={() => props.onOpen(props.email.id)}
onKeyDown={(ev) => ev.key === "Enter" && props.onOpen(props.email.id)}
class="mail-item"
data-selected={props.isSelected ? "true" : undefined}
aria-selected={props.isSelected ? "true" : undefined}
>
<div>
<div class="mail-item-subject truncate">{props.email.subject}</div>
<div class="mail-item-snippet truncate">{props.email.snippet}</div>
</div>
<time
class="text-xs muted"
datetime={props.email.date}
title={new Date(props.email.date).toLocaleString()}
>
{new Date(props.email.date).toLocaleDateString(undefined, {
month: "short",
day: "numeric",
})}
</time>
</div>
);
- 新規作成
MailListItem 個別のメールリストアイテムのレンダリングを処理するコンポーネント - メールアイテムの JSX とロジックを以下から抽出:
MailList して新規の以下に移動:MailListItem コンポーネント - 更新:
MailList 新しいコンポーネントを使用するように変更:MailListItem コンポーネント - プロジェクトをビルドして、変更が正しくコンパイルされることを検証
- アプリケーションをテストして、機能が損なわれていないことを確認
- 個別のメールリストアイテムをレンダリングするための再利用可能なコンポーネントを作成しました
- 受け入れるプロパティ:
email ,isSelected 、およびonSelect props - すべてのアクセシビリティ機能(ARIAロール、キーボードナビゲーション)を維持
- スタイリングとインタラクションの挙動を維持
- インラインのメールアイテムレンダリングロジックを削除して簡素化
- 現在は新規
MailListItem コンポーネントをクリーンなプロパティ渡しで使用 - コンポーネントの複雑さを軽減し、可読性を向上
- ✅ ビルド成功
- ✅ すべての機能が正常に動作(フィルタリング、選択、ナビゲーション)
- ✅ キーボードのアクセシビリティを維持(Enterキーによるナビゲーション)
- ✅ 視覚的な選択状態が正常に機能
MailList.tsx 内の各行をスタンドアロンの MailListItem コンポーネントに抽出します。選択状態、キーボードナビゲーション、および既存の仮想化動作を維持してください。MailListのレイアウトをマッピングしました
現在は行がインラインでレンダリングされており、選択状態はuseSelection で管理されています。react-window の外側要素がリストをラップしているため、仮想化を維持するために、その行レンダラーが新しいコンポーネントを指すようにします。
message、selected、onSelectの props を持つMailListItem.tsxを作成します。message.idとselectedの比較関数を使用して、React.memoでラップします。useSelectionをMailListにリフトアップし、ハンドラーを下に渡します。
focus() を呼び出すようにして、スイートを再実行します。MailListToolbar コンポーネントに抽出し、その Storybook ストーリーを追加します。あなたに代わって開発するエージェント
自律的に計画を立て、コードを変更し、コマンドを実行し、完了するまで反復するAIエージェントにタスクを任せましょう。
たとえば、バックグラウンドでバグのトリアージと修正を行うCLIベースのエージェントを割り当てたり、統合ブラウザでのライブ検証を使用して機能を実装するために別のエージェントとやり取りしたり、ホームページの再設計をクラウドエージェントに委任してチームがレビューするためのプルリクエストを開かせたりすることができます。
エージェントを使い始めるpackage http
import (
"context"
"encoding/json"
"errors"
"io"
"log/slog"
"mime/multipart"
"net/http"
"time"
"golang.org/x/sync/errgroup"
"golang.org/x/sync/semaphore"
"go.opentelemetry.io/otel"
)
type Result[T any] struct {
Name string `json:"name"`
Value T `json:"value,omitempty"`
Error string `json:"error,omitempty"`
}
type Meta struct {
Format string `json:"format"`
Width int `json:"width"`
Height int `json:"height"`
Bytes int64 `json:"bytes"`
}
const (
perRequestTimeout = 30 * time.Second
maxParallel = 8
)
func (s *Server) handleBatch(
w http.ResponseWriter,
r *http.Request,
) {
ctx, span := otel.Tracer("http").
Start(r.Context(), "batch")
defer span.End()
ctx, cancel := context.WithTimeout(
ctx, perRequestTimeout,
)
defer cancel()
r.Body = http.MaxBytesReader(
w, r.Body, s.cfg.MaxBytes,
)
if err := r.ParseMultipartForm(
s.cfg.MaxBytes,
); err != nil {
s.fail(w, http.StatusBadRequest, err)
return
}
files := pickFiles(r.MultipartForm)
if len(files) == 0 {
s.fail(w, http.StatusBadRequest,
errors.New("no files"))
return
}
out := make(
[]Result[Meta], len(files),
)
sem := semaphore.NewWeighted(maxParallel)
g, gctx := errgroup.WithContext(ctx)
for i, fh := range files {
i, fh := i, fh
if err := sem.Acquire(gctx, 1); err != nil {
break
}
g.Go(func() error {
defer sem.Release(1)
out[i] = process(gctx, s, fh)
return nil
})
}
_ = g.Wait()
s.log.LogAttrs(ctx,
slog.LevelInfo, "batch.done",
slog.Int("count", len(out)),
slog.Duration("budget",
perRequestTimeout),
)
w.Header().Set(
"Content-Type", "application/json",
)
_ = json.NewEncoder(w).Encode(out)
}
func process(
ctx context.Context,
s *Server,
fh *multipart.FileHeader,
) Result[Meta] {
res := Result[Meta]{Name: fh.Filename}
f, err := fh.Open()
if err != nil {
res.Error = err.Error()
return res
}
defer f.Close()
data, err := io.ReadAll(
io.LimitReader(f, s.cfg.MaxBytes),
)
if err != nil {
res.Error = err.Error()
return res
}
m, err := s.proc.ExtractCtx(ctx, data)
if err != nil {
res.Error = err.Error()
return res
}
res.Value = Meta{
Format: m.Format,
Width: m.Width,
Height: m.Height,
Bytes: int64(len(data)),
}
return res
}
POST /process/batch エンドポイントを追加します。リクエストごとのバジェット、構造化ロギング、OpenTelemetryスパンを使用して、最大8個のファイルを並行して処理します。アイテムごとの結果を返します。サービスのレイアウトをマッピングしました
既存のハンドラーはinternal/http にあり、プロセッサは同期処理の Extract を公開しています。ワーカープールがキャンセルを尊重できるように ExtractCtx バリアントを追加し、errgroup と重み付きセマフォを使用してファンアウトさせます。
http.HandleFunc を grep:- ジェネリックな
Result[Meta]型を使用して、batch.goにhandleBatchを追加します。 semaphore.NewWeighted(8)で並行数を制限し、ファンアウトをerrgroupでラップします。- リクエストを OTel スパンと 30秒のコンテキスト期限でラップします。
server.goでルートを紐付けし、テーブルテストを追加します。
go test ./internal/http -run Batch -race を実行-race エラーなしで合格しました。64枚の画像バッチ(平均1.2MB JPEG)のスループット:エンドツーエンドで 184msから31ms に短縮k6 スクリプトを追加します。p99_ms Prometheus ヒストグラムを公開し、既存の Grafana ダッシュボードに紐付けます。あらゆるエージェント、あらゆるモデル
あなたのワークフローに合ったエージェントハーネスを使用しましょう。Copilotや、Claude、OpenAIといったサードパーティプロバイダーを使用して、ローカルまたはクラウドでエージェントを実行できます。
高速な補完モデルから高度な推論モデルまで、プロバイダーをまたぐ数十のモデルから選択できます。あるいは、独自のキーを持ち込んで、任意のプロバイダーの任意のモデルを使用することも可能です。
すべてのセッションを1つのビューに
複数のエージェントが並行してタスクに取り組んでいる間も、生産性を維持できます。実行場所に関係なく、すべてのエージェントセッションを単一のビューから追跡します。
別のツールやターミナルに切り替えることなく、セッションのフィルタリングや監視、または個々のエージェントとのインタラクションへのドリルダウンを迅速に行うことができます。
あなたのルール、あなたのエージェント
エージェントがあなたの開発プラクティスやチームのワークフローに従うようにします。カスタム指示の定義、エージェントスキルの追加、あるいはプロジェクトに合わせたカスタムエージェントの構築が可能です。
MCPサーバーを使用して外部のツールやサービスに接続したり、エージェントのプラグインや拡張機能をインストールして、エージェントの機能を拡張したりできます。
コアとなるのは、世界クラスのコードエディター
VS Codeは、10年以上にわたり何百万人もの開発者に選ばれ続けているエディターです。AIを搭載したインライン提案、インテリジェントな補完、そして豊かな編集体験により、ご自身でコードを書く際にも同様に強力な威力を発揮します。
エージェントとの作業と、手作業でのコーディングを、すべて同じエディター内でシームレスに切り替えることができます。
VS Codeを始めるimport numpy as np
import pandas as pd
iris_data = pd.read_csv("iris_dataset.csv")
def describe(species: str) -> pd.Series:
7
subset = data[data["species"] == species]
subset = iris_data[iris_data["species"] == species]
if subset.empty:
raise ValueError(f"{species} missing from sample")
return subset[["petal", "sepal"]].agg(["mean", "std"]).loc["mean"]
def summary():
13
for species in np.sort(data["species"].unique()):
for species in np.sort(iris_data["species"].unique()):
try:
stats = describe(species)
except ValueError:
print(f"{species}: no records")
continue
print(f"{species}: petal={stats['petal']:.2f} sepal={stats['sepal']:.2f}")
if __name__ == "__main__":
summary()
拡張機能を使用したコード作成
拡張機能やModel Context Protocol(MCP)サーバーのツールを使用して、エージェントを拡張できます。また、独自の拡張機能を構築して、チーム特有のシナリオを強化することもできます。
8万以上の拡張機能を拡張機能マーケットプレイスで見る
あらゆる言語でコードを書く
VS Codeは、ほぼすべての主要なプログラミング言語をサポートしています。JavaScript、TypeScript、CSS、HTMLなどは標準で搭載されていますが、その他の言語の拡張機能もVS Codeマーケットプレイスで見つけることができます。

JavaScript
TypeScript
Python
C#
C++
HTML
Java
JSON
PHP
Markdown
Powershell
YAML完全にカスタマイズ可能
VS CodeのUIとレイアウトをカスタマイズして、自分のコーディングスタイルに合わせることができます。
配色テーマを使用すると、VS Codeのユーザーインターフェースの色を好みに合わせて変更し、作業環境に適応させることができます。
設定の同期(Settings Sync)機能を使用すると、お使い of VS Codeインスタンス間でユーザー設定を共有できます。
プロファイルを使用すると、カスタマイズのセットを作成して素早く切り替えたり、他の人と共有したりできます。
どこでもコードを書く
クラウドやリモートリポジトリに接続している場合でも、Web版VS Code(vscode.dev)を使ってブラウザで作業している場合でも、最も生産性が高まる場所でコードを書くことができます。
組み込みのソース管理により、すぐにGitサポートを利用できます。他の多くのソース管理プロバイダーも拡張機能を通じて利用可能です。
GitHub Codespacesは、長期的なプロジェクトから、プルリクエストのレビューなどの短期的なタスクまで、あらゆるアクティビティに対応するクラウド駆動の開発環境を提供します。
リッチな機能でコーディング
エディターにはまだまだ多くの魅力があります。組み込みの機能を使う場合も、豊富な拡張機能を使う場合も、すべての人に最適な何かが見つかります。
統合ターミナル
zsh、pwsh、git bashなど、お気に入りのシェルをすべてエディター内で使用できます。
コードの実行
エディターを離れることなく、コードの実行とデバッグを行えます。
バージョン管理
Gitやその他の多くのソース管理プロバイダー向けの組み込みサポート。
ビルドタスク
VS Code内からツールを実行し、その結果を分析します。
ローカル履歴
自動的に追跡されるローカル履歴により、変更を失うことはありません。
テーマ
テーマはあなたの個性の延長です。エディターに華を添え、あなたらしさを加えましょう。
アクセシビリティ
スクリーンリーダー、高コントラストテーマ、キーボード操作のみのナビゲーションに最適化された体験。
Webサポート
スマートフォン、タブレット、デスクトップのいずれからでも、どこからでもコードにアクセスできます。