用DeepSeek生成网易云式年度报告:数据聚合、JSON输出与专属色计算
2026/9/13 10:06:32 网站建设 项目流程

两周前朋友给我转了一份网易云年度报告,我一边看一边想:那些“年初许愿、年终翻车”式的文案,如果换成我自己这一年真实发生的事,会不会更有意思?于是就有了这篇实战第15期:让 DeepSeek 把我过去一年留下的散乱记录,变成一份带关键词、带情绪曲线、带金句的网易云式年度报告,最后连专属年度色都算了出来。

先说结论:整套东西不需要多高的前端水平,核心是用 DeepSeek 的文本理解能力处理个人流水账,再用一个简单的色彩脚本负责“专属色”部分。跑通以后,你可以把它变成每年年底固定跑一次的模板,也可以包装成给朋友做的小礼物。这篇文章不端着讲理论,只按我实际操作顺序来。

1. 拆解网易云式年度报告,到底在拆什么

1.1 一份报告卡片的底层信息架构

网易云年度报告之所以让人愿意转发,不是因为页面动效多炫,而是它把“一年的自己”切成几个能引起共鸣的模块。我拿到这个需求后,没有急着打开 DeepSeek,而是先拿往年报告截图做了一次逆向拆解。拆完发现可以用模块见下表。

模块内容目的
年度总结论用一句话概括这一年让人一眼记住
高频关键词3-5个词概括生活节奏形成记忆点
时间线叙事按月或按季度的标记事件制造“原来我也经历过”的感慨
个人状态曲线开心/平静/焦虑等情绪比例提供可视化抓手
金句/土味文案一句略带矫情但真实的话放大转发欲

这五样东西背后对应的是两类能力:一类是归纳总结,另一类是文字渲染。归纳总结需要看懂原始记录里哪些事情值得被记住;文字渲染则需要把一个普通事件说成“只有你自己才懂的梗”。这两件事如果全写在脚本规则里,维护成本会高到离谱,而 DeepSeek 这类大模型天生就擅长。

所以我最后确定的技术方案是“大模型负责语义,脚本负责视觉和颜色”。DeepSeek 不一定要直接生成一张海报,它只需要输出结构化的 JSON 数据,后面的配色和排版完全可以用 Python 的 HTML 模板来做。这样做的好处是你可以随时换报告皮肤,不必重新让模型打字。

1.2 为什么我选择 DeepSeek 而不是本地脚本

有人会问:做个报告不是直接读 Excel 统计就行吗?对,如果目的只是统计“今年跑了多少公里、看了几部电影”,写脚本完全够。但网易云式报告的灵魂在那些带叙事感的表达,比如“你在深夜 23:47 单曲循环《XX》”,换成个人生活就是“你在加完班的周三晚上,把一本闲书翻到了凌晨”。

让脚本去把“加班后翻书”这件事描述成一句有温度的话,几乎不可能。DeepSeek 的强项是理解上下文并生成自然语言,而且它的 API 调用方式与很多开源工具链兼容,我只要把月度记录以纯文本拼进去,它就能输出我要的答案。这也是我把整套流程叫做“报告生成器”的原因:输入是个人记录,输出是可直接渲染的 JSON,中间不需要搭复杂的数据库。

1.3 这套方案能扩展到什么程度

这次的标题写的是“2026”,我的实际做法是先用 2025 年全年的数据跑通模板,生成一份带有“2026 限定版”标记的个人年度备忘。这样到了 2026 年真正结束,我只需要把新一年的记录替换进去,再跑一次相同脚本,就能得到真正属于 2026 的报告。

同样的思路还可以用在月度复盘、团队 OKR 总结、甚至一个小社群的年度回忆录上。你只要把输入数据的字段换掉,提示词里改成对应的角色定位,输出结构不会有太大变化。这也是我觉得它值得写一篇文章的原因:一次调试,长期复利。

2. 数据准备:到底要把什么喂给 DeepSeek

2.1 我收集了哪几类个人数据

想让最后生成的报告不像“AI 编故事”,输入的数据必须足够具体。我没有用聊天类的天量数据,而是收集了几个可量化、且我能回忆起来的来源:

  • 日记和随笔:从日记软件里导出每月的主题句,然后人工挑出最重要的 3 条。
  • 相册:按月看照片,记下这个月反复出现的场景,比如“山居”“跑步”“朋友聚餐”。
  • 书影音记录:把今年看完的书、电影、剧集列成清单,并在后面标注一句当时感受。
  • 运动与健康数据:跑步总里程、平均睡眠时长,这些数据会作为状态曲线的底料。
  • 让我印象最深的高光/低谷事件:每月写两个关键词,比如“辞职”“新城市”“熬夜赶方案”。

把这些数据整理成一张表其实很繁琐,但这一步不能省。因为大模型无法知道你心里在想什么,它只能依赖你给它的上下文。输入越稀碎,输出就越会变成正确的废话;输入里哪怕只有一个“六月:在暴雨里搬家”这样的句子,生成结果都会立刻有烟火气。

整理好后,我没有把原始文件直接丢给模型,而是统一做成了“月度归档”的纯文本。每一行代表一个月,包含当月的主要事件、情绪占比和关键数据。

01月|关键词:雪、元旦、新计划|高光:完成年度目标拆解|情绪:平静40% 期待35% 焦虑25%|跑步42km 02月|关键词:春节、宅、读书|高光:读完3本大部头|情绪:放松55% 无聊20% 思虑25%|跑步18km ... 12月|关键词:复盘、降温、旧友|高光:和老朋友跨城见面|情绪:温暖50% 充实30% 疲惫20%|跑步35km

这段文本长度通常在 1000-2000 字,远没有到 DeepSeek 的上下文上限,却又比一条条流水账更适合做整体叙事。模型看到的是“一个人如何在十二个月里经历起落”,而不是“某月某日做了什么”,前者更容易生成有转折感的报告。

2.2 隐私与脱敏处理

用个人数据做大模型生成,最容易被忽略的是隐私。照片、聊天记录、支付明细这类数据我建议不要直接上传到任何 API。我在项目里只上传了经过抽象的文本,例如把具体人名换成“一位老朋友”,把公司名换成“前司”。你要是担心聊天记录中的隐私,也可以在本地先做一轮关键词提取,只把统计结果传给模型。

安全习惯我再强调一次:API Key 一定不要写死在代码里或提交到公开仓库。用环境变量读取是底线,谁也不想自己的账号被别人拿去跑一堆奇怪请求。

2.3 为什么先做月度聚合而不是逐日喂入

最开始我也试过把所有日记原文一股脑丢给模型,希望它“自己看着办”。实测效果并不好:日记有大量私人化的碎碎念,模型会把很多无意义细节当成重点,生成的报告显得啰嗦,而且经常抓不住年度转折点。

改成月度聚合后,相当于我先做了一遍人工降噪,再让模型在这个被筛选过的信息集上发挥。报告的金句能力来自大模型,可“哪些事值得今年被记住”的判断仍然应该由自己做。这个判断越准,报告就越像自己。

如果你实在没时间逐月整理,也可以用另一个 DeepSeek 调用来做初步整理:先让模型把整年日记按月份压缩成上面那种格式,然后人工检查一遍。但要注意,批量处理大量日记会显著增加 token 消耗,我建议还是手动控制输入规模,省下的不仅是钱,还有反复调优的精力。

3. 实操:用 DeepSeek 生成报告正文

3.1 完整流程只有三步

我最终跑通的流程是这样的。第一步,把月度归档文本和一段系统提示词一起发给 DeepSeek,要求它返回一份 JSON,里面包含年度主题、关键词、逐月叙事节点、总结文案等字段。第二步,用脚本读取这份 JSON,再结合情绪统计数据和专属年度色算法,渲染成一个 HTML 页面。第三步,把页面保存成图片或直接做成可分享的长图。

这个流程里最核心的是第一步的 Prompt 设计和输出约束。DeepSeek 的模型本身不保证每次都输出合法 JSON,所以我用了几层保险:在系统提示里给出明确的 JSON 字段定义、在用户提示里要求“必须输出 JSON,不要解释”、调用时开启 JSON Output 模式,最后再用 Python 做 json.loads 异常处理。

3.2 DeepSeek API 调用基础代码

这里先给一个最小可用的调用示例。我在项目里用的 Python 版本是 3.11,只需要安装requests或者openai库。DeepSeek 的接口风格是 OpenAI 兼容的,所以直接用openai库也可以。

import os import requests API_KEY = os.getenv("DEEPSEEK_API_KEY") def chat_with_deepseek(messages, temperature=0.7): resp = requests.post( "https://api.deepseek.com/chat/completions", headers={ "Authorization": f"Bearer {API_KEY}", "Content-Type": "application/json" }, json={ "model": "deepseek-chat", "messages": messages, "temperature": temperature, "response_format": {"type": "json_object"} } ) resp.raise_for_status() return resp.json()["choices"][0]["message"]["content"]

这份代码里的response_format就是 JSON 模式,它能让模型更倾向于输出结构化内容。注意:开启 JSON 模式后,你仍然需要在系统或用户提示中明确出现“json”字样并描述字段,否则模型不知道要输出什么结构。

3.3 提示词设计:让模型一次性给出可用内容

我的系统提示词大概长这样:

你是一个擅长写个人年度报告的产品文案专家。用户会提供按月整理的个人记录,你需要从中提炼出这一年的核心故事线。 要求: 1. 输出严格 JSON,不要输出额外文字。 2. JSON 字段包括 theme、keywords、timeline、highlight_moments、summary_sentence。 3. theme 是一句不超过20字的主标题。 4. keywords 是3-5个关键词。 5. timeline 是一个数组,每个元素包含 month 和 event 两个字段,event 必须来自用户输入且有细节。 6. highlight_moments 是2段最有故事感的回忆,每段控制在50字以内。 7. summary_sentence 是一句能引发共鸣的总结语。

用户提示则直接放我整理好的月度归档文本,再加上一句“请基于以上内容生成我的 2026 个人年度报告 JSON”。这里有个很重要的细节:不要让模型发挥出“用户输入中不存在的事实”,否则报告会显得假。比如用户输入里没有“旅行”二字,模型就不该在 timeline 里编出“在洱海边看日出”。

调试的时候我发现,把“必须基于用户输入,禁止编造未出现的事件”写进系统提示非常有效。大模型天生会为了句子流畅而补细节,所以在长文本生成任务里,这条约束能帮你省掉大量后期校对时间。

3.4 我最后拿到的 JSON 长什么样

跑成功后的核心输出大概是这样,我截取了比较有代表性的部分。这里的主题我稍微改过几版提示词,最后稳定在一个让我满意的结果:

{ "theme": "把日子过成自己的BGM", "keywords": ["重启", "独处", "夜跑", "减法"], "timeline": [ {"month": "3月", "event": "在凌晨的出租屋里写完离职交接文档"}, {"month": "6月", "event": "冒着大雨搬到离江边更近的小区"}, {"month": "9月", "event": "第一次连续跑完10公里"}, {"month": "12月", "event": "和一位老朋友在旧书店待了整个下午"} ], "highlight_moments": [ "六月搬家那天没有叫任何人,雨停后看见窗外的江面,突然觉得所有转折都有回声。", "九月第一次跑完10公里,耳机里正好放到你单曲循环过的那首歌。" ], "summary_sentence": "生活没有真正的空降热搜,只有你选择反复播放的那一刻。" }

这段 JSON 对我来说最有价值的是timeline里的event字段,它没有说空话,而是选取了真实发生过的事。这类细节才是网易云式报告能打动人的原因。因此,如果你生成的 JSON 里全是“追求梦想”“热爱生活”这种大词,先别怪模型,回去看看输入文本是不是缺少具体事件。

4. 专属年度色:不是让配色好看,而是让配色有“出处”

4.1 为什么不能只让 DeepSeek 随口报一个颜色

一开始我确实想过让模型直接告诉我“你的2026专属年度色是薄荷绿”,但后来发现这逻辑不成立。模型给出的颜色是它根据文字联想出来的,属于“审美生成”,并不一定和我的数据强相关。既然是“专属年度色”,最好的做法是让颜色从你的个人情绪数据中长出来,而不是模型灵感一拍脑袋。

所以我定下的计算思路是:先把我每个月记录的情绪标签映射到色相环上,再按每个月的事件权重做环形平均,最终得到一个只属于这堆数据的色相角。饱和度与明度则根据这一年整体能量值来定。这样得出的颜色即使不够“流行”,解释起来也足够动人:它的每一度都来自我真实的生活。

4.2 情绪标签如何映射到色相

我用了下面这套映射,色相值参考的是普通人对颜色的心理直觉:

  • 开心/高光:金黄琥珀色,色相约 45
  • 平静/放松:蓝色,色相约 210
  • 成长/专注:绿色,色相约 150
  • 焦虑/疲惫:灰紫色,色相约 280
  • 热烈/社交:红色,色相约 0
  • 独处/思考:青蓝,色相约 190

一个月的情绪通常不会只有一个,所以我会先算出每个月主要情绪占比,再把多种颜色的色相按权重合成近似值。注意色相是环形坐标,不能直接用普通平均数,否则 350 度和 10 度的平均值会被错误地算成 180 度,而正确的直觉应该是 0 度附近。在代码里我用了三角函数处理环形平均。

4.3 计算专属年度色的 Python 实现

import math from collections import Counter def average_hue(hues, weights): x = sum(math.sin(math.radians(h)) * w for h, w in zip(hues, weights)) y = sum(math.cos(math.radians(h)) * w for h, w in zip(hues, weights)) avg = math.degrees(math.atan2(x, y)) % 360 return avg # monthly_emotion_data 示例: # [{"month": "1月", "mood_counter": {"平静": 0.4, "期待": 0.35, "焦虑": 0.25}}, # {"month": "2月", "mood_counter": {"放松": 0.55, "无聊": 0.2, "思虑": 0.25}}] hue_map = { "开心": 45, "高光": 45, "平静": 210, "放松": 210, "成长": 150, "专注": 150, "焦虑": 280, "疲惫": 280, "热烈": 0, "社交": 0, "独处": 190, "期待": 60 } hues = [] weights = [] for item in monthly_emotion_data: for mood, ratio in item["mood_counter"].items(): if mood in hue_map: hues.append(hue_map[mood]) weights.append(ratio) final_hue = average_hue(hues, weights) # 饱和度/明度由年度整体稳定度决定 # 这里我简单使用平均的积极情绪占比 positive_ratio = 0.62 saturation = 0.55 + positive_ratio * 0.25 lightness = 0.72 + (1 - positive_ratio) * 0.1 print(f"HSV: ({final_hue:.0f}, {saturation:.2f}, {lightness:.2f})")

跑完这段代码,我得到的是一个类似HSV(198, 0.68, 0.82)的结果,转成十六进制后是清透的蓝青色。后来我把这个颜色发给 DeepSeek,让它帮我起一个名字,它给了个我很满意的答案:江面晨雾蓝。我很喜欢这个名字,因为六月搬家后我确实常常在江边跑步,颜色和记忆突然就串起来了。

4.4 将年度色应用到报告卡片

拿到单纯一个主色还不够,我定义了一个小的调色板函数:主色用于背景渐变,主色的互补色和提亮色用于强调关键词,另加一层半透明白色覆盖层保证文字可读性。这部分不用让模型参与,用 Python 的颜色转换库就能完成。

import colorsys def hsv_to_hex(h, s, v): r, g, b = colorsys.hsv_to_rgb(h / 360, s, v) return "#{:02x}{:02x}{:02x}".format( int(r * 255), int(g * 255), int(b * 255) )

如果你愿意,也可以把生成的十六进制色值放到截图里的每个卡片背景上,形成统一节奏。报告做完以后,我还把同款色值存进了个人资料里,用作文档封面的统一色调,操作成本几乎为零。

5. 常见问题与调优记录

5.1 模型总是输出额外文字,JSON 解析失败

这个问题最常出现在刚开始调用时。明明提示里说了“只输出 JSON”,模型还是会在开头写一句“好的,这是你的报告”之类的废话。我这里有三层缓解办法。第一层是在系统提示中明确说明“不要寒暄,不要解释,只输出 JSON”;第二层是开启response_format;第三层是在代码里做兜底,用正则提取第一个{到最后一个}之间的内容再解析。

即使有这些措施,还是可能出现个别输出字段缺失的情况。我会写一个简单的ensure_keys函数,如果字段缺失就重试一次,最多重试两次。这个方法在绝大多数场景下都能稳定拿到完整 JSON。

5.2 生成内容太泛,没有个人特色

如果报告读起来像星座运势,问题大概率出在输入数据颗粒度太粗。你只喂“一月:比较忙”,模型自然只能回“一月:忙碌而充实”。解决的思路很粗暴:把“比较忙”改成“一月:连续加了12天班,完成年度项目上线,凌晨从公司出来时看见路灯下有人遛狗”。越具体的画面,越能激活模型的叙事能力。

另外,如果某个月实在没有亮点,不要硬写。网易云报告也不会保证每天都有故事。让模型优先从有戏剧性的月份提取 timeline,整体节奏会更好。

5.3 超长数据和上下文限制

单个用户一年数据其实不会太长,但如果你要帮一群人批量生成报告,文本总量会被快速放大。我的做法是给每条输入预生成一个摘要层,让 DeepSeek 只处理摘要,而不是原始数据。这相当于做了一个简单的 RAG 前的粗筛:先按月份把重点事件捞出来,再交给模型整合。

控制 token 通常还会直接省钱。这里有一个参考数字:一份包含12个月个人月度记录的报告生成请求,输入大概 1500 token,输出约 600 token,成本非常低。但如果连续生成几十次,费用也会积累,批量场景建议设置单次最大 token 数,比如max_tokens=700,避免模型每次自由发挥太多。

5.4 温度参数要调到多少

温度控制的是随机性。我试过从 0.2 到 1.2 的多组参数。温度太低时,报告句子规整但无聊,“像一份公务员自我鉴定”;温度太高时,文案会为了金句开始飞,比如编造你根本没做过的事。结合我的调参经验,生成叙事文本用 0.7 表现最好,生成标题和总结语时我会临时改成 0.9,让句子更有意外感。

5.5 接口报错速查

错误现象可能原因对策
401 UnauthorizedAPI Key 错误或没有写入环境变量检查DEEPSEEK_API_KEY是否已正确设置
400 Bad Request请求体字段格式不对,或 JSON 模式缺少字段说明检查 messages 里是否包含“json”提示
429 Rate Limit请求频率过高或余额不足增加 sleep 间隔,检查账号额度
JSON 解析失败模型输出被截断调大max_tokens,或增加重试机制

如果你是在编辑器或编程助手类的工具里接入 DeepSeek 调试脚本,遇到类似报错时也可以先按这张表排查。大多数问题不是模型能力问题,而是请求结构不规范。

5.6 用图片还是 HTML 渲染报告

我一开始是把 JSON 输出手动粘贴到设计工具里排版,效率太低。后来写了一个简单的 Jinja2 模板,把 JSON 里的字段渲染成移动端尺寸的 HTML 长图,再用无头浏览器截图。如果你不想引入无头浏览器,也可以用 Python 的 Pillow 直接绘制文字和色块,只是动态字体布局会更麻烦。

HTML 路线还有一个优势:你可以直接在浏览器里按 F12 把长图分成多张卡片保存,适合发朋友圈。不要追求一个巨大尺寸的 PNG,网易云真正刷屏的场景是一张张滑动卡片,而非一望无际的长图。

6. 从“一份报告”到“一套个人年度制造机”

6.1 把报告做成家人朋友都能用的输入框

做完给自己的版本后,我顺手做了一个给别人用的简化页面:只需要对方按月份填写一个事件和一个情绪词,脚本就能自动调 DeepSeek 生成他们的专属年度报告。因为提示词和输出结构完全复用,我这个页面只花了一晚上就写完了。如果你也想做类似的小礼物,建议尽量降低对方的输入成本,最好让对方填“一句话+一个情绪”就行,而不是要求对方交出一整年的日记。

6.2 年度色可以延伸到更多场景

专属年度色算出来后,我把它应用到了个人博客的封面图上。配色这个东西很神奇,一旦你赋予了它“来自我的2025”这个背景,它就不再只是装修层面的好看。后来我在给朋友的生日贺卡上也算了一个“年度色”,对方听完计算逻辑后很喜欢:不是随机给的粉色,而是从她一年里所有开心时刻平均出来的颜色。

6.3 如果你有 VSCode 或桌面端工具,可以进一步自动化

我在调 Prompt 初期也试过把类似需求放到 AI 编程助手类的配置里,感受是:聊天窗口适合调思路,批处理还是适合写成 Python 脚本。因为一旦你频繁修改参数和输入数据,脚本的可重复性远高于每次手动复制粘贴。建议流程是先在脚本里把整条链路打通,后面再考虑接到其他工具里做展示层。

6.4 最后分享一个我自己的小习惯

把个人记录整理成月度归档这个动作,本身也挺有价值。我现在会在每月最后一天花十分钟写下这个月的一个高光事件、一个低谷事件和三个情绪占比,存进同一个纯文本文件。到了年底,别人需要翻半年微博才能回忆起来的事,我五分钟就能整理成报告原料。

这次项目做完后,最让我满足的不是画面有多好看,而是我发现“回顾”可以用一种更主动的方式发生。DeepSeek 帮忙完成的是锦上添花的语言包装,色彩脚本负责把情绪变成可视化的坐标,但真正让报告无法复制的,永远是你愿意如实留下的那几行细节。工具会迭代,Prompt 可以复制,唯独你的那一年,只属于你自己。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询