AI 工具链使用经验总结

AI 工具链使用经验总结

从 AI 助手到代码执行,从浏览器自动化到内容发布,一次完整的工具栈实践记录


📋 前言

最近一段时间,我搭建并深度使用了一套 AI 驱动的工具栈,涵盖了从日常助手、代码执行、浏览器自动化到内容创作和知识管理的多个场景。这篇博客是对这些工具的使用经验、踩坑记录和最佳实践的总结。


🤖 核心平台:AI 助手

整个工具栈的核心是一个开源的 AI 助手平台,支持多种消息渠道和多种 AI 模型。

使用场景

  • 日常对话助手,随时提问和查询
  • 文件操作和服务器管理
  • 浏览器自动化控制
  • 定时任务和提醒
  • 多平台消息路由

踩坑记录

  • 沙箱限制:默认的工作区写入模式在某些环境下会遇到兼容性问题,需要切换到更宽松的模式
  • 浏览器超时:长时间操作浏览器时容易超时,建议用 CDP 直接操作而不是模拟点击
  • 记忆管理:助手基于文件系统的记忆需要定期整理,否则上下文会丢失

💻 代码执行:AI 编程工具

使用 AI 驱动的命令行代码执行工具,适合复杂代码任务和文件操作。

安装配置

1
2
npm install -g @openai/codex
codex login # 使用 OAuth 登录,不需要 API Key

实际使用经验

  • 优势:可以读取和修改任意文件,执行复杂的多步骤任务,内置图像生成工具
  • 沙箱模式:受限模式在多数场景下不够用,完整模式更灵活但需谨慎
  • CDP 操作:可以通过 CDP 直接控制浏览器,比普通的浏览器工具更灵活
  • 图像生成:内置图像生成模型,可以生成高质量图片

踩坑 1:Shadow DOM 问题

在操作某些网页时,按钮是自定义 Web Component,使用闭合 Shadow DOM。普通的 click() 事件无法触发。解决方案是直接派发 publish 自定义事件。

踩坑 2:浏览器文件选择器

自动化上传文件时,无法通过模拟点击文件选择器。解决方案是使用 CDP 的 DOM.setFileInputFiles 直接设置文件路径。


🌐 浏览器自动化:CDP

Chrome DevTools Protocol (CDP) 是浏览器自动化的核心工具,可以直接操作 DOM、执行 JavaScript、设置文件等。

常用操作

1
2
3
4
5
6
7
8
9
// 执行 JavaScript
await send('Runtime.evaluate', { expression: 'document.body.innerText' });

// 设置文件输入
await send('DOM.setFileInputFiles', { nodeId, files: ['/path/to/file.png'] });

// 派发自定义事件(绕过 Shadow DOM)
const el = document.querySelector('xhs-publish-btn');
el.dispatchEvent(new CustomEvent('publish', { bubbles: true, composed: true }));

最佳实践

  • 使用 Runtime.evaluate 直接执行 JS,比模拟点击更可靠
  • 遇到 Shadow DOM 组件时,直接派发自定义事件
  • 文件上传用 DOM.setFileInputFiles,不要模拟文件选择器
  • 操作前先用 snapshot 获取页面状态,避免操作错误元素

🎨 AI 图像生成

使用 AI 图像生成工具创建高质量图片,效果远超手写代码生成。

使用技巧

  • Prompt 要具体:描述颜色、布局、文字内容、风格等细节
  • 指定尺寸:根据用途选择合适比例,如 9:16(竖版封面)、16:9(横版图解)、1:1(方形对比)
  • 英文 Prompt 效果更好:AI 对英文提示的理解更准确
  • 后处理:生成后用图像处理工具调整到精确尺寸
1
ffmpeg -y -i input.png -vf scale=1080:1440:flags=lanczos output.png

📱 内容平台自动化发布

通过 AI 助手 + 浏览器自动化,实现了内容平台笔记的内容生成到发布的完整自动化流程。

技术架构

1
2
3
4
5
AI 助手
├── MCP Server (内容平台 SDK)
├── 无头浏览器 (Chrome)
├── CDP (DevTools Protocol)
└── AI 编程工具 (复杂任务执行)

实现的功能

  1. 内容生成:根据主题自动检索资料、撰写正文、生成标题和话题标签
  2. 图片制作:代码生成初版 → AI 图像生成精修版
  3. 旧笔记编辑:定位旧笔记 → 删除旧图 → 上传新图 → 修复话题标签 → 提交更新
  4. 状态确认:自动截图验证、检查审核状态、数据监控

踩坑记录

  • 不要删除到 0 张图片:编辑器不允许图片数为 0,至少要保留 1 张作为占位
  • 审核中仍可编辑:即使内容在审核中,仍然可以进入编辑页面修改
  • 话题标签格式:必须通过编辑器的话题入口添加,直接输入纯文本无效
  • 字数限制:正文有字数上限,需要预留话题标签的空间
  • Cookie 过期:内容平台的登录态需要定期刷新,否则自动化会失败
  • 首次浏览器下载:首次使用自动化框架时会自动下载 Chromium 浏览器

注意事项

  • 内容平台有反爬和频率限制,自动化操作要控制节奏
  • 不要创建重复内容,编辑旧内容比新建更安全
  • 发布后需要等待审核,审核期间数据可能暂时不更新

📝 知识库笔记自动同步

这是我最满意的一个自动化系统——将本地的 Obsidian 知识库自动构建为可访问的网站,整个过程完全无人值守。

整体架构

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
Obsidian Vault (本地/NAS)

│ rsync (排除配置和缓存目录)

Quartz 4 项目目录 (content/)

│ npx quartz build

Quartz public/ 目录

│ cp 复制到

Nginx 静态文件目录


浏览器访问

使用的核心工具

工具 用途
Obsidian 本地 Markdown 知识库管理,支持双向链接、标签、文件夹结构
Quartz 4 静态站点生成器,专为 Obsidian 笔记设计,支持双向链接解析、反向链接、图谱视图
rsync 文件同步工具,将 Obsidian Vault 增量同步到 Quartz 的 content 目录
Cron 定时任务调度,每 10 分钟检测一次变更
Nginx Web 服务器,托管生成的静态 HTML 文件

自动检测机制

不使用 inotify 监听(因为 NAS 网络存储对 inotify 支持不稳定),而是采用 状态指纹轮询 的方式:

1
2
3
4
5
6
7
8
9
10
11
12
13
# 计算当前知识库的状态指纹
# 方法:取最近 50 个文件的修改时间,计算 MD5 哈希
current_state=$(find "$VAULT" -type f \
-not -path "*/.obsidian/*" \
-not -path "*/.stfolder/*" \
-not -name ".stignore" \
-printf "%T@\n" 2>/dev/null | sort -r | head -50 | md5sum)

# 与上次状态对比
if [ "$current_state" = "$last_state" ]; then
# 无变化,跳过构建
exit 0
fi

这种方式的优点:

  • 不依赖文件系统事件,对网络存储友好
  • 取最近修改的 50 个文件而非全部,计算效率高
  • 状态指纹是纯哈希值,存储占用极小
  • 任何文件的新增、删除、修改都会触发重建

完整更新流程

更新脚本执行以下步骤:

第 1 步:检查知识库路径

1
2
3
4
if [ ! -d "$VAULT" ]; then
echo "Vault path not found"
exit 1
fi

第 2 步:同步到 Quartz content

1
2
3
4
5
6
7
8
rsync -av \
--exclude ".obsidian" \ # Obsidian 配置
--exclude ".trash" \ # 回收站
--exclude ".stfolder" \ # Syncthing 同步标记
--exclude ".git" \ # Git 仓库
--exclude "workspace.json" \ # 工作区状态
--exclude ".stignore" \ # Syncthing 忽略规则
"$VAULT"/ "$QUARTZ/content"/

第 3 步:自动生成首页索引

Quartz 本身不会自动生成首页,所以脚本会自动遍历所有 Markdown 文件,生成一个首页索引:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
cat > "$QUARTZ/content/index.md" << 'EOF'
---
title: 知识库首页
---

# 知识库首页

下面是当前知识库中的笔记列表。

EOF

cd "$QUARTZ/content"
find . -type f -name "*.md" ! -name "index.md" | sort | while read -r file; do
title="$(basename "$file" .md)"
path="${file#./}"
echo "- [[$path|$title]]" >> "$QUARTZ/content/index.md"
done

这样每次有新笔记,首页会自动更新列表,点击即可跳转。

第 4 步:清理缓存

Quartz 有缓存机制,但有时会导致旧数据残留,所以每次构建前强制清理:

1
2
3
rm -rf "$QUARTZ/.quartz-cache"
rm -rf "$QUARTZ/public"
rm -rf "$QUARTZ/.cache"

第 5 步:执行构建

1
2
cd "$QUARTZ"
npx quartz build

构建过程会解析所有 Markdown 文件,处理双向链接、生成图谱数据、构建搜索索引、输出静态 HTML。当前笔记数量下构建耗时约 14 秒。

第 6 步:发布到 Web 服务器

1
2
3
rm -rf "$OUT"
mkdir -p "$OUT"
cp -r "$QUARTZ/public/"* "$OUT"/

第 7 步:修复权限

1
2
chown -R "$WEB_USER":"$WEB_GROUP" "$OUT"
chmod -R a+rX "$OUT"

Web 服务器进程以独立用户运行,必须确保有读取权限,否则会出现 403 错误。

并发控制

定时轮询和文件监听器可能同时触发更新,导致并发构建。解决方案是使用锁文件:

1
2
3
4
5
6
7
8
9
10
LOCK="/tmp/notes-update.lock"

if [ -f "$LOCK" ]; then
echo "Another update is running, skipping"
exit 0
fi

touch "$LOCK"
# ... 执行更新 ...
rm -f "$LOCK"

Nginx 缓存策略

不同类型的文件采用不同的缓存策略:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
# HTML 页面:不缓存,确保用户总是看到最新内容
location ~* \.html$ {
try_files $uri /index.html;
add_header Cache-Control "no-store, no-cache, must-revalidate";
}

# JS/CSS/JSON(含搜索索引):不缓存
location ~* \.(css|js|mjs|json)$ {
try_files $uri =404;
add_header Cache-Control "no-store, no-cache, must-revalidate";
}

# 图片/字体:缓存 7 天,减少带宽
location ~* \.(png|jpg|jpeg|gif|svg|woff|woff2|ttf)$ {
try_files $uri =404;
access_log off;
expires 7d;
}

# SPA 路由回退(支持 Quartz 的单页应用模式)
location / {
try_files $uri $uri.html $uri/ /index.html;
}

踩坑记录

  1. Git 仓库缺失警告:Quartz 构建时如果 content 目录没有 Git 仓库,会显示 couldn't find git repository 警告。这只是警告,不影响构建结果。可以通过 git init 初始化一个空仓库来消除警告。

  2. 缓存残留:如果不删除 .quartz-cache,修改笔记后 Quartz 可能仍然使用旧的解析结果。每次构建前强制清理是最稳妥的做法。

  3. 权限 403:Web 服务器用户没有读取权限是最常见的发布后访问失败原因。每次同步后必须修复权限。

  4. 状态指纹精度:最初用全部文件的修改时间计算哈希,文件多了会很慢。改为取最近 50 个文件后,检测速度提升明显,且不会漏掉变更。

  5. 并发构建冲突:如果 cron 和 inotify 同时触发更新,两个构建进程会同时写入 public 目录,导致文件不一致。使用锁文件可以有效避免。

  6. 首页索引重复追加:最初每次更新时 >> 追加到 index.md,导致首页列表越来越长。修复为先 > 覆盖写入。

优化建议

  • 增量构建:当前是全量构建,每次清理缓存后重新解析所有文件。如果笔记数量增长到较多,可以考虑 Quartz 的增量构建模式,只重新构建变更的文件。
  • Webhook 替代轮询:如果知识库支持 Git,可以用 Git Hook(post-receive)替代 cron 轮询,实现真正的实时触发。
  • 构建失败告警:目前更新失败只会写入日志,没有主动通知。可以添加简单的告警机制,比如连续失败 N 次后发送通知。
  • HTTPS 自动续期:使用 Certbot 管理 SSL 证书,设置自动续期任务,避免证书过期导致网站无法访问。

🛠️ 其他实用工具

多媒体处理

用于图片尺寸调整、视频处理等,比编程语言的图片库更快更可靠。

NAS 存储

用于备份重要文件和存储生成的内容。建议定期备份到云端。

个人博客

使用静态站点生成器搭建的个人博客,支持 Markdown 写作和自动部署。


💡 总结与建议

工具选择建议

场景 推荐方案 原因
日常对话 AI 助手 + 大语言模型 响应快,成本低
代码执行 AI 编程工具 可以读写任意文件
浏览器自动化 CDP + 无头浏览器 直接操作 DOM 最可靠
图像生成 AI 图像模型 质量高,支持文字
内容发布 浏览器自动化 绕过文件选择器限制
知识管理 Obsidian + Quartz + 定时同步 自动检测、自动构建

最佳实践

  1. 工具组合使用:AI 助手负责日常调度,编程工具处理复杂任务,CDP 操作浏览器
  2. 隐私保护:公开内容中隐藏敏感信息,如密钥、服务器地址等
  3. 定期备份:重要文件和配置定期备份
  4. 文档记录:每次踩坑都记录下来,方便后续查阅
  5. 自动化优先:能自动化的尽量自动化,减少人工干预

📝 后续计划

  • 探索更多 AI 模型的 API 集成
  • 优化浏览器自动化的稳定性
  • 尝试语音识别和语音合成的集成
  • Quartz 增量构建优化
  • 内容数据监控自动化

本文基于实际使用经验总结,所有路径和配置均已做匿名化处理。

  • 版权声明: 本博客所有文章除特别声明外,著作权归作者所有。转载请注明出处!
  • Copyrights © 2015-2026 北山念我心
  • 访问人数: | 浏览次数: