news 2026/10/1 4:10:09

豆包智能体聊天记录批量导出实战:从抓包到本地备份的完整方案

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
豆包智能体聊天记录批量导出实战:从抓包到本地备份的完整方案

1. 为什么我要折腾聊天记录备份这件事

用了大半年豆包智能体,我陆陆续续攒了几十个对话窗口,有用来做知识库问答的,有专门跑文案润色的,还有几个是帮团队做客服话术训练的。直到上个月电脑主板挂了,重装系统之后打开豆包网页版,发现之前那些对话记录全没了——不是账号丢了,是本地缓存和部分会话上下文没同步上去。那一刻我才意识到,聊天数据备份这件事,不能指望平台自动帮你兜底。

后来我在几个技术群里问了一圈,发现遇到类似情况的人不少。有人是换了设备之后历史记录对不上,有人是想把某个智能体的优质回答整理成文档,还有人纯粹是想做批量导出方便做二次分析。但豆包官方目前并没有提供一个显眼的"一键导出全部对话"按钮,网页版只能一条条翻,客户端也没有批量操作入口。这就催生了一个很实际的需求:手动把聊天数据批量导出来,存成自己能掌控的格式。

这篇内容就是把我自己踩过的坑、试过的方案、以及最后跑通的一套流程完整记录下来。适合两类人看:一类是像我这样有几十上百个对话需要归档的普通用户,另一类是手里有多个智能体、想把对话数据拿去做训练语料或者分析的技术同学。整个过程不需要写复杂代码,但需要你对浏览器开发者工具和基本的文件操作有一点耐心。核心关键词就三个:豆包、智能体、批量导出,围绕它们把技术原理和操作步骤讲透。

2. 批量导出的底层逻辑:数据到底存在哪里

2.1 聊天记录的三种存在形态

在动手之前,得先搞清楚豆包的聊天数据到底以什么形式存在。我通过抓包和翻本地存储,梳理出来三种形态:

第一种是服务端会话记录。你每次发消息,请求会带着会话ID打到服务端,服务端把这一轮问答存进数据库。这部分数据你在网页版刷新之后还能看到,说明它是跟着账号走的。但问题是,服务端并没有开放一个"导出全部会话"的接口给普通用户,你只能通过会话列表逐个拉取。

第二种是浏览器本地缓存。网页版为了加快加载速度,会把最近打开的会话内容存在IndexedDB或者localStorage里。这部分数据的特点是读取快、结构清晰,但容量有限,而且清缓存就没了。我实测下来,网页版大概会缓存最近二三十个会话的完整消息体,更早的就需要重新请求。

第三种是客户端本地数据库。如果你用的是豆包电脑版客户端,它会在本地建一个SQLite数据库文件,把会话、消息、智能体配置都存进去。这个文件才是批量导出的"富矿",因为它是结构化的,一张表存会话,一张表存消息,字段清晰。但不同版本的客户端,数据库路径和表结构会有差异,需要你根据实际情况去定位。

提示:我下面讲的操作以网页版为主,因为网页版跨平台、不需要装客户端,通用性最强。客户端方案我会在第四节单独说,适合数据量特别大的情况。

2.2 为什么不能直接"复制粘贴"

有人可能会说,我直接打开每个对话,全选复制粘贴到Word里不就行了?我试过,十个对话以内还能忍,超过二十个就是纯体力活,而且复制出来的格式全乱,角色标识、时间戳、代码块全都混在一起。更麻烦的是,智能体的回答里经常有Markdown表格和代码块,粘贴到Word里直接变成一坨。

所以批量导出的核心诉求不是"能导出",而是"导出后还能用"。这就要求我们拿到的是结构化的数据,最好是JSON格式,每条消息带角色、时间、内容字段,这样后续无论是转成Markdown、导入知识库、还是做数据分析,都有得商量。

2.3 整体技术路线选型

我把可行的方案列了个表,对比一下各自的优劣:

方案原理优点缺点适合场景
浏览器开发者工具抓接口监听网络请求,拿到会话列表和消息接口数据最全,结构清晰需要手动翻页,接口可能变几十到上百个会话
本地存储读取从IndexedDB/localStorage提取缓存速度快,无需网络只有最近部分会话快速备份近期对话
客户端数据库导出直接读SQLite文件一次性拿全量需要定位文件,版本差异大数据量特别大
页面自动化脚本模拟点击逐条抓取不依赖接口慢,容易被限流接口不可用时兜底

我最终采用的是接口抓取为主、本地存储为辅的组合方案。原因很简单:接口返回的数据最完整,包含会话标题、创建时间、消息列表;本地存储可以作为补充,把接口没覆盖到的近期缓存捞回来。两者一合并,基本能做到不丢数据。

3. 动手前的环境准备与关键参数

3.1 你需要准备的东西

在开始之前,确认手头有这几样:

  • 一台能正常访问豆包网页版的电脑,Chrome或Edge浏览器都行,我用的Chrome 120以上版本。
  • 登录你的豆包账号,确保能看到完整的会话列表。
  • 一个用来存放导出文件的文件夹,建议单独建一个,比如doubao_backup。
  • 如果会话数量超过五十个,建议准备一个能处理JSON的工具,比如VS Code或者任何文本编辑器。

不需要装额外的软件,也不需要什么特殊权限。整个过程都在浏览器里完成。

3.2 关键参数:会话ID和分页机制

抓接口之前,得先理解两个关键参数。

会话ID(conversation_id):每个对话窗口都有一个唯一ID,通常是一串长字符串。你打开某个对话时,URL里或者请求参数里会带上它。批量导出的第一步,就是先把所有会话ID收集齐。

分页参数:会话列表接口一般不会一次性返回全部,而是分页的。常见的是offset和limit两个参数,limit控制每页返回多少条,offset控制从第几条开始。我实测下来,把limit设成50比较稳妥,太大容易超时,太小翻页次数多。

注意:不同时期豆包的接口参数名可能有变化,比如有的版本用page和page_size。你在抓包的时候以实际看到的为准,不要死记我这里的参数名。

3.3 打开开发者工具的正确姿势

按F12打开开发者工具,切到Network面板,勾选Preserve log(保留日志),这样页面跳转时请求记录不会被清空。然后刷新一下豆包页面,你会看到一堆请求刷过去。

这时候在筛选框里输入conversation或者message,把无关的请求过滤掉。我一般会先点开一个对话,观察发出去哪些请求,找到返回消息列表的那个。通常它的Response是一个JSON,里面有data字段,里面套着messages数组。

找到目标接口之后,右键选择Copy as cURL,把它存到一个文本文件里。这一步很关键,因为后面我们要用这个请求模板去批量拉取不同会话的数据。

4. 完整实操流程:从抓包到落地成文件

4.1 第一步:收集全部会话ID

打开豆包的会话列表页面,在Network面板里找到返回会话列表的那个接口。它的Response大概长这样:

{ "data": { "conversations": [ {"id": "conv_abc123", "title": "文案润色助手", "created_at": 1700000000}, {"id": "conv_def456", "title": "知识库问答", "created_at": 1700000100} ], "has_more": true } }

你要做的就是不断翻页,把每一页的conversations数组里的id字段提取出来,汇总成一个列表。手动翻页的话,改offset参数重新发请求就行。如果会话不多,翻个三五页就齐了。

我自己的做法是把这个接口的cURL复制出来,改一下offset,在终端里用curl循环跑,把结果存成一个个JSON文件。这样比在浏览器里点快得多。

# 示例:循环拉取会话列表,offset从0开始,每次加50 for offset in 0 50 100 150 200; do curl 'https://xxx/conversation/list?offset='$offset'&limit=50' \ -H 'cookie: 你的cookie' \ -o conv_list_$offset.json done

跑完之后,用一段简单的Python把所有的id抽出来去重:

import json, glob ids = set() for f in glob.glob('conv_list_*.json'): data = json.load(open(f)) for conv in data['data']['conversations']: ids.add(conv['id']) print(len(ids)) with open('conv_ids.txt', 'w') as fp: fp.write('\n'.join(ids))

这一步做完,你就有了一个纯文本的会话ID列表,一行一个。

4.2 第二步:批量拉取每个会话的消息

有了ID列表,接下来就是逐个拉消息。消息接口通常长这样:https://xxx/conversation/messages?conversation_id=xxx。同样用curl循环:

while read cid; do curl 'https://xxx/conversation/messages?conversation_id='$cid \ -H 'cookie: 你的cookie' \ -o messages_$cid.json sleep 1 done < conv_ids.txt

这里我加了个sleep 1,目的是控制请求频率。实测下来,如果不加延迟,连续请求几十次之后会触发限流,返回429。加一秒延迟基本能稳住,一百个会话也就两分钟的事。

提示:cookie是有有效期的,一般几个小时到几天不等。如果你中途发现请求返回401或者跳登录页,重新登录一下,把新的cookie换上去就行。

4.3 第三步:数据清洗与格式统一

拉下来的原始JSON结构可能不太一致,有的消息内容在content字段,有的在text字段,角色标识有的用role: "user",有的用is_user: true。所以需要做一层清洗,统一成下面这种格式:

{ "conversation_id": "conv_abc123", "title": "文案润色助手", "created_at": "2024-01-01T10:00:00", "messages": [ {"role": "user", "content": "帮我把这段话润色一下", "time": "2024-01-01T10:00:05"}, {"role": "assistant", "content": "好的,以下是润色后的版本...", "time": "2024-01-01T10:00:08"} ] }

清洗脚本用Python写,核心就是遍历每个messages_*.json,把字段映射到统一结构。我大概写了三十行代码就搞定了,关键是要处理一下空消息和异常字段,避免脚本中途崩掉。

import json, glob, os result = [] for f in glob.glob('messages_*.json'): try: raw = json.load(open(f, encoding='utf-8')) except Exception as e: print('skip', f, e) continue msgs = [] for m in raw.get('data', {}).get('messages', []): msgs.append({ 'role': 'user' if m.get('is_user') else 'assistant', 'content': m.get('content') or m.get('text') or '', 'time': m.get('created_at', '') }) result.append({ 'conversation_id': raw.get('data', {}).get('conversation_id', ''), 'title': raw.get('data', {}).get('title', ''), 'messages': msgs }) json.dump(result, open('doubao_backup.json', 'w', encoding='utf-8'), ensure_ascii=False, indent=2)

跑完之后你会得到一个doubao_backup.json,里面是所有会话的完整消息。这个文件就是你的"数据资产",后面想怎么用都行。

4.4 第四步:转成可读格式

JSON虽然结构化好,但直接看不太方便。我一般会再写个小脚本,把它转成Markdown,每个会话一个文件,标题作为文件名,消息按角色分段。这样用任何Markdown阅读器都能看,也方便导入到笔记软件里。

import json, re data = json.load(open('doubao_backup.json', encoding='utf-8')) for conv in data: title = re.sub(r'[\\/:*?"<>|]', '_', conv['title'] or conv['conversation_id']) with open(f'output/{title}.md', 'w', encoding='utf-8') as fp: fp.write(f"# {conv['title']}\n\n") for m in conv['messages']: prefix = '**我**' if m['role'] == 'user' else '**豆包**' fp.write(f"{prefix}:{m['content']}\n\n")

到这一步,整个批量导出流程就跑通了。从抓包到落地成Markdown,一百个会话大概花了我二十分钟,其中大部分时间是在等请求返回。

5. 常见问题与排查技巧实录

5.1 请求返回401或跳登录页

这是最常见的问题,九成是cookie过期了。解决办法很简单:重新登录豆包网页版,按F12打开开发者工具,在Network面板里随便找一个请求,把cookie请求头完整复制出来,替换掉脚本里的旧cookie。注意cookie里包含多个字段,要整段复制,不要只复制其中一部分。

如果换了新cookie还是401,检查一下请求头里有没有漏掉user-agent或者referer。有些接口会校验这两个字段,缺了就会被拒。

5.2 翻页翻到一半返回空列表

这种情况通常是offset设太大了,超出了实际会话总数。你可以在返回结果里看has_more字段,如果是false就说明到底了,不用再翻。另外有些版本的接口用cursor而不是offset,每次返回一个next_cursor,下次请求带上它就行。以实际抓到的为准。

5.3 消息内容出现乱码或截断

乱码一般是编码问题,确保你的脚本在读写文件时都指定了encoding='utf-8'。截断则可能是单条消息太长,接口做了长度限制。我遇到过一条智能体回答超过五千字被截成两段的情况,解决办法是把两段按时间顺序拼回去,或者直接保留原始JSON,不做截断处理。

5.4 请求频率过高被限流

前面提过,加sleep是最简单的办法。如果会话特别多,比如上千个,建议把sleep调到2到3秒,或者分批跑,跑一百个歇十分钟。别想着并发拉取,限流策略对并发更敏感,得不偿失。

5.5 客户端数据库找不到

如果你用的是电脑版客户端,数据库文件一般在安装目录下的data或者userdata文件夹里,文件名可能是chat.db或者message.sqlite。用SQLite工具打开之后,找conversation和message两张表。不同版本表名可能不一样,实在找不到就用关键词搜一下.db文件。找到之后导出成CSV,再转JSON,流程和网页版类似。

注意:操作客户端数据库之前先复制一份备份,别直接在原文件上改,万一搞坏了客户端就打不开了。

6. 几个让我少走弯路的实操心得

第一个心得是先小范围试跑。别一上来就把几百个会话全拉一遍,先拿三五个ID跑通整个流程,确认数据格式没问题、脚本没报错,再放量。我第一次就是贪快,结果脚本里一个字段名写错了,拉了两百个文件全是废的,白等半小时。

第二个心得是原始数据一定要留着。清洗后的JSON和Markdown是给人看的,但原始接口返回的JSON别删。万一后面发现某个字段清洗错了,还能从原始数据里重新提取。我专门建了个raw文件夹存原始文件,占不了多少空间。

第三个心得是定期备份比一次性导出更重要。我现在养成了习惯,每个月月初跑一次导出脚本,把新增的会话追加进去。这样即使某天账号出问题,最多也就丢一个月的记录。脚本可以做成增量式的,只拉created_at比上次备份时间新的会话,速度快很多。

第四个心得是注意智能体配置的备份。聊天记录只是数据的一部分,如果你自己搭建过智能体,它的提示词、知识库文件、参数配置同样重要。这些内容有的在会话里,有的在单独的配置接口里,导出的时候别漏了。我一般会把智能体配置单独存一个JSON,和聊天记录放一起。

最后说个细节:导出的Markdown文件如果会话标题有重复,会互相覆盖。我在脚本里加了个序号前缀,比如001_文案润色助手.md,这样就不会冲突了。小问题,但不注意的话会丢文件。

这套流程我跑了三个月,累计导出了四百多个会话,没出过什么大问题。核心就是理解数据在哪、怎么拿、怎么存这三件事。工具会变、接口会变,但思路是通用的。你要是也在用豆包智能体攒了一堆对话,不妨按这个路子试一次,跑通之后心里会踏实很多。

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

航电需求验证全解析:从验证确认到RTM构建与落地实践

做航电开发的工程师&#xff0c;应该都听过这个说法&#xff1a;“需求验证做不好的项目&#xff0c;最后验收一定很难看。”这话真不夸张。我在几个航电型号项目里轮过几轮&#xff0c;见得太多了&#xff1a;团队把需求验证等同于“最后写点测试用例跑一跑”&#xff0c;结果…

作者头像 李华
网站建设 2026/10/1 4:09:23

梦笔记:从梦境记录到自我观察与创造力挖掘的实用指南

1. 缘起&#xff1a;为什么会开始"梦笔记"这件事先说个实话。在开始梦笔记之前&#xff0c;我对于"记录梦境"这事的态度&#xff0c;一直停留在"记得住就记&#xff0c;记不住拉倒"的随缘状态。偶尔梦到一些特别离谱或者特别清晰的场景&#xff…

作者头像 李华
网站建设 2026/10/1 4:08:56

Java Web学生成绩管理系统:从架构拆解到部署跑通全流程

简介&#xff1a;基于Java的Web学生成绩管理系统压缩包是一份完整的课程设计/毕业设计参考项目&#xff0c;面向Java Web初学者及有成绩管理需求的教育机构开发者。项目采用ServletJSPJDBC技术栈&#xff0c;遵循MVC分层思想&#xff0c;覆盖学生信息维护、成绩录入修改、条件查…

作者头像 李华
网站建设 2026/10/1 4:08:34

Vue Router 核心原理与 router/index.js 配置实战解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/10/1 4:08:30

Pixel Canary:首个确定性编程辅助模型实战指南

1. 项目概述&#xff1a;当“匿名模型”开始在编程榜上真实交锋最近刷到一条标题——“又一款匿名模型杀入编程榜&#xff1a;免费、性能追平 GPT-6 Astra”&#xff0c;我第一反应不是点开&#xff0c;而是把手机倒扣在桌面上&#xff0c;静了三秒。不是因为 skepticism&#…

作者头像 李华
网站建设 2026/10/1 4:08:29

汽车CUBING综合匹配样架全解析:从设计到验收的尺寸工程指南

第一次看到“CUBING”这个词&#xff0c;是在一个外资项目的尺寸工程周会上。当时PPT上放了一张钢架加铝块拼成的“车架子”&#xff0c;有人拿着间隙尺在量前保险杠和大灯的缝隙&#xff0c;旁边标注着“CUBING”。我一开始以为是某个软件的缩写&#xff0c;后来才搞清楚&…

作者头像 李华