从零搭建可维护的技能管理系统:纯文本+脚本实现技能盘点与提醒
1. 从“skills”这个词说起它到底指什么“skills”这个词单独拎出来看信息量其实非常低。它可以是招聘网站上的一个标签可以是某个学习类应用的模块名也可以是某个内部工具系统的代号。但正因为它的含义足够宽泛反而给了我们一个很好的切入点当一个人或一个团队说“我要整理我的skills”时他真正想解决的问题是什么我接触过不少做个人知识管理、团队能力盘点、内部培训系统搭建的朋友发现一个共性大家嘴上说的是“skills”实际面对的却是一团乱麻——技能条目散落在各种文档里熟练度定义模糊更新频率极低最后变成一份没人看的“僵尸清单”。所以这篇文章不打算泛泛而谈“技能很重要”而是围绕一个具体的项目思路展开如何从零搭建一套可维护、可查询、可迭代的个人或小团队技能管理系统项目代号就叫“skills”。这套东西适合谁如果你是独立开发者、自由职业者、小团队负责人或者只是单纯想把自己的能力家底理清楚那接下来的内容可以直接抄作业。它不依赖任何特定平台用最朴素的文本加脚本就能跑起来后期想迁移到数据库或可视化面板也毫无压力。2. 整体设计思路为什么我不推荐一上来就上系统2.1 先想清楚“技能”的粒度问题很多人做技能管理第一步就卡在“我到底该列多细”。写“编程”太粗写“Python中asyncio的事件循环异常处理”又太细细到你自己都记不住。我的经验是技能条目的粒度应该以“能否独立完成一个可交付成果”为标准。举个例子“能用Python写脚本处理Excel”是一个合格粒度因为它对应一个明确的产出“熟悉Python”就不合格因为它无法验证。再比如“会用Figma画线框图”合格“懂设计”不合格。这个标准的好处是你后续做熟练度评估时有天然的判断依据——能不能独立交付交付质量如何。注意粒度不是一次定死的。我建议第一版先粗后细先列出30到50条用两周时间实际使用把那些“从来没用过”和“总是需要查资料”的条目合并或拆分。技能清单是长出来的不是一次性设计出来的。2.2 为什么用纯文本加脚本而不是直接上Notion或数据库我试过用在线文档、表格、笔记软件来管技能清单最后都放弃了。原因很实在更新成本太高。每次想加一条技能要打开应用、找到页面、点新建、填字段、保存五步操作下来热情已经没了。而纯文本方案打开编辑器敲一行就完事脚本负责把它变成结构化数据。具体来说我用的结构是每行一条技能用竖线分隔字段类似这样Python脚本开发|能独立编写数据处理脚本|4|2025-03-01 Figma线框图|能完成中等复杂度页面线框|3|2025-02-15字段依次是技能名称、熟练度描述、熟练度等级1到5、最后使用日期。这个格式的好处是人眼可读脚本也好解析。你完全可以用Markdown表格代替但纯文本的编辑摩擦最小。2.3 脚本要解决的核心问题查询与提醒纯文本的缺点是查起来麻烦。所以脚本要干两件事第一按熟练度或关键词过滤第二找出那些“很久没用”的技能提醒你该复习或该放弃了。第二点尤其重要因为技能这东西不用就会退化清单上留着一堆“曾经会”的条目除了自我安慰没有任何价值。我用的脚本逻辑很简单Python标准库就能搞定不需要装任何第三方包。读取文本文件按行解析过滤输出。后面我会把完整代码和参数计算过程贴出来。3. 核心细节解析字段定义与熟练度分级3.1 熟练度等级怎么定才不拍脑袋1到5级如果只是“了解、熟悉、掌握、精通、专家”那跟没定一样因为每个人对“精通”的理解天差地别。我采用的是行为锚定法每一级都对应一个可观察的行为等级行为描述典型场景1知道概念需要照着教程做第一次接触能跑通示例2能独立完成简单任务但需要查文档写个小脚本偶尔卡壳3能独立完成中等任务很少查文档日常开发主力技能4能解决复杂问题能指导他人团队内被请教的对象5能设计解决方案能处理边界情况遇到疑难杂症第一个想到你这个表我建议你根据自己的领域微调但核心原则不变每一级都要有“别人能观察到”的行为证据。这样你在评估时问自己“我上次做这件事是什么时候当时卡了多久”答案自然就出来了。3.2 最后使用日期为什么比“学习日期”更重要很多人记录技能时喜欢写“学习时间”但那个日期只会越来越旧没有任何行动指导意义。而“最后使用日期”是一个动态指标它直接告诉你这个技能还活着吗我给自己定了一条规则超过90天没用过的技能自动降一级超过180天没用过的标记为“待评估”。这个阈值不是拍脑袋来的。对于大多数实践型技能90天是一个记忆保留的临界点超过这个时间重新捡起来需要明显的热身成本。180天基本意味着你已经忘了大半要么重新学要么从清单里删掉。脚本里我会用当前日期减去最后使用日期算出天数然后按阈值分类输出。这样每周跑一次就知道哪些技能该练了哪些该删了。3.3 技能分类标签的轻量做法纯文本方案里加分类标签最省事的办法是在技能名称前加前缀比如“编程-Python脚本”“设计-Figma线框图”。但前缀多了会显得乱。我的做法是单独加一个字段用逗号分隔多个标签Python脚本开发|能独立编写数据处理脚本|4|2025-03-01|编程,数据处理这样脚本可以按标签过滤比如只看“编程”类或者排除“软技能”类。标签数量控制在3个以内多了就失去分类意义了。4. 实操过程从零搭建你的skills管理系统4.1 第一步初始化技能清单文件新建一个文本文件命名为skills.txt编码用UTF-8。第一行可以写个注释以#开头脚本解析时跳过。然后按上面的格式一行一条技能。刚开始不用追求完整先把你能想到的、最近半年实际用过的技能写进去大概20到30条就够了。我建议你花15分钟做这件事不要边写边纠结措辞。先写下来后面再改。写完后用编辑器的排序功能按熟练度等级排一下你会立刻发现哪些技能是“虚高”的——那些等级4但最后使用日期是去年的明显有问题。提示如果你用VS Code可以装一个“Sort Lines”插件选中所有行一键按字段排序。如果没有插件用命令行sort -t| -k3 -nr skills.txt也能按第三列降序排。4.2 第二步写解析与查询脚本下面是我实际在用的Python脚本只依赖标准库复制到一个.py文件里就能跑。我加了详细注释方便你按自己的字段调整。import datetime # 配置区根据你的实际字段调整 SKILL_FILE skills.txt LEVEL_NAMES {1: 知道, 2: 能简单用, 3: 熟练, 4: 精通, 5: 专家} STALE_DAYS 90 # 超过这个天数未使用降级提醒 OBSOLETE_DAYS 180 # 超过这个天数未使用建议删除 def parse_skills(filepath): 读取技能文件返回技能字典列表 skills [] with open(filepath, r, encodingutf-8) as f: for line in f: line line.strip() if not line or line.startswith(#): continue parts line.split(|) if len(parts) 4: continue # 字段不足跳过 name parts[0].strip() desc parts[1].strip() level int(parts[2].strip()) last_used datetime.datetime.strptime(parts[3].strip(), %Y-%m-%d).date() tags parts[4].strip().split(,) if len(parts) 4 else [] skills.append({ name: name, desc: desc, level: level, last_used: last_used, tags: [t.strip() for t in tags if t.strip()] }) return skills def days_since(date): 计算距今天数 return (datetime.date.today() - date).days def filter_by_tag(skills, tag): 按标签过滤 return [s for s in skills if tag in s[tags]] def filter_by_level(skills, min_level): 按最低熟练度过滤 return [s for s in skills if s[level] min_level] def find_stale(skills): 找出需要复习或删除的技能 stale [] obsolete [] for s in skills: d days_since(s[last_used]) if d OBSOLETE_DAYS: obsolete.append((s, d)) elif d STALE_DAYS: stale.append((s, d)) return stale, obsolete def print_report(skills): 打印完整报告 print( * 50) print(f技能总数{len(skills)}) print( * 50) # 按等级分组统计 level_count {} for s in skills: level_count[s[level]] level_count.get(s[level], 0) 1 print(\n各等级分布) for lv in sorted(level_count.keys(), reverseTrue): print(f {LEVEL_NAMES.get(lv, lv)}{lv}级{level_count[lv]} 条) # 过期提醒 stale, obsolete find_stale(skills) if stale: print(f\n超过{STALE_DAYS}天未使用建议复习) for s, d in stale: print(f {s[name]}{d}天前当前{s[level]}级) if obsolete: print(f\n超过{OBSOLETE_DAYS}天未使用建议评估是否删除) for s, d in obsolete: print(f {s[name]}{d}天前当前{s[level]}级) if __name__ __main__: skills parse_skills(SKILL_FILE) print_report(skills)这个脚本跑起来后输出大概是这样 技能总数28 各等级分布 精通4级6 条 熟练3级12 条 能简单用2级8 条 知道1级2 条 超过90天未使用建议复习 Figma线框图112天前当前3级 SQL查询优化95天前当前4级 超过180天未使用建议评估是否删除 某旧版框架开发210天前当前2级看到这个输出你的行动优先级就非常清楚了。我一般每周一早上跑一次花5分钟看一眼然后决定这周练哪个技能。4.3 第三步参数阈值的计算依据前面提到的90天和180天我是这么算出来的。假设一个技能你达到3级熟练需要大约100小时的实践那么遗忘曲线在没有任何复习的情况下90天后大约会退化到2级水平也就是需要重新花20到30小时才能恢复。而如果你在90天内用过一次哪怕只是半小时恢复成本会降到2小时以内。180天的依据更简单大多数技术类技能的半衰期在6到12个月之间超过180天没用要么说明这个技能在你的实际工作里根本不重要要么说明你已经转方向了。两种情况都指向同一个动作从清单里删掉或者降级到1级并标注“已生疏”。注意这个阈值对语言类、软技能类可能不适用。比如“公开演讲”这种技能半年不用不代表你忘了只是没机会用。所以我在脚本里没有强制降级只是输出提醒最终决策还是人来做。4.4 第四步定期维护的节奏我自己的节奏是每周一跑脚本看提醒每月初花20分钟更新一次清单每季度做一次大清理。更新清单时只做三件事把上周实际用过的技能日期改成今天把新学的技能加进去把脚本标记为“建议删除”且自己确认不再需要的条目删掉。这个节奏听起来很轻但坚持三个月后你会发现清单上的条目从最初的30条精简到20条左右但每一条都是活的、准的。这比列100条“曾经会”的技能有价值得多。5. 常见问题与排查技巧实录5.1 脚本报错“字段不足”怎么办最常见的原因是技能描述里用了竖线比如“能写Python|Java脚本”这样split后字段就乱了。解决办法有两个要么在描述里避免使用竖线用顿号或斜杠代替要么把分隔符改成更少见的字符比如::。我选的是后者因为竖线在Markdown表格里也容易冲突。改分隔符只需要改两处文本文件里的分隔符和脚本里split(|)改成split(::)。其他逻辑不变。5.2 日期格式写错导致解析失败datetime.strptime对格式非常严格2025-3-1和2025-03-01是不一样的。我的建议是统一用YYYY-MM-DD格式并且在脚本里加一个try-except遇到解析失败的行就打印行号和内容方便定位。try: last_used datetime.datetime.strptime(parts[3].strip(), %Y-%m-%d).date() except ValueError: print(f日期格式错误跳过第{line_num}行{line}) continue5.3 技能太多导致报告太长如果清单超过100条报告会刷屏。这时候可以用命令行参数控制输出比如只看4级以上的或者只看某个标签的。我在脚本里预留了filter_by_tag和filter_by_level函数你可以在__main__里按需调用。# 只看编程类且3级以上的技能 filtered filter_by_level(filter_by_tag(skills, 编程), 3) for s in filtered: print(f{s[name]} - {s[level]}级 - 最后使用{s[last_used]})5.4 常见问题速查表问题现象可能原因解决方法脚本无输出文件路径不对或文件为空检查SKILL_FILE路径确认文件有内容某条技能不显示字段数不足4个检查该行是否缺少竖线分隔日期计算为负数最后使用日期填成了未来检查日期是否手误写错年份标签过滤无效标签字段有空格在split后加.strip()去除空格中文乱码文件编码不是UTF-8用编辑器另存为UTF-8编码5.5 一个容易被忽略的坑不要用“学习时长”代替“使用日期”我见过有人把“最后使用日期”填成“最后学习日期”比如看了一篇教程就更新日期。这会导致脚本误判你还在活跃使用这个技能。只有实际动手做过、交付过成果才算“使用”。看教程、读文档不算。这个区分很关键否则你的清单会充满虚假的活跃度。6. 后续扩展方向从个人到小团队个人用顺了之后这套东西很容易扩展到小团队。最简单的做法是把每个人的skills.txt放在共享目录里脚本加一个参数读取整个目录然后按人名聚合输出。这样团队负责人一眼就能看到谁有什么技能、哪些技能团队里只有一个人会单点风险、哪些技能整体都生疏了。再进一步可以把文本文件换成SQLite数据库脚本改成带Web界面的小工具。但我的建议是不要急着上数据库。先用纯文本跑三个月等你真正养成了每周维护的习惯再考虑要不要加界面。大多数人的问题不是工具不够好而是根本坚持不下来。我在实际使用中最大的体会是技能清单的价值不在于“记录”而在于“触发行动”。每次看到“112天未使用”的提醒我就会问自己这个技能我还需要吗需要就安排时间练不需要就删掉。这个简单的决策循环比任何复杂的评估模型都管用。