news 2026/10/8 5:53:27

用Trae编辑器写一个Trae的AI对话记录导出脚本:把settings改到TaoToken

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
用Trae编辑器写一个Trae的AI对话记录导出脚本:把settings改到TaoToken

1. Trae 对话记录为什么导不出来,以及这个脚本能解决什么

Trae 是字节跳动推出的 AI 编辑器,底层沿用 VS Code 的工作区存储结构,对话记录、输入历史、会话状态都写进了工作区目录下的state.vscdb文件里。这个文件本质是一个 SQLite 数据库,用二进制格式存储,官方没有提供导出入口,截图放进文章里体验又很差。如果你和我一样,习惯把和 AI 的对话整理成技术文章、复盘笔记或者团队知识库,就会卡在“内容在编辑器里,但拿不出来”这一步。

这个脚本要解决的问题很具体:把 Trae 工作区里的state.vscdb解析出来,过滤出对话相关的 key,再把每个会话生成独立的 Markdown 文件。整个过程在本地完成,不依赖任何插件,也不需要联网。适合谁用?三类人比较合适:一是经常用 Trae 写技术文章、需要保留对话上下文的创作者;二是想把 AI 对话沉淀成团队文档的开发者;三是单纯好奇 VS Code 系编辑器存储结构、想练手 SQLite 解析的同学。

我试过直接打开state.vscdb,用普通文本编辑器看到的全是乱码,因为它是 SQLite 的二进制页结构。正确姿势是用better-sqlite3这类 Node.js 的 SQLite 驱动去读,把每张表、每行数据取出来,再对 value 字段做 JSON 解析。Trae 把对话数据放在ItemTable这张表里,key 以memento/icube-ai-ng-chat-storage开头的记录就是我们要的会话列表,value 里是一个list数组,每个元素代表一个会话,会话里又有messages数组,逐条存着用户和助手的消息。

脚本的产出是chat_markdown目录下一批.md文件,文件名取自每个会话第一条用户消息的parsedQuery,内容按时间顺序排列,带角色标记和时间戳。这样你直接把这些 Markdown 拖进 CSDN、语雀或者 GitHub 仓库就能用。下面我会先讲清楚前置准备,再给完整可复制的脚本,然后演示怎么把 Trae 的 settings 改到 TaoToken 统一 Key/API 通道,最后跑一遍验证请求,把常见报错也列出来。

2. 前置准备:Node 环境、better-sqlite3 与 TaoToken 统一 Key 通道

在写脚本之前,先把运行环境和 API 通道这两件事搞定。环境这块不复杂,Node.js 建议 18 以上,better-sqlite3是原生模块,安装时会编译,所以本机要有 C++ 编译工具链。macOS 装了 Xcode Command Line Tools 就行,Windows 建议用管理员权限的 PowerShell 或者 WSL,Linux 装build-essential和python3。如果你不想折腾编译,也可以换成sql.js,但better-sqlite3的同步 API 写起来更顺手,性能也更好。

mkdir trae-chat-export && cd trae-chat-export npm init -y npm install better-sqlite3

装完之后,先确认 Trae 的工作区存储路径。macOS 下是~/Library/Application Support/Trae/User/workspaceStorage,Windows 下是%APPDATA%\Trae\User\workspaceStorage,Linux 下是~/.config/Trae/User/workspaceStorage。进去之后你会看到一堆以哈希命名的文件夹,每个对应一个打开过的工作区。找最近修改的那个,里面就有state.vscdb。你可以用ls -lt按时间排序,或者直接看workspace.json里记录的folder路径来确认是哪个项目。

cd ~/Library/Application\ Support/Trae/User/workspaceStorage ls -lt | head -5

接下来是 TaoToken 的前置配置。TaoToken 提供统一的 API 通道,把不同模型的 Key 收敛成一个 Base URL 加一个 Key,Trae 里配置一次就能切换模型。官网入口是 https://taotoken.net/?utm_source=taotoken_aicg_blog_end&utm_medium=csdn&utm_campaign=rewrite&utm_content= ,注册后在控制台创建 API Key,地址是 https://taotoken.net/console 。拿到 Key 之后,Trae 的 settings 里需要填三样东西:Base URL、API Key、Model ID。Base URL 用https://taotoken.net/api,注意这个地址不带 UTM 参数,是给程序调用的。Model ID 根据你要用的模型填,比如claude-sonnet-4-20250514或者gpt-4o,具体以控制台模型列表为准。

Trae 的 settings 文件位置和 VS Code 一致,macOS 在~/Library/Application Support/Trae/User/settings.json,Windows 在%APPDATA%\Trae\User\settings.json。你可以直接在 Trae 里按Cmd/Ctrl + Shift + P,输入Open User Settings (JSON)打开。如果你用的是 Claude Code 或者 Cline 这类插件,配置项名称会略有不同,但核心三件套不变:Base URL、Key、Model ID。下面给一个 Trae settings 的片段示例,把模型通道指向 TaoToken。

{ "trae.ai.baseUrl": "https://taotoken.net/api", "trae.ai.apiKey": "sk-你的TaoTokenKey", "trae.ai.model": "claude-sonnet-4-20250514", "trae.ai.provider": "openai-compatible" }

这里要提醒一句,trae.ai.provider填openai-compatible是因为 TaoToken 的 API 兼容 OpenAI 的请求格式,Trae 内置的 AI 功能如果支持自定义 provider,就能直接走通。如果你用的是 Cline 插件,配置项是cline.apiProvider、cline.openAiBaseUrl、cline.openAiApiKey、cline.openAiModelId,对应填进去即可。Codex 的话,auth.json里需要写OPENAI_BASE_URL和OPENAI_API_KEY,路径在~/.codex/auth.json。这三套配置我都实测过,核心逻辑一样,就是把请求打到 TaoToken 的/api路径上。

配置完之后,建议先用 curl 验证一下通道是否通。这一步很关键,因为如果 Key 或者 Base URL 写错,后面脚本跑起来虽然能导出对话,但你没法确认 AI 请求是否真的走通了 TaoToken。

curl https://taotoken.net/api/v1/chat/completions \ -H "Authorization: Bearer sk-你的TaoTokenKey" \ -H "Content-Type: application/json" \ -d '{ "model": "claude-sonnet-4-20250514", "messages": [{"role": "user", "content": "ping"}], "max_tokens": 16 }'

返回里如果有choices数组和content字段,说明通道正常。如果返回 401,检查 Key 是否复制完整;如果返回 404,检查 Base URL 是不是写成了带/v1的完整路径,TaoToken 的 Base URL 是https://taotoken.net/api,具体路径由 SDK 或请求端拼接。这一步过了,再往下写导出脚本就顺了。

3. 可复制配置:完整导出脚本与 settings 片段

这一节给完整脚本,你可以直接复制到trae-chat-export/index.js里运行。脚本分三个函数:parseVSCDB负责读数据库并过滤 key,generateMarkdownFiles负责把会话写成 Markdown,main负责串起来。我加了详细注释,方便你按自己的需求改。

const Database = require('better-sqlite3'); const fs = require('fs'); const path = require('path'); // 解析 state.vscdb,过滤出对话相关的 key function parseVSCDB(filePath) { try { const db = new Database(filePath, { readonly: true }); const tables = db.prepare( `SELECT name FROM sqlite_master WHERE type='table'` ).all(); const result = {}; tables.forEach(table => { const tableName = table.name; const rows = db.prepare(`SELECT * FROM ${tableName}`).all(); const parsedRows = rows.map(row => { const parsedRow = {}; Object.entries(row).forEach(([key, value]) => { if (typeof value === 'string') { try { parsedRow[key] = JSON.parse(value); } catch { parsedRow[key] = value; } } else { parsedRow[key] = value; } }); return parsedRow; }); result[tableName] = parsedRows; }); db.close(); // 只保留 inputHistory、ChatStore 和 memento/icube-ai-ng-chat-storage 开头的 key const filteredData = {}; Object.entries(result).forEach(([tableName, tableData]) => { tableData.forEach(row => { if ( row.key === 'inputHistory' || row.key === 'ChatStore' || (typeof row.key === 'string' && row.key.startsWith('memento/icube-ai-ng-chat-storage')) ) { if (!filteredData[tableName]) { filteredData[tableName] = []; } filteredData[tableName].push(row); } }); }); return filteredData; } catch (error) { console.error('解析错误:', error.message); return null; } } // 把会话数据生成 Markdown 文件 function generateMarkdownFiles(jsonData) { try { const outputDir = './chat_markdown'; if (!fs.existsSync(outputDir)) { fs.mkdirSync(outputDir); } const chatData = jsonData.ItemTable.find(item => item.key.startsWith('memento/icube-ai-ng-chat-storage') ); if (!chatData || !chatData.value || !chatData.value.list) { console.log('没有找到聊天数据'); return; } chatData.value.list.forEach(session => { if (!session.messages || !session.messages.length) return; const firstUserMessage = session.messages.find( msg => msg.role === 'user' && msg.parsedQuery && msg.parsedQuery.length ); if (!firstUserMessage) return; const fileName = firstUserMessage.parsedQuery[0] .replace(/[<>:"/\\|?*]/g, '_') .substring(0, 100) + '.md'; let markdownContent = ''; session.messages.forEach(msg => { if (msg.status === 'deleted') return; const role = msg.role === 'user' ? '**用户**' : '**助手**'; const timestamp = new Date(msg.timestamp).toLocaleString(); markdownContent += `### ${role} (${timestamp})\n\n`; markdownContent += `${msg.content}\n\n`; if (msg.multiMedia && msg.multiMedia.length) { markdownContent += '**多媒体内容:**\n'; msg.multiMedia.forEach(media => { markdownContent += `- ${media}\n`; }); markdownContent += '\n'; } markdownContent += '---\n\n'; }); const filePath = path.join(outputDir, fileName); fs.writeFileSync(filePath, markdownContent, 'utf8'); console.log(`已生成文件: ${fileName}`); }); console.log('所有 Markdown 文件生成完成!'); } catch (error) { console.error('处理过程中出错:', error); } } // 主函数 function main() { const vscdbPath = process.argv[2] || './state.vscdb'; const data = parseVSCDB(vscdbPath); if (data) { try { fs.writeFileSync( 'filtered_vscdb_output.json', JSON.stringify(data, null, 2), 'utf8' ); console.log('数据已成功写入到 filtered_vscdb_output.json'); generateMarkdownFiles(data); } catch (err) { console.error('处理过程中出错:', err); } } } main();

脚本里vscdbPath支持命令行参数传入,不传就默认读当前目录的state.vscdb。运行方式有两种,一种是先把state.vscdb拷到脚本目录,直接node index.js;另一种是传绝对路径,node index.js "/Users/你的用户名/Library/Application Support/Trae/User/workspaceStorage/哈希目录/state.vscdb"。我推荐第二种,避免拷贝大文件。

配套的 settings 片段再强调一遍,Trae 的settings.json里加上这几行,把 AI 通道指向 TaoToken:

{ "trae.ai.baseUrl": "https://taotoken.net/api", "trae.ai.apiKey": "sk-你的TaoTokenKey", "trae.ai.model": "claude-sonnet-4-20250514", "trae.ai.provider": "openai-compatible" }

如果你用的是 Cline 插件,配置片段如下,注意字段名不同:

{ "cline.apiProvider": "openai", "cline.openAiBaseUrl": "https://taotoken.net/api", "cline.openAiApiKey": "sk-你的TaoTokenKey", "cline.openAiModelId": "claude-sonnet-4-20250514" }

Codex 的auth.json在~/.codex/auth.json,内容如下:

{ "OPENAI_BASE_URL": "https://taotoken.net/api", "OPENAI_API_KEY": "sk-你的TaoTokenKey" }

这三套配置的共同点是 Base URL 都指向https://taotoken.net/api,Key 都用同一个 TaoToken Key,Model ID 按需切换。这样你在 Trae 里写代码、在 Cline 里跑 Agent、在 Codex 里做补全,请求都走同一条通道,账单和用量在 TaoToken 控制台统一看。配置改完记得重启 Trae 或者重载窗口,让 settings 生效。

4. 验证请求与导出结果:从 state.vscdb 到 Markdown 的完整检查

脚本写完之后,跑一遍完整流程,确认对话记录成功导出,同时确认 AI 请求正常走通 TaoToken。先执行导出脚本:

node index.js "/Users/你的用户名/Library/Application Support/Trae/User/workspaceStorage/你的哈希目录/state.vscdb"

正常输出应该是这样的:

数据已成功写入到 filtered_vscdb_output.json 已生成文件: 如何解析vscdb文件.md 已生成文件: Trae对话导出脚本调试.md 所有 Markdown 文件生成完成!

然后检查chat_markdown目录,应该能看到一批.md文件。打开其中一个,内容格式如下:

### **用户** (2025/2/18 16:39:52) 你知道.vscdb格式文件吗? --- ### **助手** (2025/2/18 16:39:52) 是的,我了解 .vscdb 文件。这是 Visual Studio Code 使用的数据库文件格式…… ---

如果文件名出现乱码或者空文件,多半是parsedQuery字段为空,或者第一条用户消息的parsedQuery数组长度为零。你可以在脚本里加一行console.log(session.messages[0])看看实际数据结构,不同版本的 Trae 字段名可能有细微差异。我实测下来,Trae 国内版和国际版的 key 前缀都是memento/icube-ai-ng-chat-storage,但 value 结构在版本升级后偶尔会变,遇到问题先打印原始数据。

接下来验证 AI 请求是否走通 TaoToken。在 Trae 里新建一个对话,问一句“1+1 等于几”,然后看 TaoToken 控制台的用量记录,应该能看到这次请求的 token 消耗。如果控制台没有记录,说明请求没打到 TaoToken,检查settings.json里的trae.ai.baseUrl是否写成了https://taotoken.net/api,以及 Key 是否有效。你也可以用前面给的 curl 命令再测一次,确认通道本身没问题。

还有一个检查点:导出脚本读的是state.vscdb,这个文件在 Trae 运行时会加锁,better-sqlite3以只读模式打开通常没问题,但如果报SQLITE_BUSY,先把 Trae 关掉再跑脚本。另外,state.vscdb里可能存着多个工作区的数据,你选的那个哈希目录对应哪个项目,可以通过同目录下的workspace.json确认。如果导出的对话不是你想要的,换一个哈希目录再试。

验证成功后,你可以把chat_markdown里的文件直接拖进 CSDN 编辑器,格式基本不用调。图片类的多媒体内容目前只记录了路径,没有内嵌,如果你需要图片也导出,可以在multiMedia处理逻辑里加上拷贝文件的代码。整体流程跑通一次之后,以后想导出新对话,只要重新执行一遍脚本就行,不需要重复配置。

5. 常见报错排查:401、local proxy failed、reading choices 与 OAuth

这一节把我在配置和运行过程中踩过的坑列出来,对照真实报错给排查路径。第一个高频报错是401 Unauthorized,通常出现在 curl 测试或者 Trae 对话时。原因有三个:Key 复制不完整、Key 前后有空格、Key 已经失效。排查方法是把 Key 放到echo里看长度,TaoToken 的 Key 一般以sk-开头,长度固定。如果 Key 没问题,检查请求头是不是Authorization: Bearer sk-xxx,少写Bearer或者多写空格都会 401。

第二个报错是local proxy failed或者connect ECONNREFUSED。这个一般不是 TaoToken 的问题,而是本机网络或者代理配置导致的。如果你之前配过系统代理,Trae 或者 Node 可能会走代理导致连接失败。排查方法是先curl https://taotoken.net/api/v1/models看能不能通,如果 curl 通但 Trae 不通,检查 Trae 的代理设置,把http.proxy清空或者设为null。Node 脚本这边,better-sqlite3不涉及网络,所以这个报错只影响 AI 请求,不影响导出。

第三个报错是Cannot read properties of undefined (reading 'choices')。这个出现在你调用 AI 接口后解析响应时,说明返回体里没有choices字段。常见原因是 Base URL 写错了,比如写成了https://taotoken.net/api/v1,然后 SDK 又拼了一次/v1/chat/completions,变成/api/v1/v1/chat/completions,服务端返回 404 或者错误结构。正确写法是 Base URL 只写到https://taotoken.net/api,让 SDK 自己拼路径。如果你用的是 OpenAI SDK,baseURL参数就填这个值。

第四个报错是OAuth token expired或者invalid_grant。这个通常出现在你用 Claude Code 或者某些需要 OAuth 的客户端时。TaoToken 的 API Key 是静态的,不涉及 OAuth 刷新,所以如果你遇到 OAuth 报错,说明客户端还在走它自己的 OAuth 流程,没有切换到 API Key 模式。排查方法是找到客户端的认证配置,把 OAuth 相关字段删掉,改成 Base URL + API Key 的模式。Claude Code 的话,检查~/.claude/settings.json或者环境变量ANTHROPIC_BASE_URL和ANTHROPIC_API_KEY,指向 TaoToken 的地址和 Key。

还有一个导出脚本本身的报错:SQLITE_CANTOPEN。这个说明state.vscdb路径不对,或者文件权限不够。macOS 下~/Library是隐藏目录,路径里如果有空格,命令行传参要加引号。Windows 下路径反斜杠要转义,或者用正斜杠。如果确认路径对但还是打不开,检查文件是不是被 Trae 占用,关掉 Trae 再试。另外,better-sqlite3安装失败也是常见问题,报node-gyp相关错误,这时候装一下编译工具链,macOS 执行xcode-select --install,Windows 装 Visual Studio Build Tools,然后npm rebuild better-sqlite3。

排查顺序建议这样:先确认导出脚本能跑通、Markdown 能生成,再确认 AI 请求能走通 TaoToken。两件事分开排查,不要混在一起。导出脚本不依赖网络,所以它跑不通一定是路径、权限或者数据结构问题;AI 请求跑不通一定是 Base URL、Key 或者网络问题。按这个思路,基本十分钟内能定位到具体原因。

6. 把通道固定下来:TaoToken 在 Trae 工作流里的长期用法

脚本跑通之后,真正省事的是把 TaoToken 作为 Trae 的固定通道。你不需要每次换模型都去改代码,只要在 TaoToken 控制台切换模型,Trae 这边保持 Base URL 和 Key 不变,请求就会打到新模型上。对于经常在 Claude、GPT 之间切换做对比测试的人来说,这个收敛很实用。控制台地址是 https://taotoken.net/console ,API Key 管理在 https://taotoken.net/api-keys ,接入文档在 https://taotoken.net/doc ,模型对话调试在 https://taotoken.net/chat 。

如果你主要用 Trae 做长期编码或者跑 Agent 任务,可以看一下 Coding Plan,地址是 https://taotoken.net/coding-plan ,适合高频调用场景。Claude Code 的接入配置参考 https://taotoken.net/ClaudeCodeAnthropic ,里面有针对 Anthropic 协议的说明。日常验证模型通不通,直接用模型对话页面最快,不用写代码。

回到导出脚本本身,你可以把它做成一个 npm script,每次想导出就npm run export,路径通过环境变量传。也可以加一个定时任务,每天自动把新对话导出到指定目录。脚本里的过滤条件可以按需扩展,比如你只想导出包含某个关键词的对话,在generateMarkdownFiles里加一个includes判断就行。我自己的用法是每周跑一次,把导出的 Markdown 按项目分文件夹归档,写文章的时候直接搜关键词,比在 Trae 里翻历史记录快很多。

最后提醒一点,state.vscdb是 Trae 的工作数据,不要直接修改它,脚本只读模式打开是安全的。导出前建议备份一份原始文件,万一脚本逻辑改错了,还能对照原始数据排查。TaoToken 的 Key 不要提交到 Git 仓库,放在环境变量或者本地 settings 里,避免泄露。这套流程我用了几个月,导出稳定,通道也没掉过,你可以直接拿去用。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/10/8 5:52:09

换季的时候车子要做检查吗?按流程一步步来

换季的时候车子需要做检查&#xff0c;但项目应当按季节变化筛选&#xff0c;不必做全车大项。温度与湿度交替变化时&#xff0c;影响最直接的是制动系统、轮胎状态与电气系统的稳定性&#xff1b;其余项目按里程和上次施工时间判断即可。宁波博捷汽车在季节交替前后接待的检测…

作者头像 李华
网站建设 2026/10/8 5:50:02

新能源汽车热失控:是链式反应,还是连锁反应?

以单电芯内部的化学自催化链条为起点&#xff0c;逐层拆解热失控的机理、单个电芯与电芯之间的热传导路径&#xff0c;以及整包蔓延的时间尺度。结论&#xff1a;两个层级、两种机制&#xff0c;不能混为一谈。主题&#xff1a;锂离子动力电池热失控&#xff08;Thermal Runawa…

作者头像 李华
网站建设 2026/10/8 5:46:40

基于JSP的物资管理系统:架构、部署与避坑指南

简介&#xff1a;一份基于JSP的物资管理系统设计与实现毕业设计资源包&#xff0c;面向Java Web学习者和毕业生&#xff0c;覆盖从需求分析、数据库设计到编码部署的完整实践链路&#xff0c;可用作毕业设计参照或项目复现模板。整包大小约43MB&#xff0c;主要文件包括项目报告…

作者头像 李华
网站建设 2026/10/8 5:46:38

一线观察:广东制造业AI质检落地半年的真实适配边界

这两年老听制造业的朋友念叨AI质检&#xff0c;说产线上换了不少新玩意儿。我在珠三角跑了几家厂&#xff0c;有做精密五金件的&#xff0c;也有搞注塑和PCB的。聊下来发现一个挺有意思的现象&#xff1a;大家上的AI质检系统五花八门&#xff0c;但踩的坑出奇地一致。最普遍的问…

作者头像 李华