開源 AI 程式碼編輯器

您的多 Agent 開發中心

下載 Visual Studio Code

使用 VS Code 即表示您同意其授權條款隱私權聲明

互動式主圖顯示 Visual Studio Code 介面,包含 Agent 工作階段、範例標籤頁和 Copilot 聊天;請使用導覽功能探索編輯器內容。
Agent 工作階段
本地聊天 Agent 重構 MailList 元件結構 GitHub Copilot 雲端 Agent 擷取 MailListItem 為獨立元件 10 分鐘 #1
+42 -24
GitHub Copilot CLI Agent 啟動 CLI Agent 工作階段
MailList.tsx MailListItem.tsx 擷取 MailListItem 為獨立元件
import { For, createSignal, createMemo } from "solid-js";
import { useNavigate, useParams } from "@tanstack/solid-router";
import { getEmailsForMailbox } from "~/data/emails";
import { MailListItem } from "~/components/MailListItem";

export function MailList() {
  const params = useParams({ strict: false }) as {
    mailbox?: string;
    id?: string;
  };
  const navigate = useNavigate();
  const [query, setQuery] = createSignal("");
  const mailbox = () => params.mailbox || "inbox";
  const list = createMemo(() => {
    const q = query().toLowerCase();
    return getEmailsForMailbox(mailbox()).filter(
      (e) =>
        !q ||
        e.subject.toLowerCase().includes(q) ||
        e.snippet.toLowerCase().includes(q)
    );
  });
  function open(id: string) {
    navigate({
      to: "/mail/$mailbox/$id",
      params: { mailbox: mailbox(), id },
      search: (prev) => prev,
    });
  }

  return (
    <For each={list()}>
      {(e) => (
        <div
          role="listitem"
          tabindex={0}
          onClick={() => open(e.id)}
          onKeyDown={(ev) => ev.key === "Enter" && open(e.id)}
          class="mail-item"
          data-selected={params.id === e.id ? "true" : undefined}
          aria-selected={params.id === e.id ? "true" : undefined}
        >
          <div>
            <div class="mail-item-subject truncate">{e.subject}</div>
            <div class="mail-item-snippet truncate">{e.snippet}</div>
          </div>
          <time
            class="text-xs muted"
            datetime={e.date}
            title={new Date(e.date).toLocaleString()}
          >
            {new Date(e.date).toLocaleDateString(undefined, {
              month: "short",
              day: "numeric",
            })}
          </time>
        </div>
        <MailListItem
          email={e}
          isSelected={params.id === e.id}
          onOpen={open}
        />
      )}
    </For>
  );
}
聊天
請更新 MailList 元件,將郵件清單項目抽象化為其自身的獨立元件 GitHub Copilot 雲端 Agent 委託給雲端 Agent Agent 將以非同步方式建立包含您所要求變更的提取要求 (pull request)。 kenzi.lawson avatar kenzi.lawson已選擇「委託」 GitHub Copilot 雲端 Agent [WIP] 重構 MailList 以抽象化郵件清單項目 - Copilot 雲端 Agent 已開始處理「請更新 Mail...」,並將隨著進度更新此提取要求。請更新 MailList 元件,將個別郵件清單項目抽象化為其自身的元件。透過 GitHub Pull Request 延伸模組從 VS Code 建立。 ✨ 讓 Copilot 編碼 Agent 為您設定一切 — 當針對您的存放庫進行設定後,編碼 Agent 的運作速度更快且品質更高。 GitHub Copilot 雲端 Agent 已開始處理您的請求。請在相關聯的聊天和提取要求中關注其進度。 MailList.tsx
描述下一步要建置的內容
Agent Claude Opus 4.6

為您建置開發工作的 Agent

將任務交給 AI Agent,讓它們自主規劃、修改程式碼、執行指令並持續迭代,直到工作完成。

例如,指派一個基於 CLI 的 Agent 在背景分類並修復錯誤,與另一個 Agent 互動以在整合式瀏覽器中使用即時驗證來實作功能,並將首頁重新設計委託給雲端 Agent,讓它開啟提取要求供您的團隊審核。

開始使用 Agent
互動式 Agent 導覽,包含 VS Code 標籤頁、側邊欄和聊天互動;使用標準鍵盤導覽探索每個窗格。
batch.go processor.go image_processor_test.go health.go main.go
package http

import (
    "io"
    "log/slog"
    "mime/multipart"
    "net/http"
    "strings"
)

type BatchItemResult struct {
    Name string `json:"name"`
    Metadata *struct {
        Format string `json:"format"`
        Width  int    `json:"width"`
        Height int    `json:"height"`
        Bytes  int    `json:"bytes"`
    } `json:"metadata,omitempty"`
    Error string `json:"error,omitempty"`
}

type BatchResponse struct {
    Results []*BatchItemResult `json:"results"`
    Count   int                `json:"count"`
    Success int                `json:"success"`
    Failed  int                `json:"failed"`
}

// handleProcessBatch processes multiple uploaded images (multipart/form-data) under the field name "files".
// It returns metadata for each image or an error per item without failing the whole batch unless the request is malformed.
func (s *Server) handleProcessBatch(w http.ResponseWriter, r *http.Request) {
    // Enforce max body size overall.
    r.Body = http.MaxBytesReader(w, r.Body, s.cfg.MaxUploadBytes)
    if ct := r.Header.Get("Content-Type"); !strings.HasPrefix(ct, "multipart/form-data") {
        s.writeJSON(w, http.StatusBadRequest, map[string]string{"error": "content type must be multipart/form-data"})
        return
    }
    if err := r.ParseMultipartForm(s.cfg.MaxUploadBytes); err != nil {
        status := http.StatusBadRequest
        if strings.Contains(err.Error(), "request body too large") {
            status = http.StatusRequestEntityTooLarge
        }
        s.writeJSON(w, status, map[string]string{"error": "invalid multipart form: " + err.Error()})
        return
    }

    // Accept files under the key "files". If absent, attempt to fallback to any file parts.
    var fileHeaders []*multipart.FileHeader
    if r.MultipartForm != nil && len(r.MultipartForm.File["files"]) > 0 {
        fileHeaders = r.MultipartForm.File["files"]
    } else if r.MultipartForm != nil {
        // Fallback: gather all files across keys.
        for _, fhs := range r.MultipartForm.File {
            fileHeaders = append(fileHeaders, fhs...)
        }
    }

    if len(fileHeaders) == 0 {
        s.writeJSON(w, http.StatusBadRequest, map[string]string{"error": "no files provided (expect key 'files')"})
        return
    }

    resp := &BatchResponse{Results: make([]*BatchItemResult, 0, len(fileHeaders))}

    for _, fh := range fileHeaders {
        item := &BatchItemResult{Name: fh.Filename}
        f, err := fh.Open()
        if err != nil {
            item.Error = "open file: " + err.Error()
            resp.Results = append(resp.Results, item)
            resp.Failed++
            continue
        }
        data, err := io.ReadAll(f)
        _ = f.Close()
        if err != nil {
            item.Error = "read file: " + err.Error()
            resp.Results = append(resp.Results, item)
            resp.Failed++
            continue
        }
        meta, err := s.proc.ExtractMetadata(data)
        if err != nil {
            item.Error = err.Error()
            resp.Results = append(resp.Results, item)
            resp.Failed++
            continue
        }
        // Copy into anonymous struct to decouple from internal type if it changes.
        item.Metadata = &struct {
            Format string `json:"format"`
            Width  int    `json:"width"`
            Height int    `json:"height"`
            Bytes  int    `json:"bytes"`
        }{Format: meta.Format, Width: meta.Width, Height: meta.Height, Bytes: meta.Bytes}
        resp.Results = append(resp.Results, item)
        resp.Success++
    }

    resp.Count = len(resp.Results)
    s.log.LogAttrs(r.Context(), slog.LevelInfo, "batch processed", slog.Int("count", resp.Count), slog.Int("success", resp.Success), slog.Int("failed", resp.Failed))
    s.writeJSON(w, http.StatusOK, resp)
}
Copilot Claude Code - VSCode · AI 程式碼編輯器 Claude Code Codex - VSCode · AI 程式碼編輯器 Codex Cline - VSCode · AI 程式碼編輯器 Cline Gemini - VSCode · AI 程式碼編輯器 Gemini 聊天
我正在建置一個影像處理服務。您可以建立一個支援批次影像處理的新端點嗎?
建立待辦事項清單 我將從建立待辦事項清單開始,管理諸如讀取現有的伺服器和處理器程式碼、設計批次端點契約,以及實作一個包含處理常式的新檔案等任務。我希望將處理常式連接到伺服器路由中,並可能為批次端點添加一個基本的測試,雖然那是可選的。我還計劃在之後執行測試並建置所有內容。讓我們開始執行吧!
為實作批次影像處理端點建立結構化的待辦事項清單。 已建立 7 個待辦事項 在新增批次端點之前,先讀取核心檔案以了解目前的伺服器和影像處理實作。 讀取server.go 讀取processor.go 讀取logging.go 讀取health.go
正在改進檔案處理... 我可以修改 server.go,但他們要求使用新檔案。因此,我需要建立一個路由,暫且稱之為 /process/batch。我將強制執行最大 body 大小,並確保內容類型為 multipart/form-data。接著,我將解析表單並反覆運算 form.File["files"]。 對於每個 FileHeader,我會開啟它並讀取位元組,然後呼叫 ExtractMetadata 來收集結果。最後,我將回傳一個包含結果的結構化 JSON 回應,並處理無檔案和最大批次限制的極端情況。 我認為這可能不是絕對必要,但我正考慮使用 sync.WaitGroup 依序處理每個檔案,同時限制並行性。這將使初始提交更簡單。我需要新增程式碼檔案並匯入 internal/image 引用別名。 接著,我將查看 tests/image_processor_test.go 中現有的測試,了解其風格並決定是否應該為批次處理常式建立新的測試檔案。我將通讀該檔案,然後更新待辦事項狀態,將任務一和二標記為已完成。
在新增批次端點之前,先閱讀現有測試以模仿其風格,然後再進行設計與實作。 讀取image_processor_test.go
準備 HTTP 測試 我需要執行 HTTP 測試,但我注意到目前的測試套件位於 'tests' 中,而不是在主模組內。為了進行 HTTP 測試,我必須設定幾項內容,如設定、處理器、記錄器和伺服器,並發送一個多部分請求。我的下一步是檢查 config.go 中的設定,以了解我需要包含哪些必要欄位。讓我們開始深入研究吧!
讀取設定以在 HTTP 測試中建構伺服器。 讀取config.go
管理更新與修補程式 我需要使用待辦事項清單管理功能來保持一切井然有序,確保我不會遺漏任何任務。一旦完成,我就可以繼續套用修補程式。這將涉及新增一個新檔案並對 server.go 進行編輯。我希望確保在此過程中一切都清晰準確,以避免出現任何錯誤。讓我們繼續前進!
開始執行 (3/7) 設計批次契約
實作更新與測試 我將設計契約標記為已完成,接著我需要實作更新。我將繼續管理待辦事項清單,並套用修補程式以新增檔案並更新 server.go。看來我可能需要在 server.go 中為 /process/batch 新增路由,並實作一個新檔案 internal/http/batch.go。撰寫程式碼後,我會新增測試檔案,使用 go test 執行測試,並使用 run_in_terminal 命令。讓我們開始吧!
已完成 (3/7) 設計批次契約 套用修補程式以新增批次處理常式、路由及測試。 server.go+1 -0 batch.go+106 -0 batch_endpoint_test.go+123 -0 已實作新的批次影像處理端點 變更/新增的檔案
  • server.go:註冊了新路由 POST /process/batch。
  • batch.go:新的處理常式 handleProcessBatch,其功能為:
    • 接受 multipart/form-data。
    • 讀取 files 鍵下的多個檔案 (如果缺少 files 則回退到任何檔案部分)。
    • 回傳個別檔案的成功/錯誤資訊,而不會導致整個批次失敗。
    • 彙總計數:總數、成功、失敗。
  • batch_endpoint_test.go:測試正常流程 (1 個有效 + 1 個無效檔案) 和缺少檔案的錯誤情況。
建議的後續步驟 (可選)
  • 新增每批次最大檔案數的可設定限制 (例如:透過 config)。
  • 針對極大型影像使用記憶體受限的串流處理 (處理 + 捨棄)。
  • 使用工作池 (worker pool) 和內容取消 (context cancellation) 進行可選的並行處理。
  • 在解碼前對每個檔案進行大小驗證。
  • 為非多部分請求的用戶端支援基於 JSON 的批次 (URL 或 base64)。
如果您希望進行上述任何增強,或偏好不同的請求/回應格式,請告訴我。
batch.go
描述下一步要建置的內容
Agent Gemini 1.5 Pro (預覽版)

任何 Agent,任何模型

使用符合您工作流程的 Agent 套件。在本地或雲端執行 Agent,並搭配 Copilot 或 Claude、OpenAI 等第三方供應商。

從各家供應商的數十種模型中進行選擇,從快速完成模型到進階推理模型應有盡有。或者自備金鑰以使用來自任何供應商的任何模型。

所有工作階段,一覽無遺

在多個 Agent 並行處理任務時保持高效率。從單一檢視畫面追蹤所有 Agent 工作階段,無論它們在哪裡執行。

快速篩選並監控工作階段,或深入了解個別 Agent 的互動,無需切換到不同的工具或終端機。

您的規則,您的 Agent

確保 Agent 遵循您的實踐經驗與團隊工作流程。定義自訂指令、新增 Agent 技能,或建置為您的專案量身打造的自訂 Agent。

透過 MCP 伺服器連接外部工具與服務,或安裝 Agent 外掛程式或延伸模組以擴展 Agent 的功能。

免費開始使用 AI Agent 進行開發

無需試用。無需信用卡。只需您的 GitHub 帳戶。

免費試用

核心是世界級的程式碼編輯器

十多年來,VS Code 一直是數百萬開發者的首選編輯器。AI 驅動的行內建議、智慧補全和豐富的編輯體驗,讓您在親自撰寫程式碼時同樣強大。

在 Agent 協助工作與親自編寫程式碼之間無縫切換,一切都在同一個編輯器中完成。

開始使用 VS Code
main.py
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()

支援任何語言

VS Code 支援幾乎所有主流程式語言。內建支援多種語言,如 JavaScript、TypeScript、CSS 和 HTML,而其他語言的延伸模組可在 VS Code 市集中找到。

JavaScript iconJavaScript
TypeScript iconTypeScript
Python iconPython
C# iconC#
C++ iconC++
HTML iconHTML
Java iconJava
JSON iconJSON
PHP iconPHP
Markdown iconMarkdown
Powershell iconPowershell
YAML iconYAML

完全可自訂

自訂您的 VS Code UI 和版面配置,使其符合您的編碼風格。

色彩佈景主題讓您可以修改 VS Code 使用者介面中的顏色,以符合您的偏好和工作環境。

設定同步讓您可以透過設定同步功能,在不同的 VS Code 實例之間共用您的使用者設定。

設定檔讓您可以建立一組自訂設定,並在它們之間快速切換或與他人共用。

Selecting the GitHub Dark theme with a quick pick Selecting the GitHub Dark theme with a quick pick

隨處編寫程式碼

無論您是連接到雲端、遠端存放庫,還是在瀏覽器中使用 VS Code 網頁版 (vscode.dev),都能在您生產力最高的地方編寫程式碼。

內建原始碼控制為您提供現成的 Git 支援。許多其他原始碼控制供應商也可透過延伸模組取得。

GitHub Codespaces 為任何活動提供雲端驅動的開發環境 — 無論是長期專案,還是像審查提取要求這樣的短期任務。

vscode.dev in an Edge browser tab vscode.dev in an Edge browser tab

功能豐富的編碼體驗

編輯器的功能遠不止於此。無論是使用內建功能還是豐富的延伸模組,每個人都能找到適合自己的功能。

© . This site is unofficial and not affiliated with Microsoft.