事情得从办公室那声“老登”说起。我组里几个年轻人,平时管我这个工作十二年、现在主攻 AI 应用落地的人叫“老登程序员”。上个月我花半天时间把 agentskill.work 从空白仓库做到全量上线,回来之后他们再喊这个称呼,我答应得比谁都快。这个项目是一个给 AI Agent 使用的技能包分享站,把大模型干活时需要的那套标准化流程、工具参数、提示词模板打包成一个个 SKILL.md 文件,让人可以浏览、筛选、复制、提交并查看说明。如果你也想尽快上线一个内容型小产品,又想在第一版就把部署、SEO、自动化审核全部安排明白,那这篇记录应该能给你省下不少时间。
1. 为什么偏偏是 agentskill.work
1.1 一次群聊引发的立项
起因很简单。上周一个技术群里有人晒了个三天完成的 Agent 工作流平台,界面很花哨,接了模型、接了很多工具,但点进去发现核心技能定义散落在数据库和代码里,别人根本没法复用。我当时就一个想法:这东西要能“标准化、可分享”,才算真正有点价值。
所谓 Agent 技能,说人话就是给大模型搭配的一套可复用的操作说明书。核心是文本协定:一个 SKILL.md 文件说明“什么时候调用、调用时需要哪些参数、按什么流程处理”,再配上一组脚本或资料文件,让 Agent 遇到对应任务时能按部就班地用起来。很多场景里的可靠性就是这么来的,因为提示词是软的,但流程定义是硬的。
我随手起了个名字 agentskill.work,拆开就是 agent、skill、work。思路很清楚:做一个公开的技能包仓库站点,让每个人都能提交自己的 SKILL.md,其他人能看到它适合什么场景、依赖哪些工具、怎么安装,一键复制到本地或者自己的 Agent 项目里。群里那个人做的是“平台”,我做的是“基础设施”,两者不冲突,而且后者内容涨起来之后价值会越来越厚。
立项通常用不着一整张 PPT,能说得清三个问题就够了:给谁用、解决什么麻烦、跟已有方案有什么差异。这个项目的用户就是 Agent 开发者和使用者,麻烦在于技能不透明、不互通、到处复制粘贴又没人维护版本。
1.2 老登的技术选型哲学
年轻人听说我要半天上线,第一反应是用一套前端重型框架加实时数据库,再配一堆模型网关、向量库,听起来很稳妥,但半天根本做不完。老登的哲学不一样:能用静态生成器就不上服务端渲染,能用纯文本存数据就不建数据库,能交给托管平台执行构建就不自己买服务器。
我的最终选型是:Next.js 做静态导出,内容全部以 Markdown 文件存在 GitHub 仓库里,部署走 Vercel,DNS 用 Cloudflare 管理。有人可能觉得这组合不够“新”,但每一项都是为内容型站点量身定制的。
- Next.js 的静态导出能力可以把每个技能详情页提前生成成 HTML,访客访问时不需要任何 Node 进程,加载极快,天然抗爬。
- Markdown 文件自带可读性,人类能直接 review 内容,机器也能通过固定路径快速解析。
- GitHub 是天然的存储引擎和协作后台,大家提交技能包不是往数据库里灌数据,而是提 Pull Request。
- Vercel 在我 push 到 main 分支后自动触发构建和部署,省掉所有运维心智负担。
为什么强调“自动化能交出去就不手写”?因为上线的敌人不是功能少,而是变更链路长。当构建、预览、发布、回滚全部复用原生的托管平台能力,你就可以把精力集中在内容规则和审核逻辑上,而不是半夜爬起来重启服务。
1.3 把边界画出来再动手
半天项目有个残酷规律:你想得越宽,死得越快。我给自己立了三条不可违背的边界。
第一,首版不做账号系统。用户提交技能走 GitHub PR,站长在仓库里做人工审核,不需要注册、邮箱验证、权限分级。这意味着身份认证的复杂度直接被移除,同时审核流程天然留痕。
第二,首版不做在线 Agent 执行沙箱。让用户在网页里直接调模型、跑一遍技能,确实很酷,但会引入 API Key 管理、模型计费、超时任务清理这些深坑。首版老老实实做“预览 + 复制 + 下载”,在线执行后面用独立服务补齐。这样演示时也能说清楚 Value 在哪里,而不是用一个不停转圈的控制台糊弄人。
第三,首版全域只读。除了 GitHub 那边的 PR 提交,站内没有写操作,后端零接口,连表单都不用埋。
边界画完之后,整个项目就退化成一件极其舒服的事情:一个读取仓库文件并渲染成页面的静态站。剩下的时间全部砸在信息架构和内容规范上,因为那才是这个站点区别于普通作品集的地方。
2. 从零到上线的真实操作记录
2.1 半小时搭出站点骨架
老登做事第一板斧是把脚手架跑起来。系统里只要有 Node 和包管理器,一行命令就能得到带 TypeScript、Tailwind、App Router 的初始工程。这类项目 I/O 少、刷新频率低,我直接关掉了所有运行时特性,在 next.config.mjs 里显式声明静态导出。
const nextConfig = { output: 'export', images: { unoptimized: true }, trailingSlash: false, }; export default nextConfig;这里有个新手容易吃亏的点:用了 next/image 但忘了关图片优化,静态导出时构建会直接报错。大部分站点的技能封面都是普通图片,直接禁用优化就完事,反正部署在 CDN 前面图也快。
接下来搭三个顶层路由:首页、技能详情、提交页。提交页不接表单,只放一个按钮链到 GitHub 仓库的 Pull Request 页面,加清楚的操作指引。首页拆成 Hero 区域、标签筛选区和技能卡片列表;详情页按“概述、使用方式、配置参数、依赖、示例对话、版本记录”的顺序组织内容。
半小时搭出来的骨架主要是布局和视觉约束,不需要华丽,但要保证路子对:颜色用两三个中性色,字体默认多语言适配,卡片间距统一。丑一点没关系,内容没上来之前,美化和返工纯属浪费。
2.2 Markdown 数据流与静态渲染
设计数据流之前,我先把仓库内容组织方式定了。每个技能包占用一个目录,里面有一个 SKILL.md 作为主文件,可能还带 assets 目录放参考文档和脚本。SKILL.md 的头部用 YAML frontmatter 承载元数据,正文用标准 Markdown 写操作流程。
--- name: web-search-assist title: 内部文档检索助手 description: 帮助 Agent 在企业文档站里快速定位并总结相关信息 version: 0.3.0 tags: [搜索, 文档, 总结] tools: [web_search, extract_url, summarize] author: laodeng ---为什么选 Markdown 而不是 JSON?Agent 本身靠上下文文本工作,把技能写成文本文件,模型可以直接读取,人类也可以直接阅读和修改,版本管理又天然基于 git diff。JSON 虽然结构化,但对于非程序员来说门槛明显更高,也不利于写长流程。
页面侧的逻辑不复杂。构建时用一个脚本扫描 /skills 目录下的所有目录,读取每个 SKILL.md 的前置元数据,生成一份全局 index.json,同时给每个技能生成一个详情页面对象。用 Next.js 的 generateStaticParams,可以预先得到每个技能页的路径参数,然后逐页渲染。
export async function generateStaticParams() { const skills = await getAllSkills(); return skills.map((skill) => ({ slug: skill.slug })); }这一步是老登最看重的地方:数据是“静态”的,但绝不死板。访问者的筛选、搜索行为全部在前端完成——打开页面第一时间去 fetch 全局索引 JSON,然后根据标签和关键词做客户端过滤。为什么不上服务端搜索?因为内容总量少,索引文件小,客户端搜索响应毫秒级,还能减少一个故障源。等技能包超过几百个再考虑接入云搜索,这个演进路径是平滑的。
2.3 一键部署和域名解析
React 项目本地跑起来只算完成了一半,老登和“搬代码的”最大区别就在后面这两步:部署、上线、验证。我先把项目推到 GitHub 私有仓库,然后在 Vercel 上选择仓库并配置生产分支。Vercel 检测到 push 后自动执行 npm ci、npm run build,成功后生成一个可直接访问的预览地址,域名点击绑定即可。
域名这块,agentskill.work 的 DNS 由 Cloudflare 托管,操作顺序要谨慎。先在 Cloudflare 的 DNS 面板添加一条 CNAME 记录,指向 Vercel 提供的目标地址,再回 Vercel 的域名设置里填上 agentskill.work。我说实话,顺序反过来的话很容易出现域名可用但 HTTPS 证书迟迟签不下来的情况。CNAME 记录内容大概是:
agentskill.work -> cname.vercel-dns.com这里要提一个 DNS 生效的常识:修改解析后,全球生效时间通常在几分钟到二十四小时之间,和本地缓存强相关。验证时别用浏览器硬等,直接在终端敲一个查询命令看看结果更稳妥。
dig agentskill.work CNAME看到记录正确返回后,再访问域名看证书是否自动发好。整个部署过程我没写一行服务器配置脚本,也没有 ssh 登录任何机器。这套玩法最大的优势不是省一台虚拟机,而是让“上线”变成每天可以发生二十次的高频动作,而不是一个需要挑日子执行的仪式。
2.4 发布当天的 SEO 动作
半天上线的项目,流量不会因为域名好听就自己涌过来。我的思路很朴素:标题和描述里把核心词讲清楚,每个页面都给搜索引擎足够的结构化信息。
首页的 title 直接写成 “Agent Skills - 可复用的 AI Agent 技能包”,description 解释这个站是干什么的、适合哪些人。每个技能详情页的 title 就是“技能名 + 场景说明”,比如“内部文档检索助手 - Agent Skill”,保证搜索意图能精准匹配。
另外在每个详情页加入 JSON-LD 结构化数据。这里用同样来自 Markdown frontmatter 的字段,包括技能名称、简介、发布者、版本、标签。搜索引擎看到这些语义信息,更容易把页面当作一个标准物件来索引,而不是一堆无分类的 HTML。
我还会刻意保留一个 robots.txt 和站点地图。静态导出框架一般都能自动生成 sitemap.xml,但 robots.txt 我建议手写,明确允许全量爬取,并且把技能目录标记为优先。至于社交平台的分享卡片,我用一张动态生成的小图放在 /api/og 上,但首版没做复杂套壳,就用固定品牌图。
这些 SEO 工作看似琐碎,其实占不了半个小时。但对一个工具类内容站来说,它决定了你在前两周有没有自然搜索流量入口。标题里那个 agentskill 本身就是搜索热词的一部分,页面结构越清晰,越容易吃住这波精准需求。
3. 坑与排查:实战实录
3.1 差点翻车的三个瞬间
第一个坑是代码高亮。SKILL.md 正文里全是代码块、参数表格、shell 命令,如果渲染器选择不当,生成的页面会无比臃肿,首屏要加载几百 KB 的脚本。我用的是 react-markdown 配合一个轻量级代码高亮方案,只高亮不搞复杂交互,首版脚本体量控制在可以接受的范围。
第二个坑跟版本相关。某个技能包在 SKILL.md 里写了一个相对路径图,但站点目录结构和仓库里的目录结构不一样,导致页面 404。后来我统一了路径规则:标题里只允许用仓库根目录作为规范基准,渲染时再做一次路径 remap。这个设计很土,但在内容型项目里非常好用,直接消灭一类“本地正常、线上白屏”的问题。
第三个坑是中文内容的分页截断。有些技能说明特别长,我希望在列表卡片里显示摘要,而不是把全文切出来。为卡片做摘要时如果按字数盲切,很容易把中文标点切坏。最终的方案是在 frontmatter 里加一个 summary 字段,列表卡片只读这个字段,详情页才读全文。这样两个页面职责分离,内容作者也能完全控制展示效果。
3.2 搜索功能为什么没上服务端
项目上线前,年轻人问我搜索是不是该用 Elasticsearch 或 Algolia,我的回答是:不,用浏览器自带能力。站点内容只有几十个技能包,全局索引 JSON 也就几百 KB,浏览器控件读一次就能完成全量检索,速度根本不在一个纠结层级。
服务端搜索的方案不是不能用,但它会引入同步任务、索引构建、权限控制、费率消耗等一堆新问题。对一个首版只读、内容量可控的站点,这些都是过度设计。老登的判断标准其实很简单:当前规模下不值得做的事,就不做;等规模大了再做,也不算推翻重来。
如果你后续真的要做服务端搜索,我建议也不是一步跳到 Elasticsearch。可以用同一个 index.json 接到 Cloudflare Workers 或云函数里,做一个带关键词参数的小接口,缓存友好,成本可控。也就是说,演进路径应该是从“纯静态索引”到“一个轻量接口”再到“专业搜索服务”,而不是一上来就摆重型武器。
3.3 常见问题速查表
上线到今天,朋友和同事踩过的问题集中在下面这几类,我整理成一个速查表格,方便你直接抄作业。
| 症状 | 可能原因 | 处理方式 |
|---|---|---|
| 页面 404 或白屏 | 详情页路径与仓库目录结构不一致 | 统一使用仓库根目录作为路径基准,检查 generateStaticParams 的返回值 |
| 构建失败且报图片相关错误 | next/image 在静态导出时无法处理优化 | 在 next.config 中把 images 设为 unoptimized,或改用普通 img 标签 |
| DNS 改了解析但访问没变化 | 本地 DNS 缓存未过期 | 用 dig 命令确认记录,再尝试刷新本机缓存或切换网络验证 |
| 部署失败但本地构建正常 | 分支名不匹配或环境变量缺失 | 检查 Vercel 的 Production Branch 设置,确认提交的默认分支为 main |
| 中文摘要显示乱码或截断 | 前端按字节裁剪字符串 | 改用 frontmatter 中的 summary 字段,由内容作者控制长度 |
| 搜索无结果 | 全局索引 JSON 未更新 | 重新触发构建,确保脚本扫描技能目录后重新生成 index.json |
这些坑都算不上高级错误,但因为项目工期短,每一个都可能直接把半天压缩成一天。我会说,多踩一次,就对“为什么要自动化”多一分敬畏。
4. “老登程序员”的效率来源
4.1 不追求完美架构,追求可演进架构
年轻人做项目容易把架构设计当成交付物本身。我干了十几年,见过很多团队在首版就设计了七层抽象,结果产品没人用,代码先把自己累死了。老登做事的逻辑是:先找到能跑通的最小闭环,再考虑如何沿着同一套数据模型持续叠加功能。
agentskill.work 的整个架构核心只有一条数据路径:仓库里的 Markdown 文件 -> 构建时索引 -> 静态页面。后续所有功能演进都遵循一个原则:不断开这条链路,只往两端插东西。比如加入多语言支持,就是给文件加一个新的语言目录;加入版本对比,就是在 frontmatter 里加版本号,并保留历史文件;加入在线执行,就是在详情页加一个请求代理,复用已经定义好的技能参数。
这种架构的好处是“退路特别多”。哪天觉得 Next.js 太重,换一个静态站点生成器,只要数据格式不变,迁移成本就很低;哪天觉得 GitHub 不够用,换一个对象存储加 CMS,页面渲染逻辑也不用动。架构的价值不在于它当时多先进,而在于它不绑架下一步的方向。
我经常跟人讲,不要把时间花在“未来可能很麻烦”的担忧上,而要把时间花在“现在很差劲”的痛点上。首版架构只需要做到:改内容方便、上线方便、查问题方便。剩下的事情,等你真的遇到第二十个版本再说。
4.2 能自动化的事就不手工盯
上线第一周,我花在维护上的时间基本为零,因为把重复劳动全部压到了脚本和托管平台上。技能包数量增加、内容更新频率提高之后,手工人肉同步是不可接受的。
仓库里放了一个 GitHub Actions 工作流,功能有两块:一是跑格式校验,二是触发站点构建。校验脚本会检查每个 SKILL.md 的 frontmatter 是否包含必填字段,描述长度是否合规,标签是否在预设白名单里。校验通过后,Vercel 自动部署出新版本。
name: validate-skills on: pull_request: paths: ['skills/**'] jobs: validate: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - run: npm ci - run: npm run validate这里有个细节值得说:校验放在 Pull Request 阶段,而不是合并到 main 之后。因为此时发现问题,提交者能直接修改并重新推送,不会污染主分支。这个判断来自一个老登习惯:把错误拦截在离源头最近的地方,越往后排查成本越是成倍增长。
再说一个自动化反哺内容的例子。所有技能包都有一份对应的 README 模板,提交者只要填好模板,校验脚本会自动生成站内详情页所需的半结构化数据。这让贡献者的心智负担降到很低,也让站点的内容质量标准不依赖于某一个人的责任心。
4.3 经验的本质是预判坑位
半天上线一个项目,真正值钱的不是敲键盘的速度,而是提前把坑位圈出来的能力。年轻人第一次做部署,可能会在“为什么同样的代码我本地能跑、线上不能”上耗掉两小时;老登看了一眼分支和构建日志就能定位到问题,因为他掉进过同一个坑,而且记得比谁都清楚。
我这次的预判有三个:第一,静态导出绝不能碰动态服务端功能;第二,内容型站点的 SEO 优先级高于动画和交互特效;第三,没有后台的前提下,表单提交不如 GitHub PR 靠谱。这三条每一条都是在别处踩过坑换来的经验,今天用起来就像条件反射一样快。
经验的另一个来源是读过大量别人的生产事故复盘,特别是那些“上线很顺利,一个月之后发现数据模型扛不住”的案例。老登的优势不是不会犯错,而是能在一个错误成为事故之前就感知到它。这种对危险的嗅觉,没法靠文档传给新人,只能靠持续地在项目里翻滚、碰到问题、记录、再碰下一个问题。
5. 上线之后:从玩具到工具
5.1 技能包如何形成社区闭环
站点上线后,我最大的愿望不是流量暴涨,而是让技能包形成正向循环。所谓闭环,就是读的人越多,提交的包越丰富;提交的人越多,浏览价值越高;浏览价值越高,回访和引用越频繁。
为了让这个闭环转起来,我在每张技能卡片上都加了“复制安装命令”和“查看完整说明”两个操作,配合详情页的版本记录与依赖列表,让使用者不离开页面就能判断是否值得引入。这个判断成本如果足够低,拿走使用的概率就会明显升高。
我还把提交门槛降到最低:不需要注册账号,不需要理解 git 理论,只要会写 Markdown 就能给仓库提 Pull Request。校验脚本会在 PR 阶段把字段完整性、描述格式等问题直接反馈给提交者。相当于把审核能力前置到了开发者身边,而站长只需要在合并前扫一眼是否合规。
要说还有什么遗憾,就是站点目前还没有生成足够多的“成功案例”,也就是用户在真实工作流里用某个技能包解决了什么具体问题的叙事。这种东西比一百个点赞都有说服力。后续我打算在详情页增加一个“使用反馈”入口,让使用者留下一句话,慢慢沉淀成对提交者最好的激励。
5.2 商业化之前先想清楚的四件事
不少人看到流量起来就问怎么赚钱,我的习惯是:先把赚钱放一放,认真想清楚四件事再做决定。
第一,技能包的版权和授权规则。哪个许可证允许商用、哪个只允许个人使用、贡献者提交后算不算授权给站点分发,这些都是法律级细节,马虎不得。过早收费如果贡献者失去动力,社区生态会比赚那点钱更亏。
第二,能不能保持中立。如果哪天我自己出了很多技能包,并把它排在搜索结果前面,社区信任就会崩盘。中立性和公信力是这类基础设施的唯一资产,维护它比优化收入重要一百倍。
第三,躺着赚钱的路径是否合理。更合理的可能是提供企业服务,比如私有部署、定制技能包、团队内部技能管理平台,而不是向个人属性强的用户收费。企业愿意为可靠性和可维护性付钱,个人的可挥发性太强。
第四,自动化维护能撑到多大。技能包数量涨到一万个时,人工 review 就不可行了,需要引入更智能的重复检测和内容安全机制。这笔投入不是一次性功课,而是伴随整个业务生命周期的持续成本。
我的观点很明确:工具站最容易犯的错就是过早植入商业化,把用户当韭菜。产品先成为大家真正离不开的公共设施,再谈商业模型,腰杆才硬。
这个项目做到这里,我自己最大的体会倒不是技术多炫,而是“老登”这两个字如今确实带着点含金量。它的来源不是会多少框架,而是清楚了什么不该做、什么是首版不必解决的、哪些操作无论如何都要留着退路。agentskill.work 用半天上线,并不代表我比谁快多少,只代表我在过去的十几年里,已经把那些会浪费半天的大坑提前踩完了。如果你也想做类似的内容型项目,建议把第一版的目标定为“能安全上线、能被人看懂、能为后续留出改动空间”,而不是“在开屏动画里塞进一个 Agent”。经验这种东西,不见得非得自己撞到满头是包才长记性,读一读别人踩过的路,也算一种抄近道。