两周前朋友给我转了一份网易云年度报告我一边看一边想那些“年初许愿、年终翻车”式的文案如果换成我自己这一年真实发生的事会不会更有意思于是就有了这篇实战第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. 数据准备到底要把什么喂给 DeepSeek2.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, temperature0.7): resp requests.post( https://api.deepseek.com/chat/completions, headers{ Authorization: fBearer {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(fHSV: ({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_tokens700避免模型每次自由发挥太多。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 可以复制唯独你的那一年只属于你自己。