# Cassian Florin > Cassian Florin builds AI engineering tools, developer workflows, and personal knowledge systems. Posts are mostly written in Chinese, with a smaller set of English translations. Every page exists under both a `/zh/` and an `/en/` prefix; the canonical default is `/zh/`. Available locales: zh, en. Recurring subjects: AI agents and agent tooling, developer workflow and environment setup, personal knowledge management with Obsidian, backend engineering in Java, and self-hosted infrastructure. ## Posts - [误删生产数据卷之后:一次零丢失的 ext4 数据恢复实战](https://www.cassianflorin.com/zh/blog/20260813-ext4-docker-volume-data-recovery): 误删数据后按「进程 fd → 文件系统日志 → 空闲块雕刻 → 旧备份兜底」的顺序恢复,成本递增、时效窗口递减。忙碌磁盘上 ext4 日志几小时就会滚掉,但 photorec 按文件头从空闲块雕刻 SQLite 这类小文件成功率很高;再用业务里的单调计数器和外部事件做时间锚点,就能从几十个历史残影里认出删除时刻的那一份。以及:加密备份的口令必须有独立于服务器的第二份副本,否则备份等于没有。 - [博客 GEO 改造:让文章能被 AI 引用,顺带挖出线上的 500](https://www.cassianflorin.com/zh/blog/20260804-blog-geo-overhaul): GEO 的重点不是关键词,而是让内容能被生成式引擎整段摘走:每篇一个自包含结论、把问答和步骤做成结构化数据、RSS 输出全文。这轮真正棘手的两个问题都不在代码里,只有探线上才看得见。 - [多语言博客 SEO 改造:sitemap 里每个 URL 都在重定向](https://www.cassianflorin.com/zh/blog/20260729-nextjs-i18n-seo-overhaul): 有 middleware 做语言前缀重定向的站点,sitemap 必须输出带语言前缀的 URL,否则每条 URL 都是一跳重定向。这个问题在代码里完全看不出来,只有把 sitemap 里的 URL 逐条 curl 过去才会暴露。 - [Codex CLI 接中转站配置排错:一次 401 引发的完整踩坑记录](https://www.cassianflorin.com/zh/blog/20260727-codex-cli-relay-station-config): Codex CLI 接第三方中转站的关键是:base_url 必须写在 \[model_providers.xxx\] 块内部,再由顶层 model_provider 指过去,裸写在顶层会被新版完全忽略。鉴权用顶层 experimental_bearer_token,不要依赖环境变量。 - [Agent 光会 grep 还不够:CodeGraph 让它先看懂代码结构](https://www.cassianflorin.com/zh/blog/20260526-codegraph-agent-coding): grep 只能回答「哪里出现了这个字符串」,回答不了「谁调用了它、改它会影响什么」。CodeGraph 通过 MCP 给 Agent 提供代码结构索引,让它动手前先看清定义、调用方和下游依赖,从而把改动范围判断对。 - [什么是 Obsidian:从安装到命令行打开知识库](https://www.cassianflorin.com/zh/blog/20260523-what-is-obsidian): Obsidian 是管理本地 Markdown 文件的知识库工具,一个 Vault 就是一个普通文件夹,一篇笔记就是一个 .md 文件。正因为知识以文件和双链的形式存在,脚本、命令行和 Agent 都能直接读写它。 - [Agent 与 Obsidian:把个人知识库变成可执行的第二大脑](https://www.cassianflorin.com/zh/blog/20260515-agent-obsidian-knowledge-workflow): Agent 不替代 Obsidian,而是让它从静态笔记库变成可调用的知识工作台:Obsidian 保存已确认的知识,Agent 负责检索、提炼和改写。关键边界是只有你确认过的结论才写进去,否则知识库会越大越不可用。 - [云服务器配置 Traefik 教程](https://www.cassianflorin.com/zh/blog/20260511-traefik-cloud-server-guide): 把 Traefik 放在云服务器入口层统一处理反向代理、Let's Encrypt 证书和路由,业务容器只要加入同一个 Docker 网络、用 labels 声明域名和端口就能接入。服务器只开放 22、80、443,新增服务不必再改 Nginx 配置。 - [什么是 Harness Engineering(线束工程)](https://www.cassianflorin.com/zh/blog/20260509-what-is-harness-engineering): Harness Engineering(线束工程)是把 AI 能力与接口、工具、服务「线束」在一起的架构方法论,主张 AI 的价值不在模型本身,而在怎么接进真实场景,四个关键组件是 Gateway、Tool、Memory 和 Plugin/Skill System。 - [OpenClaw vs Hermes Agent:两种 AI Agent 的设计哲学](https://www.cassianflorin.com/zh/blog/20260509-openclaw-vs-hermes-agent): 两者都是 Harness Engineering 的实践,方向却相反:OpenClaw 广度优先,强在多平台渠道覆盖;Hermes Agent 深度优先,强在记忆系统和命令行交互。要多平台统一响应选前者,要强命令行助手选后者。 - [神策数据分析开发接入文档](https://www.cassianflorin.com/zh/blog/20251111-sensors-data-integration): 神策数据分析的 Java 接入由 SensorsConfig 配置类统一管理:开发环境用 DEBUG 模式实时校验埋点,生产环境用 BATCH 模式批量上报,各环境配置通过 Nacos 下发,避免测试数据污染正式项目。 - [今天成为了 MooTool 贡献者](https://www.cassianflorin.com/zh/blog/20250927-MooToolContributors): 我给开源 Java 工具箱 MooTool 贡献了 Text Diff(文本差异比较)功能,正式成为它的贡献者。参与开源的门槛往往就是「我常用的这个功能它还没有」这么简单。 - [AI工具使用技巧分享](https://www.cassianflorin.com/zh/blog/20250909-AI-Tool-Usage-Tips-Sharing): AI 编程工具之间的效率差距,主要来自 prompt 写法和上下文组织,而不是工具本身。Cursor 这类工具靠 MCP 感知外部世界;把 AI 当协作伙伴而不是替代品,才拿得到真正的生产力提升。 - [IntelliJ IDEA File Header 自定义配置](https://www.cassianflorin.com/zh/blog/20250908-Intellj-file-header): IntelliJ 的文件头模板在 Settings → Editor → File and Code Templates → Includes → File Header 里配置。用 Groovy 脚本判断 ${PACKAGE_NAME} 的包名前缀,就能让个人项目和公司项目自动生成不同的文件头。 - [ValidatorUtils 工具类详解:身份证、手机号、银行卡等验证功能](https://www.cassianflorin.com/zh/blog/20250701-validator-utils-guide): ValidatorUtils 是一个 Java 验证工具类,覆盖身份证(15 位转 18 位、信息提取)、手机号(运营商识别)、银行卡(类型识别)、邮箱、密码强度、URL 与 IP。正则校验有性能开销,高并发场景需要自己加缓存。 - [Git Hooks 与 Node 环境问题](https://www.cassianflorin.com/zh/blog/20250619-git-hooks-and-node-env): Git hook 报 npx: command not found,根因通常是 Homebrew 装的 Node 与 hook 拿到的 PATH 不一致。卸掉 brew 版 Node 改用 nvm 管理即可;Java 用 SDKMAN、Python 用 pyenv 是同一个道理。 - [Git Hooks与多JDK环境问题解决](https://www.cassianflorin.com/zh/blog/20250619-git-hooks-and-multi-java-env): 多 JDK 共存时,Maven Spotless 会因为高版本 JDK 报 InvocationTargetException。解法是用 SDKMAN 装所需版本,项目根目录放 .sdkmanrc,并在 pre-commit hook 开头加载 SDKMAN,锁死构建用的 Java 版本。 - [SDKMAN 安装指南](https://www.cassianflorin.com/zh/blog/20250619-install-sdkman): SDKMAN 是管理 Java 等 SDK 多版本的命令行工具,macOS 和 Linux 用一行 curl 安装,Windows 需要先有 Git Bash 或 WSL。装好后用 sdk install java 装版本,在项目里放 .sdkmanrc 就能进目录自动切换。 - [多环境下的 Git Config 配置](https://www.cassianflorin.com/zh/blog/20250619-multi-environmental-gitconfig): Git 的 includeIf 能按仓库路径自动切换提交身份:把公司和开源的 user.name / user.email 拆进不同配置文件,再在 ~/.gitconfig 里用 includeIf "gitdir:路径/" 引入,进到对应目录就自动生效,不用每次手动改。 - [我的第一篇博客](https://www.cassianflorin.com/zh/blog/20250619-first-post): 这个博客用 Next.js + Tailwind CSS + MDX 搭建。MDX 让文章里可以直接写 React 组件,所以这里的技术文章能带交互演示,而不只是静态文本。 ## Pages - [/blog](https://www.cassianflorin.com/zh/blog): All posts, newest first. - [/knowledge](https://www.cassianflorin.com/zh/knowledge): Knowledge graph view of how the posts connect. - [/projects](https://www.cassianflorin.com/zh/projects): Projects and tools I have built. - [/about](https://www.cassianflorin.com/zh/about): Who I am and what I work on. - [/tags](https://www.cassianflorin.com/zh/tags): Every tag used across the blog. ## Optional - [RSS feed](https://www.cassianflorin.com/feed.xml): Full post list as RSS. - [Sitemap](https://www.cassianflorin.com/sitemap.xml): Every URL in both locales. - [Source repository](https://github.com/CassianFlorin/cassian-next-blog): The site itself is open source.