– 代理会话日,2月19日

开源 AI 代码编辑器

下载 Visual Studio Code

通过使用 VS Code,您同意其 许可协议隐私声明

交互式主页展示 Visual Studio Code 界面,包含 Agent 会话、示例选项卡和 Copilot 聊天;使用导航探索编辑器内容。
代理会话
本地聊天代理 重构 MailList 组件结构 GitHub Copilot 云代理 将 MailListItem 提取为独立组件 10 分钟 #1
+42 -24
GitHub Copilot CLI 代理 启动 CLI 代理会话
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 云代理 委托给云代理 代理将异步工作以创建包含您请求的更改的拉取请求。 kenzi.lawson avatar kenzi.lawson选择了“委托” GitHub Copilot 云代理 [WIP] 重构 MailList 以抽象邮件列表项 - Copilot 云代理已开始处理“请更新 Ma...”并将随着工作的进行更新此拉取请求。请更新 MailList 组件以将单个邮件列表项抽象为自己的组件。由 VS Code 通过 GitHub 拉取请求扩展创建。✨ 让 Copilot 编码代理为您设置一切 — 编码代理在为您的仓库设置后,工作速度更快且质量更高。 GitHub Copilot 云代理已开始处理您的请求。请在关联的聊天和拉取请求中跟踪其进度。 MailList.tsx
描述接下来要构建的内容
代理 Claude Opus 4.6

适用于任何团队的任何模型

从多个开箱即用的模型中选择,或带来您自己的密钥以访问您首选模型和托管提供商的模型。

代理 GPT-5.3-Codex
自动 变量 GPT-5 mini 0x Claude Opus 4.6 3x Claude Sonnet 4.6 1x Gemini 3 Pro (预览版) 1x GPT-5.3-Codex 1x 管理模型...

了解您的代码库的专家

您的代码库已本地和远程索引,以了解相关内容,从而实现快速、感知上下文的交互。

main.rs
代码库中的数据库连接字符串在哪里配置?
代理 GPT-5.3-Codex

以您的团队工作方式使用 AI

使用自定义代理、自定义指令和可重用的提示文件来个性化交互,这些提示文件针对您的工作流程和工具量身定制。

交互式 VS Code 编辑器模拟,其中提示文件在选项卡中打开;使用标准键盘导航来探索每个窗格。
Compact.agent.md AGENTS.md docs.instructions.md
---
                        description: 'Generate compact responses, focusing on brevity and clarity.'
                        tools: ['search', 'fetch', 'githubRepo', 'usages', 'vscodeAPI', 'problems', 'changes', 'testFailure', 'todos']
                        ---
                        You are an agent that provides extremely concise and clear responses. 
                        Your replies should be brief, to the point, and free of unnecessary details. 
                        Focus on delivering the essential information in a straightforward manner.
                        When responding, you must adhere to the following guidelines:
                        - Use short sentences and simple language.
                        - Prioritize clarity over completeness.
                        - Do not provide explanations or justifications unless explicitly asked.
                        - Do not provide any updates as you are working on the task –– only respond when the task is complete.
                        

免费使用 VS Code 中的 AI 功能

无需试用。无需信用卡。只需您的 GitHub 帐户。

免费试用

代理模式

处理复杂的、多步骤的任务。代理模式读取您的代码库,建议跨文件的编辑,运行终端命令,并响应编译或测试失败 — 所有这些都在循环中进行,直到任务完成。通过 VS Code 扩展和模型上下文协议 (MCP) 服务器进一步完善代理模式,以适应您的团队工作流程。

使用代理模式构建
交互式代理模式演示,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。我将强制执行最大正文大小,并确保内容类型为 multipart/form-data。接下来,我将解析表单并遍历 form.File["files"]。 对于每个 FileHeader,我将打开它并读取字节,然后调用 ExtractMetadata 来收集结果。最后,我将返回一个结构化的 JSON 响应,其中包含结果并处理没有文件和最大批量限制的边缘情况。 我认为这可能不是绝对必要的,但我正在考虑一个小改进,即使用 sync.WaitGroup 来顺序处理每个文件,同时限制并发。这将使初始提交更简单。我需要添加代码文件并导入内部/image 引用别名。 接下来,我将查看 tests/image_processor_test.go 中现有的测试,以了解风格并确定我是否应该为批量处理程序创建一个新的测试文件。我将阅读它,然后更新待办事项状态,将任务一和任务二标记为已完成。
正在阅读现有测试以镜像风格,然后再添加批量端点并进行设计和实现。 读取image_processor_test.go
准备 HTTP 测试 我需要运行一个 HTTP 测试,但我注意到当前的测试包位于“tests”中,而不是在主模块内。为了进行 HTTP 测试,我需要设置一些东西,例如配置、处理器、记录器和服务器,以及发送一个 multipart 请求。我的下一步是检查 config.go 中的配置,以了解我需要包含哪些必需字段。让我们深入研究一下!
正在读取配置以构建 HTTP 测试中的服务器。 读取config.go
管理更新和补丁 我需要使用 manage_todo_list 来保持一切井井有条,确保我不会遗失任何任务。完成这些操作后,我就可以继续应用补丁了。它将涉及添加一个新文件并编辑 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,则回退到任何文件部分)。
    • 返回每个文件的成功/错误,而不会使整个批处理失败。
    • 聚合计数:count、success、failed。
  • batch_endpoint_test.go: 测试正常路径(1 个有效 + 1 个无效文件)和缺少文件错误情况。
建议的下一步(可选)
  • 添加可配置的最大每批文件数(例如,通过配置)。
  • 使用有限内存(处理 + 丢弃)流式处理非常大的图像。
  • 可选的并行性,使用工作池和上下文取消。
  • 在解码之前添加每个文件的尺寸验证。
  • 支持基于 JSON 的批量处理(URL 或 base64),用于非 multipart 客户端。
如果您需要这些增强功能或更喜欢不同的请求/响应格式,请告诉我。
batch.go
描述接下来要构建的内容
代理 Gemini 3 Pro (预览版)

下一个编辑建议

VS Code 预测您在编码时的下一步操作。使用 Tab 键接受编辑器中 AI 提供的建议。它会根据您正在进行的编辑,智能地推荐更改内容以及更改位置。

使用 AI 提供的建议进行编码
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

随时随地编码

无论您是在云端、远程存储库中还是在 Web 上的 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.