乐于分享
好东西不私藏

用WorkBuddy做AI工具站07:做一个审核后台

用WorkBuddy做AI工具站07:做一个审核后台

大家好,我是宇哥,专注AI编程、智能体,解决小白AI编程问题。

前一篇我们写了第一个采集器,已经能把 5 个工具的公开页面信息采集到:

data/collected-tools-review.json

但这里千万不要急着把它们写进正式工具库。

因为采集结果里可能有这些问题:

  • 摘要太像官网原文,需要改成自己的话;
  • 价格标签不一定准确,需要人工确认;
  • 开源、免费、试用这些标签容易过期;
  • 有些工具适不适合收录,还得看你的站点定位。

所以第 7 篇我们做一个很小、但非常关键的东西:审核后台

这篇你能做出什么

跟着做完,你会得到这个目录:

tutorials/ai-tool-directory/demo/lesson-07/├── data/│   └── collected-tools-review.json├── scripts/│   ├── generate-review-admin.py│   ├── check-review-admin.py│   └── generate_lesson07_images.py├── site/│   ├── index.html│   ├── styles.css│   └── app.js└── prompts/    └── workbuddy-review-admin-prompt.md

最后你能运行:

python3 scripts/generate-review-admin.py && python3 scripts/check-review-admin.py

我这次真实跑出来的结果是:

✅ 审核后台生成完成输入记录:5 条生成文件:site/index.html, site/styles.css, site/app.js审核动作:通过 / 修改后通过 / 拒绝 / 稍后复查发布闸门:未创建或覆盖 data/tools.json✅ 审核后台检查通过待审核记录:5 条页面文件:index.html / styles.css / app.js 均存在审核动作:通过、修改后通过、拒绝、稍后复查正式数据保护:未创建/覆盖 data/tools.json

看到这组输出,就说明本篇成功:审核后台已生成,而且没有把采集数据直接写进正式库。

适合谁,不适合谁

适合你,如果你现在想要的是:

  • 让 AI 工具站的数据增长变得可控;
  • 先用本地页面审核采集结果;
  • 让 WorkBuddy 帮你写后台雏形,但自己保留最后判断;
  • 暂时不想上数据库、登录系统、权限系统。

不适合你,如果你想一步到位做:

  • 多人协作审核;
  • 带账号登录的正式管理后台;
  • 数据库写入、权限控制和操作日志;
  • 自动把抓取结果发布到线上页面。

这一篇只做最小闭环:读采集结果 → 人工标记 → 导出决策 JSON

准备环境

你需要准备:

  1. WorkBuddy:用来让 AI Agent 帮你生成脚本和页面。
  2. Python 3:本篇只用标准库,不需要安装依赖。
  3. 第 6 篇产物:data/collected-tools-review.json
  4. 一个本地项目目录。

本篇真实 demo 路径是:

/root/workspace/wechat-articles/tutorials/ai-tool-directory/demo/lesson-07/

你自己的电脑可以用类似路径:

ai-tool-directory/demo/lesson-07/

先看最终效果

本篇页面不是复杂后台,而是一个本地可打开的审核页。

它的安全链路是这样:

输入是上一篇的:

data/collected-tools-review.json

页面里每条记录显示:

  • 工具名称;
  • 来源地址;
  • HTTP 状态;
  • 风险等级;
  • 候选标题;
  • 候选摘要;
  • 价格标签;
  • 审核备注。

你可以给每条记录选 4 个动作:

最终导出一份:

data/review-decisions.json

注意,本篇还是不改正式数据:

data/tools.json

正式合并放到下一篇做。

第一步|新建 lesson-07 目录

打开你的项目目录,新建本篇目录:

mkdir -p demo/lesson-07/data demo/lesson-07/scripts demo/lesson-07/prompts demo/lesson-07/sitecd demo/lesson-07

如果你跟着我的路径做,就是:

mkdir -p /root/workspace/wechat-articles/tutorials/ai-tool-directory/demo/lesson-07/data \  /root/workspace/wechat-articles/tutorials/ai-tool-directory/demo/lesson-07/scripts \  /root/workspace/wechat-articles/tutorials/ai-tool-directory/demo/lesson-07/prompts \  /root/workspace/wechat-articles/tutorials/ai-tool-directory/demo/lesson-07/sitecd /root/workspace/wechat-articles/tutorials/ai-tool-directory/demo/lesson-07

验收点:看到这 4 个目录就算成功。

data/scripts/prompts/site/

本篇完整文件结构长这样:

第二步|复制上一篇采集结果

把第 6 篇生成的审核队列复制过来:

cp ../lesson-06/data/collected-tools-review.json data/collected-tools-review.json

复制后检查一下:

python3 - <<'PY'import jsonfrom pathlib import Pathpath = Path('data/collected-tools-review.json')records = json.loads(path.read_text(encoding='utf-8'))print('文件存在:', path.exists())print('待审核记录:', len(records))print('第一条工具:', records[0]['name'])print('第一条状态:', records[0]['review_status'])PY

我这里检查到的是 5 条记录,第一条还是待人工复核状态。

如果你看到的数量不是 5,也没关系,说明你前一篇采集到的数据不同;只要它是一个非空数组,并且每条都有 review_status,就可以继续。

第三步|把这段提示词复制到 WorkBuddy

新建文件:

prompts/workbuddy-review-admin-prompt.md

复制下面这段提示词:

你是我的 AI 工具目录站开发助手。请只在当前 lesson-07 目录里工作,目标是把上一篇采集器产出的 data/collected-tools-review.json 做成一个本地可打开的最小审核后台。输入文件:- data/collected-tools-review.json:每条记录都有 slug/name/source_url/review_status/suggested_update/evidence。请生成:1. scripts/generate-review-admin.py   - 使用 Python 标准库即可,不引入第三方依赖。   - 读取 data/collected-tools-review.json。   - 生成 site/index.html、site/styles.css、site/app.js。   - 在 app.js 里嵌入审核队列 JSON,方便本地直接打开页面。   - 页面里每条工具记录要显示:名称、来源、风险、候选摘要、价格候选、审核备注。   - 每条记录要支持 4 个动作:通过、修改后通过、拒绝、稍后复查。   - 页面要提供“导出审核结果 JSON”的文本框,方便复制保存。   - 不要自动覆盖正式 tools.json。2. scripts/check-review-admin.py   - 检查输入 JSON 存在且有记录。   - 检查 site/index.html、site/styles.css、site/app.js 存在。   - 检查页面包含 4 个审核动作。   - 检查 app.js 里没有把记录默认标记为 published。   - 检查没有创建或覆盖 data/tools.json。请写清楚验证命令:python3 scripts/generate-review-admin.pypython3 scripts/check-review-admin.py

这段提示词的重点不是“让 AI 写一个很炫的后台”,而是把边界说清楚:

审核后台可以生成,正式工具库不能动。

第四步|生成审核后台脚本

WorkBuddy 生成后,你应该得到:

scripts/generate-review-admin.py

如果你想直接跟做,可以按下面这个骨架创建文件。

先看核心逻辑:

from pathlib import Pathimport jsonROOT = Path(__file__).resolve().parents[1]DATA = ROOT / 'data'SITE = ROOT / 'site'INPUT = DATA / 'collected-tools-review.json'records = json.loads(INPUT.read_text(encoding='utf-8'))SITE.mkdir(parents=True, exist_ok=True)

这几行做了三件事:

  1. 找到当前 lesson-07 根目录;
  2. 读取上一篇采集结果;
  3. 准备生成页面目录。

然后把采集结果整理成页面需要的字段:

defnormalized_record(record):    suggested = record.get('suggested_update'or {}    evidence = record.get('evidence'or {}return {'slug': record.get('slug'''),'name': record.get('name'''),'source_url': record.get('source_url'''),'source_type': record.get('source_type'''),'http_status': record.get('http_status'),'review_status': record.get('review_status''needs_manual_review'),'risk_level': evidence.get('risk_level''unknown'),'title_candidate': suggested.get('title_candidate'''),'summary_candidate': suggested.get('summary_candidate'''),'pricing_candidate': suggested.get('pricing_candidate'''),'tags_candidate': suggested.get('tags_candidate', []),'review_notes': evidence.get('review_notes'''),'decision''review_later','editor_note''',    }

这里故意把默认决策设成:

review_later

而不是:

published

这是为了防止“采集到就发布”的危险默认值。

第五步|生成 HTML / CSS / JS

脚本要生成 3 个页面文件:

site/index.htmlsite/styles.csssite/app.js

其中 index.html 负责页面结构,styles.css 负责样式,app.js 负责审核交互和导出。

app.js 里最关键的是这 4 个动作:

const actions = ["approve""approve_with_edits""reject""review_later"];const actionLabels = {approve"通过",approve_with_edits"修改后通过",reject"拒绝",review_later"稍后复查",};

这 4 个动作对应的实际含义是:

动作
什么时候用
通过
来源可靠,字段基本准确,可以进入下一篇合并流程
修改后通过
工具有价值,但摘要、标签、价格描述需要人工改写
拒绝
来源不适合、风险高、内容过期或不符合站点定位
稍后复查
暂时不确定,先不要进入正式数据

页面导出时,不直接写文件,而是把 JSON 放进文本框:

functionrefreshExport() {const output = reviewQueue.map((item) => ({slug: item.slug,name: item.name,source_url: item.source_url,decision: item.decision,editor_note: item.editor_note,suggested_update: {title: item.title_candidate,summary: item.summary_candidate,pricing: item.pricing_candidate,tags: item.tags_candidate,    },  }));  exportBox.value = JSON.stringify(output, null2);}

为什么不让页面自动写入本地文件?

因为普通浏览器页面直接写本地文件会涉及权限和安全限制。小白阶段先用最稳的方式:复制文本框内容,手动保存成 JSON 文件

第六步|写验证脚本

新建文件:

scripts/check-review-admin.py

检查脚本至少要做 5 件事:

1. data/collected-tools-review.json 存在,并且是非空数组2. site/index.html 存在3. site/styles.css 存在4. site/app.js 存在5. app.js 包含 4 个审核动作,而且没有默认 published

核心检查可以这样写:

from pathlib import Pathimport jsonimport reROOT = Path(__file__).resolve().parents[1]DATA = ROOT / 'data'SITE = ROOT / 'site'INPUT = DATA / 'collected-tools-review.json'REQUIRED_ACTIONS = ['approve''approve_with_edits''reject''review_later']records = json.loads(INPUT.read_text(encoding='utf-8'))app = (SITE / 'app.js').read_text(encoding='utf-8')for action in REQUIRED_ACTIONS:assert action in app, f'缺少审核动作:{action}'assertnot re.search(r'decision"\s*:\s*"published"|review_status"\s*:\s*"published"', app)assertnot (DATA / 'tools.json').exists()print('✅ 审核后台检查通过')

这段检查的重点是最后两行:

不能默认 published不能创建 data/tools.json

只要这两条守住,采集数据就不会绕过人工审核。

第七步|运行验证命令

在 lesson-07 目录运行:

python3 scripts/generate-review-admin.py && python3 scripts/check-review-admin.py

我这次真实输出是:

文字版如下:

✅ 审核后台生成完成输入记录:5 条生成文件:site/index.html, site/styles.css, site/app.js审核动作:通过 / 修改后通过 / 拒绝 / 稍后复查发布闸门:未创建或覆盖 data/tools.json✅ 审核后台检查通过待审核记录:5 条页面文件:index.html / styles.css / app.js 均存在审核动作:通过、修改后通过、拒绝、稍后复查正式数据保护:未创建/覆盖 data/tools.json

如果你看到这些输出,本篇 demo 就跑通了。

然后打开:

site/index.html

你会看到一个本地审核页。你可以给每条工具选择“通过 / 修改后通过 / 拒绝 / 稍后复查”,再点击刷新导出结果。

第八步|保存审核结果

页面底部有一个“导出审核结果 JSON”的文本框。

你复制里面的内容,新建文件:

data/review-decisions.json

然后保存进去。

这一份文件大概长这样:

[{"slug":"cursor","name":"Cursor","source_url":"https://cursor.com","decision":"review_later","editor_note":"摘要需要改成自己的话,价格信息下一步再确认","suggested_update":{"title":"Cursor: AI coding agent","summary":"Built to make you extraordinarily productive, Cursor is the best AI coding agent.","pricing":"paid","tags":["website","pricing","summary","tags"]}}]

注意:上面只是说明结构。你自己的导出文件,要以页面文本框里的内容为准。

常见报错和排查

1. 找不到 collected-tools-review.json

如果运行时报:

缺少 data/collected-tools-review.json

先检查你有没有从第 6 篇复制文件:

ls data

应该能看到:

collected-tools-review.json

如果没有,就回到第二步重新复制。

2. 页面打开后没有数据

先重新生成页面:

python3 scripts/generate-review-admin.py

再检查 site/app.js 里面是否已经嵌入数据:

python3 - <<'PY'from pathlib import Pathtext = Path('site/app.js').read_text(encoding='utf-8')print('source_url 出现次数:', text.count('source_url'))PY

如果出现次数大于 0,说明数据已经进了页面文件。

3. 检查脚本提示创建了 data/tools.json

本篇不应该创建:

data/tools.json

如果你看到这个文件,先不要继续。删除它,再检查 WorkBuddy 生成的脚本有没有写入正式工具库的逻辑。

rm data/tools.jsonpython3 scripts/check-review-admin.py

等检查通过后再继续。

4. 页面能看,但导出内容没变化

检查按钮是不是绑定了 refreshExport()

在 site/app.js 里应该能看到:

exportBtn.addEventListener("click", refreshExport);

如果没有,让 WorkBuddy 帮你补上这句,再重新打开页面。

完整代码 / 配置汇总

本篇完整 demo 已保存到:

tutorials/ai-tool-directory/demo/lesson-07/

关键文件:

prompts/workbuddy-review-admin-prompt.mdscripts/generate-review-admin.pyscripts/check-review-admin.pysite/index.htmlsite/styles.csssite/app.jsdata/collected-tools-review.json

验证命令:

cd tutorials/ai-tool-directory/demo/lesson-07python3 scripts/generate-review-admin.py && python3 scripts/check-review-admin.py

成功标准:

✅ 审核后台检查通过正式数据保护:未创建/覆盖 data/tools.json

这一篇你学会了什么

这一篇我们没有追求复杂后台,而是先把数据流里最危险的一步拦住:

采集结果不能直接进正式工具库,必须先经过审核队列。

你现在已经有了:

  • 一个本地可打开的审核页面;
  • 4 种清晰的人工决策;
  • 一份可导出的审核结果 JSON;
  • 一个防止误写正式数据的检查脚本。

这就让 AI 工具站从“能采集”往“能运营”迈了一步。

下一篇预告

下一篇是:

用WorkBuddy做AI工具站08:做榜单和推荐

第 8 篇我们会继续使用本篇导出的审核决策,把通过或修改后通过的工具,做成一个简单榜单:例如“新鲜工具榜”“适合小白榜”“AI 编程工具榜”。

目标不是做复杂算法,而是先做一个透明、可解释、能被用户理解的推荐规则。

资料来源

  • 本系列前文 demo:collected-tools-review.jsontool-source-map.jsonsource-policy.json
  • Python 标准库文档:jsonpathlibhtml
  • 浏览器本地页面能力:HTML / CSS / JavaScript 基础交互