文章目录
- 背景
- [Copilot 聊天记录的存储位置](#Copilot 聊天记录的存储位置)
-
- [vscode Remote-ssh 的UI细节](#vscode Remote-ssh 的UI细节)
-
- [🖥️ VS Code Remote-SSH 信息存储与可见性一览](#🖥️ VS Code Remote-SSH 信息存储与可见性一览)
- 本地UI,远程执行
-
- [1. Copilot 聊天记录](#1. Copilot 聊天记录)
- [2. GitHub 账号信息](#2. GitHub 账号信息)
- [3. 终端命令与操作](#3. 终端命令与操作)
- [4. 代码文件与工作区插件](#4. 代码文件与工作区插件)
- [🖥️ 场景1:编写代码和浏览文件](#🖥️ 场景1:编写代码和浏览文件)
- [📺 场景2:查看终端输出](#📺 场景2:查看终端输出)
- [💻 场景3:在 UI 中查看结果文件](#💻 场景3:在 UI 中查看结果文件)
- [🧠 一个更生动的类比](#🧠 一个更生动的类比)
- 再说回插件(本地UI还是远程工作区)
-
- [🔄 场景对比:小白(模拟小白🤣)的理解 vs. 正确姿势](#🔄 场景对比:小白(模拟小白🤣)的理解 vs. 正确姿势)
- [🧩 以"代码补全"和"Copilot Agent"为例](#🧩 以“代码补全”和“Copilot Agent”为例)
-
- [1. 当我们使用代码补全(如输入 `pr` 触发 `print()`)](#1. 当我们使用代码补全(如输入
pr触发print())) - [2. 当我们使用 Copilot Agent 修改代码](#2. 当我们使用 Copilot Agent 修改代码)
- [1. 当我们使用代码补全(如输入 `pr` 触发 `print()`)](#1. 当我们使用代码补全(如输入
- [🧠 如果强制改变插件的"归属地"会怎样?](#🧠 如果强制改变插件的“归属地”会怎样?)
- [存储Copilot 聊天记录的一些方法](#存储Copilot 聊天记录的一些方法)
-
- 1,直接右键copy
- [2,通过 Ctrl+Shift+P | Chat](#2,通过 Ctrl+Shift+P | Chat)
- 3,一些三方工具
- 4,但是?
-
- [如何直接本地聊天历史文件导入本机chat session:手动?](#如何直接本地聊天历史文件导入本机chat session:手动?)
- [能否自动保存本机chat session?](#能否自动保存本机chat session?)
背景
当在多台机器上工作时,开发者通常希望保留他们之前的 GitHub Copilot 聊天会话,尤其是当这些会话包含有价值的见解或故障排除记录时。
比如说,当我有多台工作电脑时,我希望能够在这多台电脑的vscode的Github copilot之间实现聊天历史的共享、跨设备流转。
我的个人场景是多台windows设备remote ssh到同一台服务器上,IDE常用的是Vscode,
但是经常是工作日在工位上,用工位的电脑,周末或者外出出差用自己的私人电脑,
但是这些电脑之间remote的vscode的copilot聊天记录,不能够跨设备互通,无疑大大降低了跨设备使用场景的工作效率。
参考问题:
https://github.com/microsoft/vscode-copilot-release/issues/991(这个是核心sync across devices)
https://www.reddit.com/r/vscode/comments/1jt5vqx/any_way_to_sync_github_copilot_sessions/
https://github.com/orgs/community/discussions/57190
https://github.com/orgs/community/discussions/129888


Copilot 聊天记录的存储位置
在 Visual Studio Code 中,Copilot 的聊天历史记录保存在本地的一个隐藏工作区目录中。每个项目或工作区在主存储路径下都会获得一个唯一的文件夹名称。
参考https://github.com/orgs/community/discussions/57190,
直接给出答案:
python
For Windows: %APPDATA%\Code\User\workspaceStorage\
For macOS: ~/Library/Application Support/Code/User/workspaceStorage/
For Linux: ~/.config/Code/User/workspaceStorage/
每个文件夹均存放对应特定工作区的聊天记录,由唯一的工作区 ID 进行标识
我本人远程主机用的是Linux Ubuntu,里面自然是什么都没有。

然后windows本机,随便打开1个文件夹,在搜索栏中输入

python
C:\Users\zht\AppData\Roaming\Code\User\workspaceStorage

很显然这些聊天历史都保存在本地windows中
- VS Code 的数据存储机制:虽然
workspaceStorage目录在本地和远程服务器上都存在,但在使用 Remote-SSH 时,扩展的状态数据(如 Copilot 的聊天记录)默认存储在本地计算机。 - Copilot 扩展的运行位置:VS Code 的扩展可分为 UI 端和工作区端两种。
GitHub Copilot和GitHub Copilot Chat这类主要处理 UI 交互的扩展,会运行在我们本地的 Windows 电脑上。因此,它的数据自然也留存在本地。 - 工作区标识:VS Code 为每个工作区(项目)分配一个唯一的 ID,我们本地
workspaceStorage目录下的那些文件夹名称,就是这个唯一 ID。它对应着我们在远程 Linux 主机上打开的项目。
在这里,我得提1个新手非常常见的误区,就是不清楚vscode的UI界面和我们远程ssh的主机,到底干的是前端还是后端的工作,在细节上是怎么样的?
vscode Remote-ssh 的UI细节
不仅仅是"终端背后",所有与文件、代码、环境交互的"大脑"都在远程服务器上。本地 VS Code 更像是一个高性能的"遥控器 + 显示器"。
因此,同一台远程主机上的其他用户,如果使用不同的系统账号,是绝对无法通过主机上的任何文件或进程看到我们的 Copilot 聊天记录、GitHub 账号信息以及我们本地的 UI 配置的。他们能看到的,只有我们通过命令在主机上留下的实际痕迹(如代码文件、进程、.bash_history 等)。
🖥️ VS Code Remote-SSH 信息存储与可见性一览
| 信息类型 | 运行/存储位置 | 同一主机其他用户是否可见 |
|---|---|---|
| Copilot 聊天记录 | 本地 Windows 电脑 | ❌ 不可见 |
| GitHub 账号信息 | 本地 Windows 电脑 | ❌ 不可见 |
| UI 插件 (主题、图标等) | 本地 Windows 电脑 | ❌ 不可见 |
| 终端命令 | 远程 Linux 主机 | ⚠️ 部分可见 (系统级进程等) |
| 工作区插件 (Python、Go 等) | 远程 Linux 主机 | ✅ 可见 (若共用用户) |
| 代码文件 | 远程 Linux 主机 | ✅ 可见 (若共用用户) |
这种分工背后,是 Remote-SSH 的一个核心设计:本地 UI,远程执行。
本地UI,远程执行
我们可以把 VS Code Remote-SSH 理解成一个远程桌面,只不过它是专门为代码编辑和开发定制的。
- 本地 VS Code 是"前台":我们本地 Windows 上的 VS Code 负责呈现用户界面 (UI),比如编辑器、侧边栏、菜单和聊天窗口。所有影响 UI 的插件,如主题、图标和 Copilot Chat,也都在本地运行。
- 远程主机是"后台":当我们连接到远程主机时,VS Code 会在上面自动安装一个
VS Code Server。这个 Server 负责所有真正的"后台"工作,比如执行终端命令、运行调试器、进行代码分析(IntelliSense)。像 Python、Go 这类语言支持插件,也会安装在远程主机上执行。
当我们通过 Remote-SSH 打开一个集成终端并执行 ls 命令时,这个命令其实是通过 SSH 隧道,由我们本地的 VS Code 发送给远程主机上的 VS Code Server,再由它在远程主机上执行,并把结果返回显示在我们的本地终端里。这就是"本地编写,远程执行"。
结合上面的架构,我们就可以清楚地知道自己的信息具体在哪,以及别人能否看到。
1. Copilot 聊天记录
- 位置:本地 Windows 电脑。正如我们之前发现的,它们保存在
%APPDATA%\Code\User\workspaceStorage\目录下。 - 可见性:其他用户看不到。因为数据在我们本地,即使其他用户登录到同一台远程主机,也访问不到我们本地电脑上的文件(之前遇到1个学生,在实验室服务器上装了个copilot插件,用的是自己账号,买了pro会员,平时用自己windows电脑远程ssh编程,还一直担心我们会不会在主机上偷窥到他的聊条记录或者是代码idea,其实是不会的,因为聊天记录是保存在windows本地的,不在远程主机上)。
2. GitHub 账号信息
- 位置:本地 Windows 电脑。VS Code 的 GitHub 认证信息存储在 Windows 的"凭据管理器"中。
- 可见性:其他用户看不到。为了在远程终端里也能用 Git,VS Code 默认会把本地存储的凭证,通过 SSH 隧道"转发"给远程主机使用。这个过程是会话级的,数据仍在本地,因此其他用户无法获取。
3. 终端命令与操作
- 位置:远程 Linux 主机。所有命令都在远程主机上执行,效果和我们直接 SSH 上去操作完全一样。
- 可见性:部分可见。当我们执行命令时,可能会在系统中留下痕迹,因此共用同一账号的其他用户可以看到:
- 我们运行过的进程(如
ps aux | grep python)。 - 我们修改过的文件。
- 我们的命令行历史记录(如
.bash_history文件)。
- 我们运行过的进程(如
4. 代码文件与工作区插件
- 位置:远程 Linux 主机。
- 可见性:完全可见。如果我和他人共用同一个系统用户(例如
ubuntu_user1),那么我们在同一个"家目录"下工作。因此,我们能互相看到对方创建和修改的代码文件,以及安装在远程主机上的工作区插件(如 Python、Go 插件)。
我们在本地 VS Code 界面上看到的每一个字符、每一行代码、每一个终端输出,都是通过 SSH 隧道从远程主机实时传输回来的。
举几个简单的应用场景就能够明白了
🖥️ 场景1:编写代码和浏览文件
- 打开文件:当我们在侧边栏点击一个文件时,本地 VS Code 会通过 SSH 请求远程主机上的
VS Code Server:"请把/home/user/project/main.py的内容发给我。"远程 Server 读取文件后,将文本内容通过 SSH 连接发送给我们的本地 VS Code,本地编辑器再把它渲染在屏幕上。 - 编辑代码:我们每敲一个字符,本地 VS Code 都会立刻将这个变化通过 SSH 通知给远程 Server:"在
main.py的第 10 行第 5 列插入字符 'a'。"但注意,文件真正的保存和修改操作,是延迟或批量进行的。通常,只有当我们手动保存文件(Ctrl+S)或自动保存触发时,本地 VS Code 才会将修改后的整个文件内容发送给远程 Server,由 Server 写入磁盘。 - 代码补全(IntelliSense):当我们输入代码时,本地 VS Code 会请求远程 Server 进行代码分析。远程 Server 运行着 Python 语言服务器,它分析完远程主机上的项目环境和文件后,把补全建议列表通过 SSH 返回给本地 VS Code,本地 UI 再显示下拉框。
📺 场景2:查看终端输出
- 执行
ls命令:我们在本地 VS Code 的集成终端里输入ls并回车。 - 命令传输:这个输入事件被本地 VS Code 捕获,并通过 SSH 隧道发送给远程 Server:"在远程的伪终端(PTY)上执行
ls命令。" - 远程执行:远程 Server 收到指令后,在远程主机上启动一个 shell 进程,执行
ls,并捕获命令的标准输出和错误输出。 - 输出返回:远程 Server 将命令的每一行输出(比如
file1.txt file2.py)通过 SSH 流式地推送回本地 VS Code。 - 本地渲染:本地 VS Code 接收到这些文本数据后,在集成终端的面板里显示出来。我们在本地终端里看到的每一个字符,都是来自远程主机的实时输出。
💻 场景3:在 UI 中查看结果文件
这个场景其实和"打开文件"是同一个原理。
- 生成新文件:假设我们运行了一个 Python 脚本,它在远程主机上生成了一个
output.png图片文件。 - 在文件资源管理器中显示:当我们在 VS Code 的侧边栏文件浏览器中看到这个新文件时,实际上是本地 VS Code 定期向远程 Server 请求"文件列表"更新,远程 Server 返回了包含
output.png的列表,本地 UI 再刷新显示。 - 预览图片:如果我们想双击预览
output.png,本地 VS Code 会通过 SSH 请求远程 Server 读取这个文件的内容,远程 Server 将文件的二进制数据发送回来,本地 VS Code 再在自己的图片预览器中渲染出来。
🧠 一个更生动的类比
把 VS Code Remote-SSH 想象成一个网速极快、延迟极低的远程桌面软件,但它只传输文本内容和元数据,而不是传输整个屏幕的像素画面。
- 传统远程桌面:传输的是压缩后的图像数据,带宽消耗大。
- VS Code Remote-SSH:传输的是"请在第 10 行插入 'hello'"这样的编辑指令和"这是文件内容"这样的文本数据。这使得体验非常流畅,几乎感觉不到是在远程工作。
再说回插件(本地UI还是远程工作区)
关键在于,VS Code 的 Remote-SSH 不仅分流了 UI 和文件操作,也分流了插件。插件分为两类,运行在完全不同的地方:
- UI 插件 (UI Extensions):负责界面美化、快捷键、代码片段等,运行在本地。Copilot Chat 就属于这一类。
- 工作区插件 (Workspace Extensions):负责代码智能提示、语法检查、调试等,运行在远程主机上。Python、Go 语言插件就属于这一类。
当我们在 Remote-SSH 窗口打开扩展商店安装插件时,VS Code 会根据插件的性质,自动把它安装到正确的地方:本地或远程。
🔄 场景对比:小白(模拟小白🤣)的理解 vs. 正确姿势
| 场景 | 小白的理解(部分有误) | 正确姿势 |
|---|---|---|
| 代码补全 | 代码被拉回本地,由本地插件分析。 | 远程主机上的 Python 插件直接在主机上分析代码,并只把补全建议列表传回本地。 |
| 语法错误检查 | 代码被拉回本地,由本地插件检查。 | 远程主机上的 Linter 插件直接在主机上检查代码,并只把波浪线和错误信息传回本地。 |
| 代码格式化 | 代码被拉回本地,由本地插件格式化。 | 远程主机上的 Formatter 插件直接在主机上修改代码,并只把修改结果(增量)同步回本地。 |
| Copilot Chat 对话 | 远程代码被拉回本地,由本地 Copilot 分析。 | 理解正确! 本地 Copilot 会通过 SSH 通道读取远程代码作为"上下文",然后由本地的 AI 引擎生成回答。 |
| 使用 Copilot Agent | 本地 Agent 生成代码,然后 SSH 同步到远程。 | 理解正确! 本地 Agent 生成代码内容,然后通过 VS Code 的文件写入 API 将内容同步到远程主机。 |
🧩 以"代码补全"和"Copilot Agent"为例
1. 当我们使用代码补全(如输入 pr 触发 print())
这是一个工作区插件的典型场景,数据并没有离开远程主机。
- 输入事件:我们在本地按下
p,r。这个事件通过 SSH 发送给远程的 VS Code Server。 - 远程分析:VS Code Server 将指令转给同样运行在远程的 Python 插件。
- 远程计算:Python 插件读取远程文件,分析代码上下文,计算出补全建议列表。
- 结果返回:Python 插件把补全建议列表(不是整个文件)通过 SSH 发回给本地 VS Code。
- UI 渲染:本地 VS Code 收到列表,渲染出下拉菜单供我们选择。
2. 当我们使用 Copilot Agent 修改代码
这是一个 UI 插件的典型场景,但它的工作方式和我们想象的可能略有不同。
- 提供上下文:我们在本地 Copilot Chat 里说:"给这个函数写个注释"。
- 获取上下文:本地 Copilot 为了理解"这个函数",会通过 SSH 通道向远程 VS Code Server 请求读取当前文件的内容。
- AI 生成:本地 Copilot 拿到代码内容后,结合我们的指令也就是prompt,由本地的 AI 引擎生成带有注释的新代码。
- 远程写入:当 Copilot 要应用修改时,它并不是直接把文本
scp到服务器上,而是通过 VS Code 提供的 编辑器 API,将修改指令("在第10行替换为...")发给远程 VS Code Server,由 Server 来执行文件写入操作。 - UI 更新:远程 Server 写入文件后,会通知本地 VS Code,本地编辑器再更新显示。
🧠 如果强制改变插件的"归属地"会怎样?
我没有实际调查过,但是应该存在某种方式设置强制改变插件的运行位置。比如,如果强制将 Copilot Chat 变为工作区插件(在远程运行),或者将 Python 插件变为 UI 插件(在本地运行),会发生什么?
- 强制 Python 插件在本地运行:会导致插件功能完全失效,因为它无法访问远程主机的 Python 环境和文件(而我本地电脑有没有安装python解释器、创建特定python环境),IntelliSense 会消失。
- 强制 Copilot Chat 在远程运行:我们可能会遇到无法登录或无法联网的问题,因为内网的远程服务器可能无法访问 GitHub 服务(当然我们可以设置代理proxy)。这正是很多人试图强制 Copilot 在本地运行的原因。
- 强制 Copilot Chat 在本地运行(最常见情况):这就是我们当前的默认状态。如上所述,功能虽然正常,但它眼中的"工作区"是本地,因此需要通过 SSH 获取代码上下文。
总的来说,Copilot Chat 作为 UI 插件运行在本地,它需要通过 SSH 读取远程代码作为上下文。
参考:https://github.com/orgs/community/discussions/129888



我们回到我们的windows目录

下面这些hash串文件夹(注意是查看字母+数字混合的hash字符串文件夹,那些纯数字的文件夹不是),就是对应每一个工作区。

比如说我打开今天(写这篇博客时是2026年4月20日)

然后打开是项目路径

之前并没有单独一个项目路径的习惯,所以这个信息用处不大,不过我们可以知道这个项目是remote ssh,也就是远程的。
然后打开我们的chatsession文件夹

可以看到,里面有很多json、jsonl文件

然后今天的有两个

1个是在聊天框中,还没有输入的,另外一个是今天改动过的(旧的聊天窗口),文件比较大,100MB左右

python
ls -lht | head # 最近的在最上面
find . -maxdepth 1 -newermt "2024-01-01" ! -newermt "2024-02-01" -ls # 想找 2024-01-01 到 2024-02-01 之间的文件
存储Copilot 聊天记录的一些方法
既然我们已经知道了copilot聊天历史记录的存储位置,那么接下来我们就可以想办法存储这些历史对话记录了。
这里我需要提一嘴:
当我们在某个本地电脑面前的时候,注意我们能够同时访问vscode中的workspace聊天窗口,以及本地聊天记录的chat session缓存位置
1,直接右键copy
打开某个聊天session窗口,然后直接右键

- copy:鼠标光标当前对话(答复内容)的copy,注意只有当前对话答复,没有问题的copy

- copy all:当前所有对话(即整个chat session)的copy,问答都有


注意,以上copy结果都是Markdown格式内容。
至于存成什么都可以,是markdown还是html渲染
python
<style>
* { font-family: vazirmatn, vazir; direction:rtl; }
blockquote { background: #0084ff; color: #ffffff; padding: 10px 14px; margin: 8px 0 8px auto; border-radius: 14px; max-width: 75%; line-height: 1.5; word-wrap: break-word; }
blockquote p { border: none !important; font-style: normal !important; }ont-style: normal !important; }
</style>

2,通过 Ctrl+Shift+P | Chat
参考:https://github.com/orgs/community/discussions/57190

通过 Ctrl+Shift+P | Chat: Export Session... 将 Visual Studio Code 中的 Copilot Chat 会话导出到 JSON 文件

⚠️ 需要注意的一点是:当然聊天会话历史打开的是哪一个chat session,
那么export 导出的就是哪一个chat session的json对话记录。
(所以,这里我们需要手动点击进入不同chat session聊天窗口,然后在export保存到本地)

记得命名成不同的记录,而且这个json文件一般都很大,几百MB这种。

然后json格式的话,其实可以进一步python处理,把格式搞好看一点,最好是提取出完整的信息之类,
上面issue中开发者提供的一个示例脚本如下:
https://github.com/Marijn-Bergman/copilot-chat-export-formatter
当然,写这个其实难度不是很大,我们自己也可以借助AI写1个json转换为格式漂亮的txt、markdown文件的代码

python
import json
def format_chat_log(chat_log):
formatted_chat_log = ""
turns = chat_log['providerState']['turns']
for turn in turns:
request_message = turn['request']['message']
response_message = turn['response']['message']
formatted_chat_log += f"request: {request_message}\nresponse: {response_message}\n\n"
return formatted_chat_log
# Path to the JSON file
file_path = 'chat.json'
# Path to the output text file (newly created)
output_file_path = 'formatted_chat_log.txt'
# Reading the JSON file
with open(file_path, 'r') as file:
raw_data = file.read()
# Finding the index where the relevant portion starts
start_index = raw_data.find('"providerId": "copilot"')
relevant_data = raw_data[start_index:]
# Parsing the relevant JSON data
chat_log = json.loads('{' + relevant_data)
# Formatting the chat log
formatted_chat_log = format_chat_log(chat_log)
# Creating and saving the formatted chat log to a new text file
with open(output_file_path, 'w') as file:
file.write(formatted_chat_log)


3,一些三方工具
参考:https://github.com/orgs/community/discussions/57190

能够自动保存,还有一些插件等
4,但是?
前面提到的1、2、3等方法,基本上都是我们自己手动提取出聊天记录,
我们可以手动将这些文件转移到其他设备中,比如说跨设备windows。
当然,我之前操作的时候,习惯于提取出来之后都手动迁移到远程服务器中,毕竟本地机器一直在换,
但是我远程的机器没有变,可以一直访问,正好存哪里然后从哪里导入。
另外,前面的1、2、3方法,更多讲的是,我在本机前,手动保存session中的对话内容,然后手动迁移。
但是,问题在于,session中的对话聊天记录非常容易混淆。
我们可能今天在窗口A,后天在窗口B,然后几天之后就不知道每一个窗口里面的内容的版本如何了,也就是没有一个版本控制自动实现,我们当然不能寄希望于每个人的chat习惯都是从始而终,也不可能寄希望于一个人的记忆有多么强大。

所以,我们更常见的需求应该是:直接定位到windows本地缓存目录,然后直接定位修改日期最前面的chat session历史记录,
想办法如何将这个文件一直同步到多台设备中,比如说同步到Linux主机中。
如何直接本地聊天历史文件导入本机chat session:手动?
1个简单粗暴的解决方法就是,如何直接将本地的聊天历史记录文件夹导入import 到chat session中。
这里指的不是原生的本机聊天历史文件,因为机器A的原生本地文件导入到机器A的vscode终端copilot中没有这个必要,一般这个场景指的是获取了机器B的本地聊天文件,然后同步到机器A中,如何导入到机器A(假如我现在在机器A面前coding)的终端copilot中。
参考:https://github.com/orgs/community/discussions/129888

基本上还是手动更新(需要提前复制或者是同步这些在机器A上的session文件夹,到机器B上)


所以,如果能够解决同步、复制之后的导入问题,那么我们目前最大的问题就是如何轻松地同步、复制。
- 我们当然可以将不同windows电脑(或者主机)上的聊天历史记录同步到同1个存储地址中,比如说都同步到1个github私人仓库中。但是这个方法几乎不可行,因为1个chat session已经超过了单次上传的25MB限制,如果用LFS未评估。所以git作为中心存储不可行。
- 使用其他的同步工具,通过云服务(如 OneDrive、Dropbox)或同步工具(如 Syncthing),将本地的 workspaceStorage 文件夹在几台 Windows 电脑之间进行同步。比如说找到 Windows 电脑上的 workspaceStorage 文件夹路径:%APPDATA%\Code\User\workspaceStorage。将这个文件夹设置为云端同步盘(如 OneDrive)的同步目录,或使用 Syncthing 等工具在多台设备间设置同步。
能否自动保存本机chat session?
最方便的方法就是,能否直接保存本机的聊天历史,当然我说的不是windows缓存目录那种,我希望是能够格式友好、并且最好是能够指定保存地址(比如说是远程主机,因为主机是跨设备互联的,但是各个私人设备其实是不互通的)。
参考:https://github.com/microsoft/vscode-copilot-release/issues/14118
1个工具待讨论:SpecStory