让 AI Agent 安全管理 WordPress:一次分类与标签重构中的失败、回滚与最终方法
AI Agent 很适合处理重复的 WordPress 管理任务,但“可以调用 API”并不等于“适合自由决定网站结构”。
一次较大规模的分类与标签重构,很容易暴露这个差异。
表面目标可能很简单:
- 减少过度细分的 Category;
- 将三级结构压缩为较稳定的两级结构;
- 清理明显错误的 Tag;
- 保留真正有检索价值的细粒度主题;
- 不改变正文、Slug、发布时间和文章状态。
真正困难的部分,却不是 REST API,而是如何把语义决策和机械执行彻底分开。
第一类失败:用字符串代替语义
最早出现的问题,是使用简单字符串规则生成 Tag。
这种方法对长而明确的关键词有时有效,但对短词非常危险。
例如,一个只有几个字母的技术名词,可能恰好出现在:
- directory
- operator
- monitor
- editor
- vector
等完全不相关的单词内部。
如果使用:
if keyword in body:
add_tag()
就会产生大量假阳性。
这类错误的危险之处在于:系统表面上运行成功,API 返回 200,数据库也没有损坏,但网站语义已经被污染。
因此,HTTP 成功不等于任务成功。
第二类失败:过度依赖“语义审计”
发现字符串规则不可靠之后,一个自然的想法是:让模型重新阅读文章,然后判断 Tag 是否应该保留。
这看起来更智能,但仍然可能产生另一种错误:假阴性。
例如,一篇明显讨论某种疾病分级的文章,可能因为审计模型采用了错误的“检索价值”标准,而把疾病 Tag 判成无关;一篇围绕滴定原理的实验文章,也可能被错误建议删除 Titration。
问题不在于模型完全不理解文章,而在于:
模型每次运行时使用的判断标准可能略有漂移。
如果一次审计追求“Tag 要足够具体”,另一次又追求“Tag 不应与 Category 重叠”,同一批文章就可能得到完全不同的结果。
因此,大规模 taxonomy 改造不能建立在无限循环的“再审计一次”上。
第三类失败:执行器把无意义差异当成错误
即使最终决策已经正确,执行层也可能出现低级问题。
例如 WordPress 返回的 Tag ID:
计划: [302, 242, 228, 337]
返回: [302, 337, 242, 228]
从 taxonomy 语义看,这两个集合完全相同。
如果验证器直接使用数组比较:
actual == expected
就会错误判定失败。
正确方法应该是:
sorted(set(actual)) == sorted(set(expected))
这类错误非常值得警惕,因为它会触发一个荒谬的结果:
WordPress 实际写入完全正确,却因为验证器不理解集合语义而执行回滚。
所以验证器本身也必须被审计。
最终方法:模型决策,代理只执行
经过多轮尝试后,最稳定的架构并不是“让 Agent 更聪明”,而是减少 Agent 在执行阶段的决策权。
最终流程可以分成两部分。
第一部分是离线决策:
历史 taxonomy
+ 当前文章数据
+ 必要的人工语义复核
↓
生成静态最终计划
第二部分是在线执行:
读取最终计划
→ 解析 Category / Tag ID
→ 计算差异
→ 写入
→ GET 回读
→ 集合验证
执行 Agent 不需要再回答:
- “这篇文章更像 Linux 还是 Network?”
- “这个 Tag 是否还有价值?”
- “要不要顺便删掉这个空标签?”
这些问题在写入前已经解决。
旧 taxonomy 本身就是重要证据
重构老站点时,很容易忽略一个事实:旧分类虽然看起来复杂,却包含大量人工历史信息。
例如原来存在:
Tech
└── Linux
├── Arch
├── Ubuntu
├── Desktop
└── Filesystems
如果新的目标结构只保留:
Tech
└── Linux
那么这些旧三级分类不应该直接丢弃。
更合理的做法是:
- Category 压缩到
Tech > Linux; - 原来的
Arch、Ubuntu、Filesystems等细粒度信息转化为 Tag。
这样既降低了分类树复杂度,又保留了原有检索价值。
不要把所有文章重新交给模型分类
如果站点有大量文章,而且旧 taxonomy 大部分本来就是正确的,那么完全重新分类反而会增加风险。
更稳定的策略是:
明确旧分类
→ 机械映射
真正模糊的旧分类
→ 单独列出
→ 逐篇判断
例如:
Tech > Linux > Arch
→ Tech > Linux
这种关系不需要 AI 重新阅读正文。
真正需要语义判断的,只应该是类似:
Misc
Archive
Shares
Tools
Fix
Uncategorized
这种原分类本身就缺少明确主题的信息。
这样可以把“上千篇文章重新分类”的问题,缩小成“少量真正模糊文章需要判断”。
最终计划应该是静态文件
一旦内容决策完成,应当生成一个不可歧义的计划文件。
例如:
{
"post_id": 1234,
"final_category": "Tech > Linux",
"final_tags": [
"Arch Linux",
"Wayland"
]
}
每篇文章都拥有明确的最终状态。
执行 Agent 只负责把名字解析成 WordPress term ID,然后写入。
这种方法有三个明显优势:
- 执行之前就能完整审计结果;
- 执行过程中不会发生语义漂移;
- 出现问题时能够明确判断是“计划错误”还是“执行错误”。
写入前必须有快照和回滚清单
对于大规模修改,最好同时生成两类文件。
第一类是完整快照:
post_id
category IDs
tag IDs
slug
status
date
author
content hash
excerpt hash
第二类是 rollback manifest:
post_id
before_categories
before_tags
planned_categories
planned_tags
如果执行中途真正发生异常,只需要把已经修改过的文章恢复到 before_categories 和 before_tags。
由于正文从未进入更新 payload,回滚范围也非常小。
不要在同一轮删除 taxonomy definition
还有一个非常实用的经验:
文章关系调整和 taxonomy definition 删除最好不要同时进行。
某个 Tag 最终可能没有任何文章引用,但保留一个空 Tag 的代价极低。
相反,立即删除可能影响:
- term ID;
- Slug;
- archive URL;
- 历史链接;
- 之后的恢复工作。
因此,大型迁移过程中更安全的策略是:
先让文章关系正确
→ 冻结
→ 以后有明确需求时再考虑 term 清理
“后台看起来更干净”不是值得承担额外风险的理由。
正确的执行 Gate
正式写入之前,应该计算出一组确定值,例如:
计划文章数
Category 修改数
Tag 新增关系数
Tag 删除关系数
最终关系总数
无 Tag 文章数
最大 Tag 数
如果运行时重新计算得到的数字与计划不一致,就停止。
不要让 Agent 自己说:
“只差一条,应该没问题,我帮你修一下。”
这种自动“体贴”正是批量运维最危险的行为之一。
每批写入后立即验证
比较稳妥的批量策略是每次只处理少量文章,然后回读。
流程类似:
Batch 1
→ PUT/POST
→ GET
→ compare sets
→ PASS
Batch 2
→ PUT/POST
→ GET
→ compare sets
→ PASS
一旦出现真正的集合差异,立即停止后续批次。
这里尤其要注意:
- Category / Tag 比较采用集合;
- Slug 和 Status 必须精确相等;
- content / excerpt 可以使用 SHA256 比较;
modified时间允许变化,因为 taxonomy 更新本身可能触发修改时间。
最终验收比“任务完成”更重要
一个 Agent 输出:
SUCCESS
并不能证明工作真的完成。
最终验收至少应该独立确认:
- 总 Post 数没有变化;
- publish/private/draft 数量没有变化;
- 每篇恰好一个 Category;
- Uncategorized 是否符合预期;
- Category tree 是否未被意外修改;
- Tag definition 是否未被意外创建或删除;
- 文章正文 hash 是否保持;
- Slug 是否保持;
- 最终 Category / Tag 是否逐篇与计划一致。
只有最终状态与静态计划完全一致,才应该把这次迁移视为成功。
最终得到的不是“完美 taxonomy”,而是稳定基线
这类工作最容易陷入一个误区:不断寻找更好的分类方法。
实际上,长期维护需要的不是理论上的最优结构,而是一个:
- 能理解;
- 可预测;
- 可验证;
- 能长期使用;
- 不需要频繁重构;
的稳定基线。
当最终结构已经达到目标后,最正确的动作往往是停止继续优化。
后续的新文章按照相同规则正常维护即可。
总结
AI Agent 管理 WordPress 最有价值的地方,不是让模型自由决定一切,而是把重复的机械工作交给它,同时把高风险决策提前冻结。
一个可靠的流程应该是:
历史数据
→ 决策
→ 静态计划
→ 快照
→ 预计算
→ 小批量写入
→ GET 回读
→ 集合验证
→ 最终完整性审计
→ 冻结基线
当语义决策和执行权限真正分离之后,AI Agent 才从“会操作后台的聊天机器人”变成了一个可以用于真实运维的执行工具。