FolioKit - 不仅是作品集,更是 AI 驱动的个人展示平台

一直以来,想做一个能系统性展示项目的网站。博客写了不少,但没人看,发到简历里链接又太零散,现成的作品集模板或页面大都千篇一律,交互也偏静态,缺少内容组织与理解能力。于是索性写了个自己的:FolioKit。

它不仅仅是一个展示项目的页面,更像一个可以提问、可以互动的内容平台。通过语义搜索与问答机制,用户不仅能看到你做了什么,还能通过对话理解背后的结构与逻辑。

作品集地址:https://foliokit.im0o.top

核心特性

  • 支持前后端分离部署
  • Markdown 驱动项目内容管理,支持标签配色配置
  • 支持 AI 搜索与问答,内容可被理解、被重组
  • 响应式设计、暗色主题优化、字体子集化处理
  • 完整的 CI/CD 流程,自动部署到 Vercel
  • 后端参数可配置,部署灵活,支持多模型/缓存方案切换

技术栈概览

前端:

  • Nuxt3 + TypeScript
  • TailwindCSS(结合 SCSS 使用 @apply 管理样式)
  • Nuxt Content(项目数据均存 Markdown)
  • i18n 支持
  • GitHub Actions 自动部署

后端(foliokit-api):

  • Flask + Blueprint 模块化
  • LlamaIndex + OpenAI API(或其他模型,如 DeepSeek)
  • 本地 JSON 向量存储(可选 Redis 缓存)
  • gunicorn + Nginx 部署

为什么要做这个

项目太多,想展示,但传统作品集形式过于静态。博客内容也很难有效组织和回收利用。既然如此,不如构建一个结构化的项目展示平台,集成语义检索能力,让作品可以“说话”,真正做到交互式内容展示。

页面与设计

页面结构非常简单:没有导航栏,只有一个 hello 动画和一个搜索框。“关于我”等信息藏在搜索框下方的小链接里,整体布局偏极简。

作品展示以卡片形式滚动展示,浏览几次后提示跳转至完整项目列表。全站暗色主题是个人偏好,没做亮色版本。布局主要依靠弹性盒子,尽量避免 media query,追求简洁与一致性。

项目详情页从原先的卡片风格过渡为扁平风,阅读体验更轻量。

前端开发细节

  • 默认关闭 SSR 模式。原本打算 Nuxt 全栈处理,但实测 llamaindex serverless 启动慢、稳定性差,最终改为 API 独立部署。
  • CI/CD 使用 GitHub Actions + Vercel。
  • 所有项目内容放在 Markdown,元信息用 frontmatter 管理。
  • 标签颜色可在 frontmatter 里用 tag#hex 指定,所有配色集中管理在 tag.css
  • 字体子集化,区分 fontfont-full,根据网络质量切换加载模式。
  • 自定义目录结构,项目代码集中放在 src,部分插件保留在根目录。

AI 协作体验

项目整体在 Cursor IDE 中开发,过程中 AI 辅助查文档、生成 Tailwind 片段非常高效。也因此意识到:AI 不是自动补全工具,而是结构感知型对话协作者。相比命令行助手,Cursor 提供了更贴近实际工作的辅助方式。

后端设计:foliokit-api

foliokit-api 是服务 FolioKit 前端的 API 服务,设计上追求轻量可配置:

  • 所有参数写入 .env 文件,支持热切换模型、缓存、Key 等。
  • Flask 工厂模式组织,配合 Blueprint 实现模块化,易于扩展。
  • 默认使用 JSON 存储向量数据,也支持挂载 Redis 做缓存。
  • 模型支持 OpenAI / DeepSeek 等主流服务,通过接口兼容。
  • prompt 结构采用 <msg_json>...</msg_json> 形式嵌套 JSON,增强安全性、规避 prompt 注入。
  • 针对中文/英文分别设置了 system prompt,防止幻觉、增强内容一致性。
  • 使用 OpenAI 的流式输出,前端支持实时文字加载。
  • 查询不到向量时自动回退到全文内容搜索,提升问答容错率。

总结

FolioKit 是写给自己的项目,也希望对别人有用。希望它能带来一种新的作品展示方式:项目不仅是被动陈列的静态信息,也可以是主动回应的交互内容。

在 AI 与开发工具加速融合的当下,FolioKit 是一次尝试,也是一种探索。