技能盘点这件事很多人一年只做两次一次是写简历一次是年底绩效自评。真到那个节点对着空白文档才会发现“我到底会什么”这个问题比想象中难回答。我大概从两年前开始把自己的技能当成一个独立项目来维护项目名字就叫 skills。载体很简单一份 YAML 数据文件加两个 Python 脚本负责记录、计分、生成报告和图表。实际的效果是“我会 Python”会变成“Python 4 分、Flask 3 分最近一次使用是两周前证据链接在下面”。需要写简历的人、想盘点团队能力分布的管理者以及想摆脱三分钟热度的自学者都可以参考这套思路。技能管理这事听起来像是 HR 才需要的词但落到个人身上一点不虚。它不要求你用一个多复杂的系统只要把“我会什么、会到什么程度、多久没用了”这三件事用结构化方式记下来后面所有关于学习和求职的判断都会变得清晰。这篇文章我会拆解 skills 这个项目的完整设计逻辑、评分标准、YAML 数据结构和两段核心 Python 脚本最后附上我实际维护过程中踩过的坑和排查经验。只要你愿意花一两个小时把初始文件建好这套东西可以一直用下去。1. 项目整体设计与思路拆解1.1 技能管理到底解决什么问题先说痛点。很多人面试挂掉不是能力不行而是被问到“你 Java 怎么样”的时候只能回一句“还行”。这个“还行”就是典型的技能认知模糊。模糊的后果有两个一是简历没法写因为你没法用具体的产出告诉对方你熟练到什么程度二是成长没有方向你不知道下一个该补的短板在哪。技能管理本质上就是解决这两件事的。拆开看核心是四步定义把“我会”翻译成明确的技能项而不是停留在感觉层面评估给每个技能项一个说得清、可执行的打分标准追踪每隔一段时间更新状态记录最近一次使用时间和产出规划把低分和高目标之间的缺口变成下一步具体行动。这四步听起来像项目管理实际上也确实是一种项目管理只不过管理对象是自己的能力资产。拿记账来类比最合适你不记账就永远不知道钱花在哪不盘点技能就永远不知道时间浪费在哪。技能管理的价值不在于“记下来”这个动作而在于每个月被迫面对一次真实状态的那种反馈感。我做这个项目的过程中最大的感受是它把“自我感觉”和“客观事实”之间的差距一点点拉平了。以前我觉得自己什么都会一点真正开始按技能项打分之后才发现大部分都停留在 2 分左右——就是在教程辅助下能做点事离开教程就抓瞎。这个认识很扎心但很有用。1.2 为什么我不用现成的测评和学习平台市面上有不少现成方案在线学习平台带技能树招聘网站带测评工具甚至有些社区可以让你给自己的技能打标。我并不是要否定这些平台它们有各自的定位但作为个人技能的长期管理工具有几个问题绕不开。第一技能体系是平台定义的不是你自己的。平台说“Python 进阶”包含十个子项你就只能按它的框架走可你实际的工作场景可能是数据分析、可能是自动化、可能是爬虫这些通通不在它的体系里。第二测评是一次性的考完给个分数就结束了没有持续追踪的机制。第三数据不在自己手里平台哪天改版或者停止维护你这几年的记录就没了。所以我的选择是本地文件加脚本完全自建。数据就是一份 YAML 文件格式公开、可读性好、方便版本管理想怎么扩展都可以。要画图就写个脚本画图要生成 Markdown 报告就写个脚本生成要自动打卡提醒也不是难事。这个过程本身就是一种能力锻炼跟我记录技能这件事是互相成就的。这就像记账你当然可以用手机 App但真正清楚每一笔钱怎么花的人往往是那个自己维护电子表格的人。不是 App 不好用而是你自己想清楚规则之后哪怕只是用文本文件记也能得到远超工具的洞察。1.3 整体架构一个文件加两个脚本skills 项目的结构非常简单目录长这样skills/ ├── skills.yaml # 技能数据和评分所有记录都在这里 ├── report.py # 读取 YAML生成 Markdown 技能报告 ├── chart.py # 读取 YAML生成雷达图 └── output/ ├── report.md # 自动生成的报告 └── radar.png # 能力雷达图YAML 文件是唯一的数据源。所有技能项、分类、评分、权重、最近使用时间、证据链接都写在里面。report.py 负责把 YAML 转成人能直接看的报告chart.py 负责把分数变成图。这个结构的优点有两个。一是单一数据源所有改动都只改一个文件不会出现数据散落在多个表格里的情况。二是功能按需添加初期只需要 report.py觉得图表有价值再补 chart.py 也不迟。我不建议一开始就把体系搞得太复杂文件驱动的方式最怕的就是过度设计。2. 核心细节解析与实操要点2.1 技能分类与层级先少建再慢慢长技能分类看起来简单做起来最容易翻车。我第一次建这个项目的时候一口气建了六十多个技能项从编程语言一直列到办公软件甚至在“Excel 函数”和“Excel 透视表”之间强行拆了两项。结果就是每次更新都像在填报表坚持了不到半个月就弃坑了。后来我重新设计把结构压缩成三层方向技术研发、软技能、业务能力这类大分类能力方向下面的具体能力块比如 Web 后端、数据分析、数据结构技能项能力块下面的最小颗粒比如 Python、Flask、PostgreSQL。一个方向下只保留三到四个能力块一个能力块下只保留两到三个技能项。整体控制在二十个技能项以内跑顺畅了再往下扩。为什么要这么克制因为技能管理的周期是月不是天。每个月要逐个技能项更新分数和证据二十个技能项大概花半小时六十个技能项就要一个半小时人很难为一个“自我管理项目”持续支付那么高的时间成本。分类的另一个关键是技能项要能对应到“可操作的场景”。比如“Python”可以继续拆成“基础语法”“Web 开发”“数据分析脚本”但如果你平时主要用 Python 写数据脚本那你只需要一个“Python 数据分析脚本”技能项不需要拆出 Python 通用能力。以实际使用场景为分类依据比按教科书目录分类要实用得多。2.2 可执行的评分标准0 到 5 分的具体定义很多人的技能自评失败是因为没有评分标准。你问自己“Python 怎么样”脑子里浮上来的是抽象感觉不是具体刻度。所以我的方案是给 0 到 5 分各写一段描述打分的时候照着描述去匹配。我长期使用的评分定义是0 分没接触过只是听说过名字1 分见过别人用能照着现成示例跑通但离开示例写不出代码2 分能在教程、搜索引擎、AI 辅助下完成简单任务遇到报错能按提示排查3 分能独立完成常见任务熟悉核心概念遇到问题能自己定位和解决4 分能带别人能根据场景做技术选型能产出可供他人参考的实践5 分能对方法论和工具本身提出改进有领域级影响力。这套定义的关键在于把“能不能干活”和“能不能讲清楚、带别人”区分开了。3 分以上才算是真正进入了“熟练”的范畴2 分之下基本只能算入门。再讲一个加权计算的方法。不同技能项对你当前目标的重要性不一样直接求平均会拉平差异。我引入了一个权重字段一二级技能项可以复习使用频率乘以重要性快速设置初学可以直接全设为 1。举一个实际的计算例子假设“Web 后端”能力块下面有这三项Python4 分权重 2Flask3 分权重 1.5PostgreSQL2 分权重 1那么方向分 (4×2 3×1.5 2×1) ÷ (2 1.5 1) 14.5 ÷ 4.5 ≈ 3.22 分。这个数字反映的是整个能力块的综合水平比单项分数更有横向参考价值。你可以把每个方向的得分算出来再画成雷达图一眼就能看出哪个方向是短板。还是那句话这些分数只跟自己比不同人之间的分数没有可比性别拿自己的 3 分去跟别人简历上的“精通”较劲。2.3 证据链与复盘周期让分数经得起追问评分如果没有证据支撑会变成自我感觉良好。我给每个技能项加了一个证据对象包含三个字段。last_used最近一次实操的时间和内容比如“2025-01-15重构数据清洗脚本耗时约 6 小时”evidence实际产出可以是修复的 bug、写过的模块、整理过的文档、带教过的同学只要能指向具体场景都行next_step下一步打算做的事情用来承接学习规划。这套设计的逻辑很简单如果你最近三个月都没有用过某个技能那么分数打 4 分就非常可疑。last_used 会直接揭穿你。反过来如果你每天都靠某个技能吃饭但分数一直停在 3 分这也值得想一想是不是你其实每天都在重复同样的低难度工作根本没有进入 4 分要求的“选型和带人”层面。复盘周期我建议是每月底抽 30 到 60 分钟逐个技能项更新评分和证据每个季度做一次大调整审视技能分类、权重和方向设置是否还符合当前目标。复盘不是简单地改数字而是要回答三个问题这个技能最近用了吗用的难度上去了还是下来了下一步要不要花时间加强它3. 实操过程与核心环节实现3.1 先搭好技能底稿一份能直接用的 YAML 模板这一节我会给出一份完整的 YAML 模板你可以直接复制改成自己的内容。结构比内容重要初期技能项宁少勿多。version: 1 owner: self updated: 2025-06-01 categories: - name: 技术研发 weight: 3 skills: - name: Python score: 4 weight: 2 last_used: 2025-05-20重构定时任务的数据清洗模块 evidence: - 内部报表自动化脚本支撑每日数据更新 next_step: 补充并发编程实践目标 4.5 分 - name: Flask score: 3 weight: 1.5 last_used: 2025-04-18搭建内部工具的后台接口 evidence: - 内部工具后台 API接口文档已归档 next_step: 练习 RESTful 设计目标 3.5 分 - name: PostgreSQL score: 2 weight: 1 last_used: 2025-03-02写过一个多表查询报表 evidence: - 多表查询 SQL 片段存档 next_step: 系统复习索引与事务目标 3 分 - name: 软技能 weight: 2 skills: - name: 汇报能力 score: 3 weight: 1 last_used: 2025-05-28月度项目汇报主讲 evidence: - 汇报 PPT 已存档收到团队反馈 next_step: 练习用数据讲故事目标 3.5 分这份模板的细节都值得说一句。version 字段用来标记体系版本方便以后知道自己是按哪一套规则记录的。categories 下面的 weight 表示这个大方向在你当前阶段的重要性也和第二节的加权计算挂钩。skills 下面的每一项都是最终的最小单元后续所有脚本分析都会基于这个层级。3.2 用 Python 自动生成技能报告数据放在 YAML 里接下来要写一个脚本让它变成人类可读的报告。我用的是 Python 加 pyyaml你也可以用 Node 或者 Go逻辑都一样读取数据、计算加权分、生成 Markdown 文本。import yaml def load_data(pathskills.yaml): with open(path, encodingutf-8) as f: return yaml.safe_load(f) def calc_category_score(cat): total_weight 0 total_score 0 for skill in cat.get(skills, []): w skill.get(weight, 1) total_weight w total_score skill[score] * w return total_score / total_weight if total_weight else 0 def render_markdown(data): lines [f# 技能报告更新时间{data.get(updated, )}, ] for cat in data[categories]: avg calc_category_score(cat) lines.append(f## {cat[name]}方向分{avg:.2f}) lines.append() for skill in cat[skills]: lines.append( f- {skill[name]}{skill[score]} 分 f最近使用{skill.get(last_used, 未记录)} ) lines.append() return \n.join(lines) def main(): data load_data() report render_markdown(data) with open(output/report.md, w, encodingutf-8) as f: f.write(report) print(报告已生成到 output/report.md) if __name__ __main__: main()这段代码很短但覆盖了完整的流程。calc_category_score 就是第三节那个加权公式的实现render_markdown 把每个方向的方向分和每个技能项的最低信息写到 Markdown 文件里。实际执行流程很顺手先改 skills.yaml再在终端跑python report.py然后打开output/report.md看结果。如果你后续想自动推送到自己的知识库或者静态站点只需要把 main 里写文件的部分换成调用对应接口即可。这个脚本的设计重点不是一次性写完而是保持“数据与展示分离”之后任何展示层的改动都不会动到 YAML 数据。3.3 用雷达图直观展示能力结构报告是用文字表达的雷达图则能把多个方向的能力结构一次性展现出来。这里的核心逻辑是把每个方向的加权分放到极坐标上Python 用 matplotlib 实现。import matplotlib matplotlib.use(Agg) import matplotlib.pyplot as plt import math def calc_category_score(cat): total_weight 0 total_score 0 for skill in cat.get(skills, []): w skill.get(weight, 1) total_weight w total_score skill[score] * w return total_score / total_weight if total_weight else 0 def draw_radar(data, output_pathoutput/radar.png): cats [cat[name] for cat in data[categories]] scores [calc_category_score(cat) for cat in data[categories]] n len(cats) angles [i / float(n) * 2 * math.pi for i in range(n)] angles angles[:1] scores scores[:1] fig, ax plt.subplots(figsize(6, 6), subplot_kwdict(polarTrue)) ax.plot(angles, scores, color#4C72B0, linewidth2) ax.fill(angles, scores, color#4C72B0, alpha0.25) ax.set_xticks(angles[:-1]) ax.set_xticklabels(cats, fontsize12) plt.savefig(output_path, dpi150) plt.close(fig)雷达图的解读有个技巧不要只盯着最高分和最低分还要看形状。如果图形比较扁平说明你各方向发展得均衡但可能也意味着没有突出的立身之本如果图形有明显尖角说明你有方向性优势下一步更应该做的是补短板而不是继续拉长板。3.4 落地后的维护节奏与时间投入我现在的维护节奏是每周花十分钟左右更新 last_used 和 score只碰本周真正用过的技能项每月底花半小时到四十五分钟做完整复盘把所有技能项过一遍每季度做一次结构性调整比如新增技能项、调整权重、删掉一些已经不在计划里的内容。这套节奏的时间成本很低但前提是别在结构设计上过度投入。很多人在建这个项目的第一周就花了一整天去美化脚本和调图表配色结果忘了真正的问题是数据有没有按时更新。我的建议是脚本能用就行YAML 结构简单就行把精力放在“每个月能坚持复盘”这一件事上。4. 常见问题与排查技巧实录4.1 技能列表越建越臃肿怎么办这是最常出现的问题。建项目时兴致勃勃恨不得把所有学过的东西都列进去结果过了两个月YAML 文件里躺着六十个技能项每次打开就觉得无从下手。我的解决办法是引入一个状态标记。不需要删掉那些不常用的技能项而是在 YAML 里给它加一个状态字段比如status: active表示活跃维护status: deepfreeze表示暂时冻结。冻结的技能项不参与日常更新也不计入雷达图但保留在文件里作为历史记录。这样既不会丢失信息又不会让活跃列表膨胀到难以维护。4.2 分数越改越低、忽上忽下是怎么回事很多人会遇到一种情况第一次打分时自己给的分数挺高过了两个月复盘时发现越改越低。这不是技能退步了而是你开始理解对应岗位或领域的真实要求了。第一次打分往往基于“我以为自己会什么”第二次打分开始基于“我最近实际做了什么”标准自然变得更严格。分数忽上忽下也正常。因为评分实际看的是最近一个月的实操强度而不是长期能力储备。一个技能三个月没碰分数从 3 掉到 2这个下跌本身就是一个信号要么安排一次实操让手热起来要么承认它暂时不在重点里主动调低优先级。不要因为分数下降而焦虑这是数据在发挥反馈作用。4.3 没有拿得出手的项目证据怎么填没有正式项目经历的初学者问得最多。我给出的答案是把“证据”的范围放宽。修过一个 bug、顺手写过一段文档、给同学讲过一个知识点、解决过一个配置问题这些都属于实操场景都可以写进 evidence。关键不是规模而是“你确实做过而且能说清楚过程”。例如你的 Python 是 2 分evidence 可以写“用 Python 批量重命名了本地文件处理了大概 200 个文件名”你的汇报能力是 2 分evidence 可以写“在小团队周会上做了十分钟口头同步”。这些小事看起来不起眼但它们是评分标准里“独立完成常见任务”的真实佐证。有了它们下一次复盘的时候你才能判断这个技能最近有没有真的往前走一步。4.4 图表中文乱码与跨平台显示问题matplotlib 的默认字体大多不支持中文第一次跑 chart.py 时大概率会看到一个个小方块。解决方法是显式指定中文字体在绘图代码里加上两行设置。plt.rcParams[font.sans-serif] [Microsoft YaHei, SimHei, Noto Sans CJK SC] plt.rcParams[axes.unicode_minus] False第一行把中文字体加入候选列表不同系统会自动匹配可用的一款第二行是为了让负号能正常显示否则坐标轴上的负号也可能变成方框。如果你在 Linux 服务器上跑记得确认系统是否装了中文字体没装的话可以用系统包管理器装一个 Noto Sans CJK。4.5 数据同步、备份与隐私边界技能数据里面往往会写具体的项目细节和产出链接这些内容属于个人隐私不适合放在完全没有权限管控的公共位置。我的做法是用私有 Git 仓库来管理整个 skills 目录每次改动提交一次这样既有历史版本可以回溯也能在换电脑时一键拉取。还有一个容易忽略的点不要因为想展示自己的项目就把当前公司的业务代码、内部系统的截图或敏感信息写进 evidence。evidence 写的是“做了什么”以及“结果是什么”模糊成“内部数据报表自动化脚本支撑每日数据更新”就足够了具体到表结构和业务数据的细节完全没有必要写。至于代码本身report.py 和 chart.py 都是纯本地运行的脚本不依赖任何在线服务这本身就保证了数据不会在我们不知情的情况下被传出去。这是本地文件方案最大的安全感来源。我自己跑了一年多这个项目之后回头去看最有价值的时刻并不是看到雷达图成型的那一秒而是每个月复盘时被迫面对真实状态的这个过程。有些技能明明每天在用但长期停在低水平重复上有些东西很久没碰分数在悄悄下跌。如果没有这套记录这些变化都会被忙碌掩盖掉。最后再分享一个实测下来很有用的技巧给每个方向设一条“最低分底线”。比如“技术研发”方向下的每个技能项分数低于 2 分的都不算进入可用状态应该明确安排学习时间分数高于 4 分的则不用再投入日常时间最多保持使用频率。设定底线以后你的精力分配会变得非常清晰也会发现那些真正值得深耕的方向其实一直就那么两三个。