记录技术实践,也记录把复杂事情做简单的过程。本站采用 Hugo 生成,页面轻量、加载快速,适合作为个人技术资料库。
把 AI 接口接入个人工具:一次轻量化实践
2025 年,模型接口越来越多,但个人工具并不需要同时绑定很多 SDK。我做了一次轻量化尝试:在业务代码和模型服务之间增加一个很薄的适配层,只约定输入、输出和错误格式。 只保留真正需要的接口 适配层只做三件事:接收消息列表、选择模型、返回文本和用量信息。它不保存会话,也不把供应商特有的字段泄漏到业务代码中。这样更换服务商时,只需要替换适配层,而不是重写整个工具。 def ask(messages, model="small-fast"): response = client.responses.create( model=model, input=messages, timeout=30, ) return { "text": response.output_text, "usage": response.usage, } 真实项目里还需要处理超时、限流和重试。重试只针对明确的临时错误,并设置上限;如果请求已经产生费用,就不能无条件重复发送。 把日志做成能回答问题的东西 我只记录请求时间、模型名、耗时、状态码和 token 数,不记录完整提示词或敏感内容。发生问题时,这些字段足以判断是网络慢、服务拒绝,还是输入本身太大。日志的目标是帮助排错,而不是把所有数据都复制一份。 低配服务器上的取舍 适配层可以用一个很小的 Python 或 Go 服务运行,也可以在静态站点之外单独部署。博客本身不需要调用 AI 才能展示,因此把两者拆开后,即使接口服务暂时停止,文章页面仍然可以正常访问。 这次实践让我更确定一件事:个人项目的“智能化”不应以堆叠组件为起点。先把边界、超时、日志和成本控制做好,剩下的能力才有稳定的落脚点。
用 Nginx 为静态站点加上缓存与安全响应头
静态站点已经很快,但默认配置通常只完成了“能访问”。2023 年我给一个个人页面做优化时,没有引入额外的缓存服务,而是先把 Nginx 的基础能力用好。 给不同类型的文件不同缓存时间 带哈希文件名的 CSS、JavaScript 和图片可以长时间缓存;HTML 则应该短一些,方便发布后及时生效。下面是一段适合静态站点的配置: location ~* \\.(css|js|png|jpg|jpeg|gif|svg|webp|woff2)$ { expires 30d; add_header Cache-Control "public, max-age=2592000, immutable"; } location / { try_files $uri $uri/ /404.html; add_header X-Content-Type-Options "nosniff" always; add_header Referrer-Policy "strict-origin-when-cross-origin" always; } immutable 只适合文件内容一旦变化就会改名的资源。如果站点仍然使用固定的 main.css,缓存时间就不应设置得过长,否则更新样式后用户可能要手动刷新。 压缩要适度 HTML、CSS、JavaScript 和 SVG 都适合启用 gzip。图片压缩则应该在构建阶段完成,不能指望 Nginx 在每次请求时临时处理大图片。对个人博客来说,少量清晰的图片比堆叠复杂的优化插件更容易维护。 用响应头建立最低限度的安全边界 X-Content-Type-Options 可以避免浏览器猜测文件类型,Referrer-Policy 则减少从站点跳转时泄露完整路径。它们不能替代应用安全检查,却能以很低的成本补上基础防线。 配置变更后先检查语法,再平滑加载: nginx -t nginx -s reload 优化静态站点时,我通常先看真实请求的响应头和缓存命中情况,再决定是否需要更复杂的 CDN 或服务端缓存。简单的站点,简单的链路往往更稳定。
从脚本到服务:用 Docker Compose 管理一个小项目
很多个人项目最初只有一个脚本:在电脑上可以运行,换一台机器就要重新安装依赖、修改配置,再手动启动。2021 年我给一个小工具做整理时,决定把“运行环境”也作为项目的一部分保存下来。 先把服务边界说清楚 我先把程序拆成三个部分:应用本身、持久化数据、配置文件。应用容器可以随时重建,数据目录需要长期保留,配置则通过环境变量注入。这样做的好处是,升级应用时不必碰数据,迁移服务器时也只需要打包数据目录和 compose 文件。 一个最小的 docker-compose.yml 可以这样写: version: "3.8" services: app: image: example/app:1.0 restart: unless-stopped ports: - "8080:8080" env_file: - .env volumes: - ./data:/var/lib/app restart: unless-stopped 让机器重启后服务自动恢复;版本号固定则避免“今天能跑、明天突然变样”。开发阶段可以使用 latest,生产环境最好明确写版本。 配置和数据分开 密码、令牌等内容不应该提交到 Git。项目里只保留 .env.example,真正的 .env 放在服务器上,并限制文件权限: cp .env.example .env chmod 600 .env docker compose up -d 备份也围绕数据目录进行。对小项目来说,每天压缩一次数据并保留最近七份,已经比“只在出问题时想起来备份”可靠很多。 让部署变成一个动作 最后我把更新流程固定为:拉取代码、检查配置、构建新镜像、重新创建容器、查看日志。步骤固定之后,部署不再依赖某个人记得哪些命令,也更容易在低配服务器上控制资源。 这个实践让我意识到,轻量化不只是少装软件,更是让每个组件的职责足够单一。服务越小,备份、迁移和排错都越容易。