新闻详情

新闻详情

首页 / 资讯中心 / 详情

基于Markdown的个人技能树管理系统:从目录设计到自动化脚本实践

发布时间:2026/9/9 10:55:51来源:尧图网络
基于Markdown的个人技能树管理系统:从目录设计到自动化脚本实践
1. 项目概述这个叫 skills 的东西到底解决了什么问题老规矩先说结论我最近在维护的开源项目skills本质上是一套基于 Markdown 的「个人技能树管理系统」。项目目录名就叫skills里面没有一行业务代码全是结构化的.md文件和几个辅助脚本。说实话一开始做这个项目就是因为受不了自己的技术栈管理太混乱。我试过 Notion、语雀、飞书文档甚至试过在 Excel 里列技能清单但最后都放弃了。原因很简单这些工具要么太重要么数据锁死在某个平台里要么没法跟我的开发工作流打通。我想要的东西其实特别朴素——用纯文本记录我会什么不会什么正在学什么然后能随时检索、能追踪变化、能生成给简历和面试用的概览而这一切最好就在我天天都在用的 IDE 里完成。所以skills这个项目就诞生了。它的核心使用方式是你想要目录结构加上几个约定的 Markdown 字段然后靠一系列小型工具脚本把一个看起来像笔记合集的文件夹变成一套可以可视化、可搜索、可维护的技能图谱。对于经常要复盘、跳槽、带新人或者做年度规划的技术从业者来说这套东西的价值在于它把「技能管理」从一件靠脑子记的事变成了一件像写代码一样有结构、可复用、能自动化的事。这个项目适合谁用我觉得适合三类人第一类是像我一样对 Markdown 有执念、喜欢数据握在自己手里的开发者第二类是经常要做团队技能盘点或者带实习生的技术负责人需要快速看清每个人会什么第三类是正在准备面试或者做职业规划的人需要一个诚实、清晰、随时更新的技能清单。这篇文章我就把整个项目从头到尾拆开讲包括目录设计、字段规格、脚本实现以及我踩过的几个坑希望能给你一个可以直接照着抄的方案。2. 内容整体设计与思路拆解2.1 为什么非要用 Markdown 而不是现成知识库工具在动手之前我其实认真想过这个问题市面上有那么多现成的技能管理工具为什么非要自己搭我的答案有三层。第一层是数据所有权。Notion、语雀这类在线文档工具数据虽然能导出但导出之后的格式基本就废了结构丢失、图片散落、表格错乱。而 Markdown 本身就是纯文本任何一个编辑器、任何一个操作系统、哪怕是十年后打开这个文件夹文件还在内容还能读格式不会坏。这对一个持续记录了几年的技能库来说是最大的安全感。第二层是和开发工作流打通。我的日常就是在 IDE 里写代码、在终端里敲命令如果技能管理还要切到另一个网页应用那我大概率懒得更新。把skills做成一个本地目录之后我可以直接在 VS Code 里打开、编辑、保存配合 Git 做版本管理每次修改技能的 diff 都清清楚楚。第三层是可编程性。文本格式最大的优势就是可以被程序处理。我可以用 grep 搜、用脚本统计、用模板批量生成报告、甚至可以接进 CI 流水线做自动化仪表盘。这些能力是任何一个所见即所得工具都给不了的。当然我也承认Markdown 方案有它的代价比如没有图形化拖拽、没有日历视图、没有表格自动联动。所以我在设计时就定了一条原则不追求好看追求信息和结构不失真。只要结构对了展示层可以随时用脚本生成。2.2 设计目标让技能管理像写代码一样有章法在搭建skills项目时我给自己定了四个设计目标每个目标都对应了实际使用中遇到过的痛点。第一个目标是可检索。以前我在 Excel 里列技能清单一旦超过 50 行就乱成一锅粥想查一个技能得用肉眼扫半天。现在所有技能都拆成独立文件文件名就是技能名目录结构就是分类随手一个grep -i就能定位。第二个目标是可追踪。技能不是一成不变的三年前我熟练写 jQuery现在基本不碰了上个月开始学 Rust这个月已经能写点小工具。skills为每个技能文件设计了状态字段active/learning/paused配合 Git 提交记录就能看到一条完整的技能演进时间线。这个对年底写总结或者做职业复盘特别有用。第三个目标是可量化。光说我会 Python没有任何信息量得说清楚是学了两周的 Python还是写了五年生产级 Python。我给每个技能加了level字段分 1 到 5 五档每档都有明确的定义避免自己骗自己。第四个目标是可展示。技能数据不能只躺在文件夹里得有出口。所以配套脚本可以一键生成两个东西一个带进度条的 Markdown 报告方便贴到 README 或者博客一个 JSON 数据文件方便接入其他工具或页面渲染。这四个目标贯穿了整个项目设计的始终。后面每一个字段、每一个脚本都是围绕这四个目标去落地的。3. 核心细节解析与实操要点3.1 目录结构怎么搭分类、粒度与命名规范先给你看我现在实际在用的skills目录结构这是经过好几轮调整之后稳定下来的版本skills/ ├── README.md # 总览索引脚本自动生成 ├── _template.md # 技能文件模板 ├── _scripts/ │ ├── build_index.py # 生成 README 索引 │ ├── validate.py # 校验字段合法性 │ └── export_json.py # 导出 JSON 数据 ├── language/ │ ├── python.md │ ├── go.md │ └── typescript.md ├── framework/ │ ├── react.md │ ├── vue.md │ └── fastapi.md ├── devops/ │ ├── docker.md │ ├── kubernetes.md │ └── github-actions.md ├── database/ │ ├── postgresql.md │ └── redis.md └── soft-skills/ ├── code-review.md ├── technical-writing.md └── public-speaking.md这套结构的关键决策有三个我一个个说。第一个决策是分类不搞二级以上嵌套。我试过在language下面再分backend和frontend结果发现层级越深越难维护。技能之间的关系本来就是网状的——TypeScript 既是语言也是前端工具链的一部分FastAPI 既是框架也跟 Python 强相关——硬要套树状结构会造成大量重复和归类困难。所以干脆只分一级目录一个技能只归一个最贴切的类宁可在文件内部用标签字段去表达跨领域属性。第二个决策是文件名就是技能名不搞编号前缀。有些笔记系统喜欢用01-python.md这种编号维护顺序但我发现技能之间没有天然的先后顺序编号只会让你在新增技能时纠结插在哪个位置。直接用python.md这种名字按字母序排列简洁清晰配合 Git 提交历史时间线一目了然。第三个决策是模板文件必须单独存在。_template.md是新建技能时的起点里面包含了所有字段的样例和说明。这个文件的价值不只是规范更重要的是降低新建一条技能记录的心理门槛——打开模板、复制、改内容、保存一分钟搞定不用回忆字段规则。3.2 技能文件字段设计YAML 头部 正文备注的黄金组合一个技能文件的完整结构长这样以framework/react.md为例--- name: React category: framework status: active level: 4 level_label: 熟练 since: 2019-03 last_updated: 2024-11-15 tags: [frontend, ui, ssr, state-management] related: [typescript, nextjs, redux] resources: - name: React 官方文档 url: https://react.dev/ - name: 重学 React 实战课 url: https://example.com/ --- ## 熟练场景 - 独立设计并维护中后台前端应用包含复杂表单、权限路由、数据可视化面板 - 基于 React 18 的并发特性优化长列表渲染性能首屏时间降低 40% ## 日常使用 - 状态管理以 Zustand 为主Redux Toolkit 用于大型团队协作场景 - 服务端渲染用 Next.js 14App Router部署在 Vercel 上 ## 待深入方向 - React Compiler 的原理与自动 memo 优化机制 - Server Components 边界设计注意这个文件的核心信息都在开头的 YAML 头部里正文部分是用来补充上下文。这个设计我琢磨了很久最终确定了以下字段每个都有它的必要性和坑。name 和 category是基础字段必须跟目录和文件名保持一致这点我建议写进校验脚本里强制检查防止文件移动之后信息失真。status字段我用的是active / learning / paused三态模型active表示当下正在频繁使用、保持生产级水平learning表示正在系统学习、还没达到稳定输出水准paused表示曾经会但现在已经不用了、随时可能生疏。这个三态模型比单纯的布尔型会/不会要诚实得多也直接决定了技能在索引里的排序权重。level字段我用了 1 到 5 档每一档的含义在模板里有明确定义等级名称定义典型表现1了解知道概念能读懂代码能回答这是什么不能独立完成功能2入门能在指导下完成简单任务看过教程做过 demo 级项目3熟练能独立完成常规任务在真实项目中使用过能解决大部分问题4精通能设计解决方案并指导他人带过新人、做过架构决策踩过深坑5专家能推动团队技术方向有完整的方法论能识别和规避潜在风险等级定义一定要写成这种行为锚定的形式而不是抽象形容词。我最初用的是一般、良好、优秀这种词没过两周就发现评级极其随意。改成行为锚定描述之后自评的可靠性明显提升。since 和 last_updated是追踪字段。since记录初次接触的时间last_updated字段可以配合脚本自动更新——我建议在 Git 的pre-commit钩子里加一行脚本自动把这两个字段刷新。手动维护日期很容易忘而这两个日期是时间线功能的数据基础。tags 和 related是关联字段。tags是一组关键词用来做横向搜索和聚合related是相关技能用来表达依赖关系。这两个字段也需要注意克制数量不宜超过 5 个多用名词短语保持风格统一。正文部分我固定了三个二级标题熟练场景、日常使用、待深入方向。这些不是硬性要求但一致的结构有助于快速浏览。关键是正文要写能证明你水平的具体场景而不是空泛的熟悉 React 生态——说实话面试官看简历最反感的就是这种废话。4. 实操过程与核心环节实现4.1 从零搭建初始化项目、设计模板、落地第一批技能说实话刚开始搭这个项目的时候我也走了不少弯路。第一步差点就去搞一个复杂的数据库 schema后来意识到这不是在建系统而是在建一套「跟我自己的使用习惯高度匹配的文本规范」。所以我建议你跟着我的精简流程走别搞重。初始化项目其实就三步建目录、放模板、配置 Git。mkdir skills cd skills mkdir -p _scripts language framework devops database soft-skills touch _template.md README.md git init第二步是关键把_template.md写好。这个模板我前后改了四个版本最终稳定成下面这样你可以直接抄--- name: 技能名跟文件名保持一致 category: 所属分类如 language / framework / devops status: learning | active | paused level: 1-5具体标准见 README 底部 since: YYYY-MM初次接触时间 last_updated: YYYY-MM-DD更新当天 tags: [标签1, 标签2] related: [关联技能文件名称] --- ## 熟练场景 自己做过什么实际项目、解决过什么问题。写具体不要写形容词。 ## 日常使用 平时怎么用配合哪些工具和技能。 ## 待深入方向 还想学什么、还没搞明白的部分。填写模板也有几个要点status 和 level 不要想着一步到位刚开始记录时都填得保守一点后面根据实际项目情况慢慢修正since 填不准没关系大概到月份级别就行资源列表一定要填因为等你真正深入学的时候重新找入门资料非常浪费时间。第三步不是写一堆技能而是先把第一批技能控制在 10 个以内每个文件都认真填。这一批是种子数据质量和可信度直接决定了你这个系统后续能不能用下去。贪多嚼不烂——一口气填 50 个技能文件的结果就是几乎全部停留在字段层面没有上下文最后还是废的。补充一句我踩过的坑是category 分类建议首字母大写、用单数名词跟目录名严格一致。这样脚本校验的时候不用做大小写转换省心。4.2 自动化脚本实现build_index.py 把零散文件变成可视化索引纯 Markdown 文件堆在那里其实没有用HTML 不会自己长出来。所以脚本的核心目标有两个一是校验数据完整性二是自动生成 README 索引这就用一个 Python 脚本搞定。我用 Python 实现了一个build_index.py工作流分成三层第一层是读取与解析。用 PyYAML 解析每个.md文件的 YAML 头部同时用正则提取正文的第一段内容作为技能的短描述。这里有个小技巧ast.literal_eval可以把tags里的字符串解析成 Python 列表避免 YAML 在某些边界情况下的解析问题。第二层是聚合与排序。把所有技能按category分组每组内先按statusactive learning paused排序再按level降序排序。这样生成的 README 里每个分类下的技能从上到下就是核心能力到边缘技能的梯度快速概览时非常顺眼。第三层是渲染输出。用 Markdown 表格输出每个分类的技能列表带上等级、状态和时间字段然后在文件末尾加上统计汇总。我用的是 Jinja2 模板因为直接在 Python 里拼字符串一旦格式复杂就会乱。核心模板片段长这样def render_group(group_name, items): lines [f### {group_name}, ] lines.append(| 技能 | 等级 | 状态 | 最近更新 | 简述 |) lines.append(|------|------|------|----------|------|) for item in items: lines.append( f| [{item[name]}]({item[filename]}) | f{item[level_label]} | {item[status]} | f{item[last_updated]} | {item[summary][:20]} | ) return \n.join(lines)运行方式是cd skills python3 _scripts/build_index.py cat README.md脚本跑完README 会刷新成最新的技能清单。我个人的习惯是每次新增或者修改技能文件之后顺手跑一遍然后提交 Git。如果你愿意也可以把这个脚本挂进 Git 的pre-commit钩子每次git commit自动重新生成索引从源头杜绝README 和实际文件不一致的问题。4.3 进阶脚本validate.py 校验规则让数据永远干净有了基础索引之后我很快就遇到了新问题手写 Markdown 一定会出格式错误。不是忘了 YAML 字段就是date格式写错了或者是文件名跟name字段不一致。最离谱的一次我把status写成了activ索引脚本没有报错只是这个技能在排序时掉到了最后面而且界面上没有任何提示。所以第二个脚本validate.py是维持数据卫生的红绿灯。它的核心校验规则可以做成一张清单按重要性排必填字段是否齐全缺一不可用字段集合对比status值是否在枚举范围内只能三个值三选一level是否为 1 到 5 的整数类型转换失败直接报错since和last_updated是否符合YYYY-MM和YYYY-MM-DD格式用正则校验category是否跟实际存在的目录名匹配这个我最看重name字段跟文件名是否一致不一致就直接提示tags和related是否为列表类型列表元素都必须是字符串这个校验脚本虽然只有不到 100 行但是维护体验改善是立竿见影的。现在编辑完技能文件先跑一遍python3 _scripts/validate.py看到All checks passed再提交再也不用担心脏数据进入索引图了。这里我强烈建议你校验脚本一定要做不要觉得我写 Markdown 很仔细所以不需要。人总有粗心的时候脚本的意义就是当那个永远不放假的安全员。4.4 维护节奏每周 10 分钟的技能数据保鲜术系统搭好之后真正的挑战是维护。我的习惯是每周五下午花 10 分钟做一次技能数据的「保鲜」操作具体流程很简单第一步扫描一下本周的工作内容。这周写了什么模块、用了什么新技术、解决了什么有价值的问题。第二步回到skills目录看看有没有对应的技能文件。如果有就更新last_updated、level把新的实事写进熟练场景如果没有就新建一个技能文件。第三步如果某个技能这周完全没有碰过不要急着删改status为paused就好因为最近没碰和彻底不用了是两回事。第四步跑一遍validate.py和build_index.py确认数据干净、索引更新然后git commit。这套流程的关键在于频率低、动作小。一次更新 10 个技能文件跟你每隔三天花半小时维护相比前者更容易养成习惯。我把skills项目放在个人 Git 仓库里每次 review 自己过去几个月的提交记录就像看自己的技术成长日记这对于做复盘或者年度规划都是非常宝贵的素材。5. 常见问题与排查技巧实录5.1 目录越用越乱分类边界模糊怎么办这是我最常被问到的问题也是我自己经历了至少三次重构才彻底想明白的事。症状很典型一开始分类很清晰用着用着发现有些技能不知道该放哪个目录了。举个例子nextjs到底是放framework还是languageredis到底是放database还是devops每次新建技能文件都要纠结半天。我的解决方案是三个字认死理。给每个分类写一个收件标准写在 README 底部的规范区。比如language编程语言本身不管编译器framework别人写好的、你直接引用的开发框架和库devops跟部署、CI/CD、环境配置相关的工具和实践database存储数据的系统或服务然后硬性规定一个技能只能归入一个目录按照它的第一属性归类不要试图完美。Next.js 既算是框架也涉及服务端渲染但它的第一属性是 React 生态框架所以放frameworktags里加一个react就够了。Redis 既做缓存也做消息队列第一属性是数据存储服务所以放databasetags里加cache和queue。就这一条规则直接终结了分类纠结症。5.2 脚本报错合集YAML 解析失败、中文乱码、日期格式不一致用 Python 处理 Markdown 文件最常见的坑有两个我在这里统一说免得你走弯路。第一个是中文乱码。在 Windows 上如果直接用open()读 Markdown默认编码可能是gbk中文字符会直接报错。解决办法是强制指定编码with open(filepath, encodingutf-8) as f: content f.read()第二个是YAML 解析边界情况。如果正文里出现了---分隔线而这行没有缩进层级PyYAML 会错误地把后续内容也当作 YAML 处理导致解析直接崩溃。我的规避方案很简单YAML 头部之后禁止出现---。如果你确实需要水平分割线用 HTML 的hr代替。这个约束写进模板可以省很多莫名其妙的排查时间。还有一个常见问题是日期格式不统一。since字段我写2024-11last_updated写2024-11-15两者格式不同是故意的因为一个是月份精度、一个是精确到天。但如果你在别的技能文件里把since写成了2024.11或者last_updated写成了2024/11/15校验脚本就会通过datetime.strptime直接报错。从项目第一天起就要统一格式不要在看似能跑的宽松校验下埋雷。5.3 自评等级不准怎么避免自己骗自己level字段是整个系统里最容易被主观扭曲的部分。我见过有人三个月就把kubernetes填到了4档也见过干了十年的老后端把自己的python只填到3档。偏差方向虽不同但都让数据的参考价值大打折扣。我个人的校准方式有三种结合起来用。一种叫面试官自问法。给自己的技能打分之前先问自己一个问题如果我是在面试别人对方简历上写着精通 React我第一反应是追问他什么顺着这个问题想出来的追问点就是你自己当前最心虚的短板。如果完全没有追问点那这个4档才真的站得住。另一种叫输出物检验法。你在这个技能上最近的产出是什么是一篇技术博客、一个开源 PR、还是带同事做的一个项目模块有高质量的、最近三个月内的可公开输出物才可以支撑4档以上。如果没有老老实实降到3。最后一种叫责任范围法。你在这个技能上有没有真的负责过让别人依赖你的产出的事情比如团队里别人搞不定的 React 性能问题会不会来找你如果会4档没问题如果只是自己写完自己用那撑死3档。这三种方法交叉验证基本能把自评的置信度拉到可接受的范围。记住这套系统的第一个使用者是你自己数据如果骗人最后坑的也是你自己。6. 进阶玩法把 skills 数据变成你的履历引擎如果你的skills已经稳定跑了一两个月数据文件都积累到二三十个了这时你可以解锁它的真正价值把技能库变成简历、周报和面试准备的原材料库。第一个玩法是简历生成器。我写了一个很小的export_resume.py逻辑只有三步从所有level 3且status active的技能里按分类挑出核心技能然后到对应技能文件正文里抓取熟练场景的内容格式化成语录式的条目最后输出一份 Markdown 简历稿。你看现在的简历写作技巧里都在强调量化成果而skills正好就是天然的量化素材库——每个熟练场景都是一条实打实的 STARR 结构素材。第二个玩法是能力雷达图数据源。export_json.py脚本可以把所有技能输出成一个 JSON 文件前端用 ECharts 画雷达图纵轴是技能类别横轴是等级。我搭了一个简单的 HTML 页面挂在 localhost 上做季度复盘时打开看一眼哪个类别平均等级下降、哪个方向有明显提升一目了然。不夸张地说这个页面比起任何付费的职业规划工具都更懂我。第三个玩法是面试问答模拟。方法特别土但特别有效写一个脚本遍历所有status paused或level 2的技能列成一份薄弱点清单。面试前看一遍这份清单你就知道这次面试最需要提前准备的防御性话题是什么了——不是「我很厉害的技能」而是「曾经写过但已经忘了的技能」这些才是面试官的必问点。所以说skills这个项目的尽头根本不是维护一套文档而是养出一份属于你自己的、结构化的职业成长数据库。数据量足够大之后你会开始注意到很多有意思的趋势——比如你每年会新增哪些类别的技能、哪些技能两年前填了4档现在掉到了2档、以及你在学新东西上的真实节奏是快是慢。这些回看比任何计划表都更能帮你理清职业方向。我个人现在最习惯的做法是每个季度结束后的那个周五下午泡杯茶跑一遍脚本盯着新生成的 README 和 JSON 看十分钟。很多时候不写长篇总结就只是看一眼心里就有数了。这套系统不炫技、不复杂但它是我这些年做过的最值得的维护型项目之一。
网站建设高端定制企业官网
RELATED

相关资讯

更多精彩内容,欢迎继续阅读

较早相关资讯

最新相关资讯

终端侧AI芯片选型指南:从ESP32-S3到RK3588与Orin Nano 2026/9/9 11:41:01

终端侧AI芯片选型指南:从ESP32-S3到RK3588与Orin Nano

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

阅读更多 →
100G UDP上板测试实战:FPGA高速网络工程落地指南 2026/9/9 11:41:01

100G UDP上板测试实战:FPGA高速网络工程落地指南

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

阅读更多 →
openwhispr:本地语音转写利器,隐私安全零成本的Whisper封装方案 2026/9/9 11:41:01

openwhispr:本地语音转写利器,隐私安全零成本的Whisper封装方案

1. openwhispr是什么:一个被低估的本地语音转写利器 最近在折腾本地语音转写方案的时候,无意间发现了一个叫 openwhispr 的开源项目。名字看着像是 open whisper 的变体写法,实际上它确实和 OpenAI 的 Whisper 模型有千丝万缕的关系——你可…

阅读更多 →
AI本地开发避坑指南:识别ruflo误传与替代方案 2026/9/9 11:41:01

AI本地开发避坑指南:识别ruflo误传与替代方案

1. “ruflo”不是工具,是当前AI开发圈里一个正在快速消散的误传信号 最近两周,在多个技术社区、VS Code插件讨论区和本地AI部署群组里,“ruflo”这个词高频出现——但它既不是官方发布的CLI工具,也不是某个开源项目的正式名称&…

阅读更多 →
OCL功放功率增益的三重耦合建模与工程修正 2026/9/9 11:41:01

OCL功放功率增益的三重耦合建模与工程修正

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

阅读更多 →
马尾怎么扎才好看?发型师详解高度、松紧与碎发处理技巧 2026/9/9 11:38:01

马尾怎么扎才好看?发型师详解高度、松紧与碎发处理技巧

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

阅读更多 →

今日资讯

本周资讯

本月资讯

看完文章仍有疑问?

联系尧图顾问,获取一对一建站咨询

立即免费咨询 📞 400-888-8888
📞