墨天轮(MODB)的这套系统一直由我维护。过去,Sitemap 也主要靠人工更新:从多张业务表取数、拆分文件、更新前端仓库,再跟随发布流程上线。随着内容规模不断增长,这项工作越来越复杂。在人手有限、其他业务优先级更高的情况下,我中断了 Sitemap 的持续维护。

这不是维护意愿的问题,而是原来的维护方式已经很难靠有限人力长期坚持。Opsx 第一期完成后,我想用这个真实任务验证一件事:当 AI 能通过 Opsx 连接源码、主机、数据库和 OSS,它能不能帮我重新启动 Sitemap 维护,并把一次复杂操作变成以后可以持续运行的机制?

这次实践的真正目标,不是一次性补齐 120 万个 URL,而是建立一套不再持续占用工程师时间、能够让原创内容稳定进入搜索发现链路的长期机制。

先说说 Sitemap 是什么

Sitemap 是网站提供给搜索引擎的一份 URL 清单。它通常由一个 sitemap.xml 索引文件和若干 URL 分片组成,用来告诉 Google、Bing 等搜索引擎:网站有哪些页面、这些页面最近何时更新。

它不能直接保证页面被收录,但对内容量大、更新频繁的网站非常重要。搜索引擎不必只靠站内链接慢慢爬,可以从 Sitemap 快速发现新内容。

搜索引擎目前还是网站流量的第一大入口,虽然AI对搜索引擎有一定的冲击,但是基础的搜索引擎SEO对网站,尤其原创内容社区是非常必要的。

MODB 正是这样的站点。文章、问答、文档、标签、专题、招聘等内容来自不同的数据表,URL 数量已经超过 120 万。随着规模增长,Sitemap 早已不是生成一个 XML 那么简单。

我一开始只是让 Opsx 回答一个问题:

看看前端源码 /static 下的 XML 文件。这些是网站的 Sitemap,最新更新时间是什么时候?

这个尝试很快从核对更新时间扩展成一次完整的生产改造:迁移旧文件、补齐中断期间的数据、纠正数据源、重新设计存储结构、记录增量水位,再创建每周自动运行的 Shell Schedule。AI 负责解决重新启动时的复杂性,后续正常运行不再依赖 LLM,也不再消耗推理 Token。

整个过程都发生在同一个 Issue 中。Opsx 共记录了 27 次对话、888 个 Agent turns、1,761 个执行事件。Claude Code 调用 MiniMax-M3 完成本次治理,可归属到该 Issue 的已记录用量为 752,506 Token;期间还发生了 701 次 Shell 类工具调用。最终核对和处理 10 类内容、1,204,599 个 URL、45 个 Sitemap 索引条目

opsx_issue_sitemap.png

下面按实际发生的八个步骤展开。

第一步:让 Opsx + AI 重建完整的维护上下文

先确定“在操作什么”

即使系统一直是自己维护,时隔两年重新启动这项工作,也需要重新确认:前端仓库实际部署在哪台机器?数据库应该连接主库还是只读备库?OSS 使用哪个区域和 Bucket?文件处理脚本应该在哪个 Runtime 执行?这些信息分散在不同系统里,重新串起来本身就是成本。

Opsx 的做法不同。Issue #172 首先绑定源码资产 repo-modb-front,然后由资产关系和 Runtime 能力决定后续执行路径。

这背后是 Opsx 的一个基础设计:基于资产和知识的确定性运维。它不会只把一句 Prompt 丢给 LLM,再让模型猜仓库、环境和连接方式。每次操作都应该从已经解析出的资产身份开始,结合真实的元数据、架构图、上下游关系、影响范围和明确的 Runtime 路由;如果资产已有 Memory、Discovery Report 或 Knowledge,也会把其中经过验证的环境事实和历史经验带入当前 Issue。

资产身份与元数据    → 它对应哪个系统、属于什么环境、代码和配置在哪里
架构图与上下游关系  → 它连接哪些服务、主机、数据库和云资源
Memory / Discovery  → 目前已知的资产画像、运行特征和待确认项
Knowledge / Playbook → 过去验证过的事实、方法、风险和操作步骤
Runtime 路由与权限  → 应该在哪里执行、用什么能力、允许做到什么程度

所以,“前端仓库对应哪个服务、代码在哪里、应该连接哪个环境、命令在哪台主机运行”不是由模型临场发挥。LLM 负责在这些确定性上下文上推理,Opsx 负责解析目标资产、提供关系与知识,并把动作送到显式绑定的 Runtime。

这次实际涉及的资产和执行能力如下:

角色Opsx 中的资产 / Runtime用途
前端源码repo-modb-front读取 Git 历史、检查和修改 static/
应用主机host-moapp-0002Sitemap 文件所在主机,也是后续 Schedule 的目标资产
仓库 Shell Runtimedaemon-moapp-0002执行 Git、文件处理及 ossutilarm64
MogDB 备库db-mo16-0004-26000使用只读连接查询 Sitemap 数据缺口
数据库 Runtimedb-mogdb-01能力包括 shellclaude
OSS 资产oss-public-bj对应北京区域的公共 OSS 资源
OSS Runtimemes-agent-01已安装阿里云 CLI,可检查 OSS 资源
AI Runtimemes-app-01提供 claudeopencodeshell 能力

Issue 的主要分析由 mes-app-01 上的 Claude Code Runner 完成;执行记录显示实际调用的模型为 MiniMax-M3,通过 Anthropic 兼容接口运行。涉及源码、数据库或 OSS 的确定性操作,则由 Opsx 路由到对应 Runtime 执行。

这里很关键:AI 负责理解问题和制定下一步,但它不靠猜测选择生产目标。资产身份、资产关系和 Runtime 路由由 Opsx 控制。

执行记录也能看到这个过程:Agent 多次读取 Issue Context、Asset Info 和 Asset Knowledge。这个仓库最初已有的 Discovery 和 Memory 还不完整,因此第一轮仍需要结合现场证据和我提供的历史 SQL 来补充背景;但随着任务推进,后续 Execution 已经可以直接读取沉淀下来的知识,获得 OSS endpoint、ossutilarm64 的使用方式、旧 Git 版本限制以及远程 Shell 工作目录等信息,不必每次重新试错。知识在这里既是本次执行的输入,也是本次执行继续积累的输出。

这次还有两道刻意保留的生产护栏:

  • 云资源侧使用已经安装并配置好的阿里云 CLI,而不是让 AI 临时拼接云 API 或在网页控制台中盲目点击;
  • 数据库侧只向 Opsx 提供 MogDB 只读备库和只读账号,不向 Agent 暴露生产主库写权限。

这两点让 AI 获得完成任务所需的能力,但没有获得超出任务范围的权限。

AI 找到了什么

Opsx 检查了 /home/opsx/repo/modb-front/static、Git 历史和已有 XML。重新维护前,最后一次 Sitemap 相关内容更新停在:

776a1e4 | 2024-06-17 19:29:19 +0800 | update sitemap date

到本次处理时,已经过去约两年两个月。

同时,原有架构也已经不适合继续扩展:历史 Sitemap 直接放在前端仓库的 static/ 目录中。网站内容不断增长,XML 文件会越来越多、越来越大,不仅占用源码仓库空间,还把“内容数据发布”和“前端代码发布”绑在了一起。

过去由我人工完成这一步,需要在源码平台、应用主机、数据库和 OSS 之间逐个确认。现在 Opsx 已经把这些对象连接成资产,AI 可以围绕一个 Issue 连续调查,不需要我再次打开四套平台、维护多个终端,再手工拼接结论。

第二步:重新设计 Sitemap 架构

确认现状后,没有直接生成新文件,而是先确定未来架构。

旧结构大致是:

数据库
  ↓ 人工 SQL
大量 Sitemap XML
前端仓库 static/
跟随前端代码一起发布

新结构改成:

MogDB 原始数据
Opsx + Shell 生成与校验
OSS sitemap/ 目录保存全部 URL 分片和主索引
CDN / 搜索引擎

前端仓库
├── static/sitemap.xml   # 只保留一个入口,指向 OSS 主索引
└── static/robots.txt    # 声明同一个 OSS Sitemap 地址

仓库中的 static/sitemap.xml 被缩小成一个很轻的跳转索引:

<?xml version="1.0" encoding="UTF-8"?>
<sitemapindex xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
  <sitemap>
    <loc>https://oss-emcsprod-public.modb.pro/sitemap/sitemap.xml</loc>
    <lastmod>2026-08-19T11:38:16+08:00</lastmod>
  </sitemap>
</sitemapindex>

同时确认仓库中的 static/robots.txt 已经声明同一入口:

Sitemap: https://oss-emcsprod-public.modb.pro/sitemap/sitemap.xml

因此这次不需要重复修改 robots,只要保证仓库入口、robots 和 OSS 主索引三者一致。

这个设计带来三个直接好处:

  1. Sitemap 大文件不再占用前端源码仓库;
  2. 更新 Sitemap 不需要重新构建和发布前端;
  3. OSS 负责大文件存储和 CDN 分发,Git 只保留配置与增量状态。

第三步:把前端仓库中的 Sitemap 迁移到 OSS

方案看起来简单:上传文件,然后从仓库删除。但真正执行时,这一步比预期复杂得多。

先找到正确的 OSS 访问路径

Opsx 从 oss-public-bj 资产找到 mes-agent-01,确认该 Runtime 上已有阿里云 CLI。继续检查后又发现:最终要上传的 XML 就在 daemon-moapp-0002,而这台主机已经有可用的 ossutilarm64

阿里云 CLI 在这里不是一个可有可无的工具。它让 Agent 可以先用命令确认 bucket、区域和对象列表,并把结果直接带回 Issue:

aliyun oss ls oss://oss-emcsprod-public/sitemap/ \
  --region cn-beijing \
  --profile modb

如果没有 CLI,这一步通常要由人登录阿里云控制台、切换地域、进入 bucket、翻页查看对象,再把文件名复制出来与 Git 清单比较。这个过程不仅慢,也很难被 AI 连续执行和复核。CLI 把 OSS 从一个只能人工操作的网页,变成了 Opsx 可以编排、可以留证据的云资产能力。

不过,CLI 适合做云资源发现和清单核对,不代表所有文件都应该先传到 mes-agent-01。真正需要上传的 XML 已经位于 daemon-moapp-0002,因此批量传输最终使用同机的 OSS 官方工具 ossutilarm64。两者分工很清楚:

工具本次用途
阿里云 CLI确认 OSS 访问、bucket 区域和线上对象清单
ossutilarm64在 XML 所在主机直接执行批量上传、下载和验证

与其把几十个文件跨主机传给 mes-agent-01 再上传,不如直接在文件所在主机调用 OSS 官方工具:

OSSUTIL=/home/opsx/ossutilarm64
ENDPOINT=oss-cn-beijing.aliyuncs.com
BUCKET=oss-emcsprod-public

chmod +x "$OSSUTIL"

"$OSSUTIL" cp static/ask.xml \
  "oss://$BUCKET/sitemap/ask.xml" \
  --endpoint "$ENDPOINT" \
  --force

这里还踩了几个真实的坑:

  • OSS bucket 位于北京,但某些 CLI 默认 profile 指向杭州,必须显式指定 endpoint;
  • ossutil 使用自己的配置文件,不能直接假设它读取阿里云 CLI 的 profile;
  • 仓库里的 ARM64 ossutil 最初没有执行权限,需要先 chmod +x
  • 目标主机上的 Git 版本较老,不支持一些现代参数。

Git 是这次迁移的回退底座

这次能安全处理 31 个大文件,还有一个容易被忽略的前提:前端代码和 Sitemap 历史一直由 Git 管理。

Opsx 没有直接用 rm 抹掉文件,而是让删除进入 Git 的变更记录。迁移顺序也刻意拆开:

检查 Git 工作区和当前分支
上传 OSS
重新列举 OSS 对象并校验文件
git rm 删除仓库中的旧 Sitemap
检查 diff 后独立提交
新增轻量 sitemap.xml 入口并再次提交

最终两次关键变更都有独立 Commit:

976df18  chore(static): remove sitemap xml files (moved to OSS bucket)
61161ae  chore(static): replace removed sitemaps with OSS-backed index

前面 7 个漏传文件,就是从上一个 Git 版本精确恢复出来的。这不是理论上的“可以回退”,而是本次任务真正使用过的恢复手段。

如果入口文件、robots 或增量状态改错,可以按文件恢复;如果整次提交有问题,已经共享的分支可以通过 git revert 生成反向提交:

# 兼容目标主机的旧 Git,从指定版本恢复某个文件
git checkout <known-good-commit> -- static/sitemap.xml

# 对已经推送的错误提交做可审计回退
git revert <bad-commit>

Git 带来的不是“绝对不会出错”,而是让错误可见、修改可审、历史可查、仓库内容可恢复。再加上 Opsx Issue 中保存的命令和执行证据,即使 AI 改错,也能知道改了什么、由哪次执行产生,并回到已知正确版本。

当然,Git 只能保护仓库中的代码、入口和状态文件,不能自动回退已经覆盖的 OSS 对象。OSS 侧仍需依靠上传后校验,并建议开启对象版本控制。仓库 Git 历史与 OSS 对象版本共同组成完整的回退机制。

第四步:从现有 Sitemap 找最大值,再跨到数据库寻找 gap

迁移只是把旧内容换了存储位置,并没有解决维护中断两年间缺失的数据。

下一步需要针对每一类 URL 做两件事:

  1. 从 OSS 已有 Sitemap 中提取当前最大 ID 或最后日期;
  2. 到 MogDB 查询该表的最新数据,计算两者之间的 gap。

这一步最能体现 Opsx 与普通 AI 聊天工具的区别。

源码在 repo-modb-front,旧分片在 oss-public-bj,业务数据在 MogDB 备库 db-mo16-0004-26000。三者位于不同资产、不同主机和不同访问方式下,但都已经接入 Opsx:

repo-modb-front
      │ 读取旧文件与 Git 历史
daemon-moapp-0002 ───────► oss-public-bj
      │                    读取线上分片
      └──────────────────► db-mo16-0004-26000
                           只读查询当前数据

为什么只接入只读备库

这次没有让 AI 直接连接生产主库。Opsx 使用的是 MogDB 备库资产 db-mo16-0004-26000,通过 db-mogdb-01 Runtime 和只读账号查询。执行前还确认了数据库处于 recovery 状态。

所有数据库操作都限制为 SELECTCOPY (...) TO STDOUT

COPY (
  SELECT id
  FROM cs_db_doc
  WHERE id > :last_max_id
  ORDER BY id
) TO STDOUT;

这样做有三层价值:

  1. 权限隔离:账号本身没有写权限,即使 Agent 生成了错误语句,也不能修改业务数据;
  2. 负载隔离:十张表的范围查询和批量导出落在备库,尽量不占用生产主库资源;
  3. 能力收敛:Opsx 只把完成 Sitemap 所需的读取能力提供给 Agent,而不是因为用了 AI 就放大权限。

AI 运维要提高效率,但不能用扩大生产风险来换效率。资产路由、Runtime 能力和数据库只读权限共同构成了防线。

如果人工处理,通常是一个人先登录前端主机写脚本解析 XML,再切换数据库客户端查询十张表,然后打开 OSS 控制台逐一核对文件。Opsx 把这些动作放进同一个 Issue:AI 负责维护整体计划,具体查询由相关资产上的 Shell Runtime 执行,返回结果继续进入同一上下文。

最终确认了十类数据:

数据表URL 前缀重建或核对的 URL 数
cs_knowledge/db/634,193
cs_datalk/datalk/343,898
cs_db_doc/doc/125,013
cs_tag/tag/51,317
cs_db_ask/issue/27,544
cs_db_invite/bid/14,761
cs_column/topic/2,578
cs_db_entry/wiki/2,588
cs_exam_daily/test/2,145
cs_recruit/job/562

这里还发生了一次重要纠错。AI 最初把 Elasticsearch 的 knowledge 索引当成数据源,那里只有约 39 万条文档。用户指出 cs_knowledge 才是原始数据后,Opsx 立即切换到 MogDB 重新验证,最终得到 634,193 条公开且未删除的数据

这不是一段需要隐藏的“AI 犯错”。在生产环境中,人本来就应该负责业务事实和关键判断。Opsx 的作用是:事实被纠正后,AI 能迅速重跑所有查询和验证,并把正确结论留给下一次任务。

第五步:生成 gap 期间的 Sitemap,并发布到 OSS

确定 gap 后,开始按表生成缺失 URL。

生成过程没有让 LLM 一行一行输出 XML,而是让 AI 组织 SQL 和 Shell,再交给数据库批量导出。下面是 Knowledge 的核心查询,连接参数已省略:

GSQL -c "COPY (
  SELECT id
  FROM cs_knowledge
  WHERE encrypt_level = 'PUBLIC'
    AND status <> 0
    AND id::bigint > $last_max
  ORDER BY id::bigint
) TO STDOUT" > knowledge_ids.tsv

不同内容的 URL key 并不完全相同:普通内容使用数值 ID,标签使用 name,每日考试使用 YYYYMMDD。脚本按 URL 类型生成标准 <url> 节点:

awk -v prefix="$url_prefix" -v today="$TODAY" '
  NF {
    key = $1
    printf(
      "<url><loc>https://www.modb.pro%s/%s</loc>" \
      "<lastmod>%s</lastmod></url>\n",
      prefix, key, today
    )
  }
' ids.tsv > urls.xml

严格控制 50,000 URL 分片

Google 和 Sitemap 协议都要求单个 Sitemap 文件不超过 50,000 个 URL。因此生成逻辑会先统计最后一个 shard 的现有数量:

current_count=$(grep -c '<url>' "$local_shard" 2>/dev/null || echo 0)
new_count=$(wc -l < "$id_file")
room=$((50000 - current_count))

if [[ "$room" -ge "$new_count" && "$current_count" -gt 0 ]]; then
  target_shard=$last_shard
else
  target_shard=$(next_shard_name "$last_shard")
fi

文件生成后先做 XML 解析验证,再上传 OSS:

python3 -c \
  "import xml.etree.ElementTree as ET; ET.parse('$target_file')"

"$OSSUTIL" cp "$target_file" \
  "oss://$BUCKET/sitemap/$target_shard" \
  --endpoint "$ENDPOINT" \
  --force

Knowledge 最终重新生成 13 个分片:前 12 个各 50,000 条,knowledge_13.xml 为 34,193 条。

12 × 50,000 + 34,193 = 634,193

发布完成后,Opsx 继续验证 OSS 与 CDN,而不是看到上传命令成功就结束:

  • OSS 主索引可以被 XML parser 正常解析;
  • CDN 能正常返回最新文件;
  • 主索引共有 45 个条目;
  • 45 个条目的 lastmod 都是 2026-08-19
  • Knowledge 分片总数与 MogDB 查询结果一致。

最后我把生成sitemap手工提交到 Google Search Console 和 Bing Webmaster Tools,后期搜索引擎会自动调度robot抓取收录有价值的网页。

第六步:把最大值记录回仓库,建立增量水位

历史缺口补完以后,如果不记录最大值,下次仍要重新扫描 OSS 并反推水位。

因此 Opsx 在前端仓库中增加了状态目录:

static/.sitemap-state/
├── all_tables.tsv
├── knowledge.tsv
└── last_run.tsv

其中 all_tables.tsv 为每张表记录:

table
url_prefix
sitemap_files
max_id
count
url_type
source
generated_at

以后不需要重新扫描 120 万条历史数据,只需读取 max_id 并查询增量:

WHERE id > :last_max_id
  AND created_time > :seven_days_ago

新的分片和 OSS 主索引发布成功后,任务才会推进状态文件中的水位。状态文件不完整、XML 校验失败或索引上传失败时执行会硬失败,避免出现“线上没发成功,但最大值已经向前移动”的情况。

Git 在这里不再保存百万级 Sitemap 内容,而只保存体积很小、可审计的入口文件和增量状态。每次水位变化都能形成 diff:哪张表的 max_id 向前推进、增加了哪个 shard、何时生成,都可以 Review。

如果增量逻辑或水位写错,可以从 Git 恢复上一个正确状态,再重新执行对应批次。换句话说,Schedule 自动化并没有绕开代码管理;它把每周运行建立在一个版本化、可回退的状态基线上。

第七步:把过程沉淀为知识和 Playbook

AI 不是万能的。第一次处理一套真实生产系统时,有些事实只存在于维护者的经验中:某张表为什么才是权威数据源、哪些状态才算公开内容、应该连接主库还是只读备库、历史脚本为什么这样设计。资产信息可以告诉 AI“有什么”,但这些业务背景和判断标准,仍需要专业的人告诉它,必要时还要及时纠偏。

这次就有一个典型例子:AI 最初使用了 ES 中的 Knowledge 投影,但我明确指出,完整数据应以 MogDB 的 cs_knowledge 表为准。数据源纠正后,再进一步确认公开、未删除等过滤条件,AI 随后重新查询只读备库、修正生成结果并完成验证。这里人的作用不是亲自重复所有命令,而是提供关键事实、约束和验收标准;AI 则负责据此调整计划并完成后续的大量执行。

但这种指导不应该每次都从头再讲。如果成功经验只留在一次聊天里,下次维护还是要重新交学费。一次经过人确认、被执行结果验证的方法,应该进入 Opsx 的长期记忆;其中稳定的事实形成 Knowledge,包含多个步骤、判断和异常处理的复杂过程则进一步整理为 Playbook。

Issue 完成后,Opsx 把过程中确认的事实和踩坑整理成了可复用知识,其中包括:

  • kw_168(Article):记录 OSS bucket 的实际区域、endpoint、阿里云 CLI 与 ossutil 的配置差异,以及 CDN 地址和索引校验方法;
  • kw_170(Playbook):保存完整的 Sitemap 重建流程,包括十张表与 URL 的映射、MogDB 权威数据源、50,000 URL 分片、跨主机文件传输、OSS 索引更新及误删同名文件等风险;
  • kw_171(Asset Memory):汇总 repo-modb-front 的资产画像、Runtime 与服务关系、Sitemap 当前配置、已知环境限制、Issue #172 的执行结果和后续诊断要点。

opsx_sitemap_playbook.png

这一步看起来不像上传文件那样“有成果”,却完成了从个人经验到平台记忆的转换。下一次遇到同一资产或相似任务时,Agent 可以先读取这些已经由人校正、由执行验证过的结论,而不是再次猜测数据源、环境和操作方法。

在 Opsx 中,知识不是某个人电脑上的 Markdown。它与资产和 Issue 关联,后续 Agent 再次处理同一仓库、主机或数据库时,可以先读取已经验证过的结论:

人的背景说明与专业纠偏
Agent 执行、验证并完成任务
事实与证据进入 Knowledge
复杂方法整理为 Playbook
绑定 repo、host、database、OSS 等资产
下一次 Issue 自动获得相关上下文

所以,人并没有从闭环中消失,而是从反复执行者变成了知识提供者、关键决策者和结果审核者。只要这一次在人的指导下真正做成,Opsx 就能把事实、过程和方法保留下来。以后执行工具可以从 Claude 换成其他 Agent,也可以完全改用 Shell;资产事实、历史证据和 Playbook 仍然存在,下一次解决同类问题就会更快、更准确。这才是真正的复用。

第八步:创建每周更新 Sitemap 的 Schedule

补齐历史数据并不代表工作结束。墨天轮每周都会产生新的文章、文档、问答等内容,这些页面只有持续进入 Sitemap,搜索引擎才能更快发现并抓取。搜索引擎是否收录、如何判断原创来源,最终仍由它自己的算法决定;但如果原创内容发布后长期没有被发现,而转载页面反而先被抓取,就可能削弱原始页面的来源信号和搜索曝光机会。

所以,Sitemap 的及时性也是内容竞争力的一部分。优秀的原创内容发布后,应当尽快把规范 URL 提交给搜索引擎,而不是等到几个月后再集中补数据。每周 Schedule 把原来不确定的人工更新时间,收敛为最长一周的固定更新窗口;如果以后对时效性要求更高,只需调整 Cron 频率,不需要重新设计整套流程。

这一步的目标,是让 Sitemap 增量成为内容发布链路中的固定环节,不再依赖我每周专门腾出时间处理。Schedule 每次读取上次记录的最大值,只查询新产生的内容,生成新的 URL 分片并更新 OSS 索引,不需要重复处理已有的 120 万个 URL。

Opsx 创建了真实 Schedule:

配置项
名称modb weekly sitemap incremental update
Schedule IDpissue_a8741c6b15c1
Workspacemodb
目标资产host-moapp-0002
Runnershell
Cron0 8 * * 1
时区Asia/Shanghai
状态active

即每周一北京时间 08:00 执行。

opsx_sitemap_schedules.png

为什么我特意选择 Shell Schedule

这里选择 shell 不是退而求其次,更不是因为 Opsx 只能调度脚本。恰恰相反:前七步已经借助 AI 把数据源、过滤条件、增量水位、分片规则和发布流程全部研究清楚,原本不确定的工作已经可以收敛成确定性程序。

我目前在 Opsx 中建立的 Schedules 都采用 Shell Runner。周期任务追求的不是每次“重新思考”,而是每次都以相同规则稳定、快速地完成。

Shell Schedule 有几个非常实际的优势:

  1. 结果确定:同样的状态和输入会走同一段脚本,不受模型输出波动影响;
  2. 启动和执行更快:不需要等待模型推理,也没有多轮工具调用;
  3. 不消耗 LLM Token:正常的每周增量完全由 Shell 和数据库完成,长期运行成本可预测;
  4. 不依赖模型可用性:LLM 服务限流、升级或短暂不可用,不会影响常规 Sitemap 更新;
  5. 更容易审计:查询条件、失败边界和发布顺序都写在脚本中,可以版本化、Review 和复现;
  6. 权限更容易收敛:Schedule 只获得目标主机、只读备库和 OSS 所需的最小能力。

因此,这套任务采用分层执行方式:

阶段执行方式作用
重新启动复杂维护Opsx + AI Agent分析资产、核对历史状态、发现 gap、设计新架构
规则确认后的周期运行Opsx + Shell Schedule以零推理 Token、确定性方式快速重复执行
出现新异常或规则变化回到 Issue,按需调用 AI读取历史证据,诊断并更新脚本或 Playbook

也就是说,AI 不必永远待在执行链路上。它先把未知问题解决并“结晶”为脚本,正常路径随后退出 LLM,只有遇到新问题时才重新介入。

这些 Shell 逻辑、入口文件和增量状态同样走 Git 管理,Schedule 并没有把代码变成一段无人知道版本的黑盒。每次调整都应该对应 diff 和 Commit;新版本有问题时,先回退到已知正确的 Git 版本,再由 Opsx 重新触发执行即可。

因此这里实际上有三层保障:

Git       → 管代码版本、diff 和回退
Shell     → 提供稳定、快速、零推理 Token 的确定性执行
Opsx      → 管资产、Runtime、调度、证据和执行历史

每周的确定性执行链如下:

读取上次 max_id
在 MogDB 备库查询本周增量
追加最后一个 shard 或创建新 shard
校验 XML 并上传 OSS
更新和验证主索引
推进 max_id,记录本次执行结果

这也不是普通 Crontab。Crontab 只保存“什么时候执行哪条命令”;Opsx Schedule 还保存目标资产、Workspace、Runtime 路由、Runner、每次执行记录以及关联知识。Shell 提供确定性,Opsx 提供资产上下文、集中调度、执行历史和失败后的继续处理能力。

回头看:如果全部由人来做

这次任务并不是因为用了 AI,就从此不需要工程师。我对 cs_knowledge 数据源的纠正非常关键。Opsx 的价值,是把人的介入位置从“亲自执行所有机械步骤”提升到“定义目标、校正事实、审核关键结果”。

环节纯人工处理Opsx + AI
找环境问人、查文档、逐台登录从资产关系直接定位 repo、host、database、OSS 和 Runtime
查现状多个平台来回切换,手工汇总结论一个 Issue 连续收集跨资产证据
操作 OSS登录控制台、切地域、翻页并手工复制对象清单阿里云 CLI 将云资源查询变成可编排、可复核的命令
查询数据库人工登录主库或临时申请高权限账号只通过只读备库查询,隔离写权限和主库负载
修改代码和状态临时备份文件,出错后很难还原完整现场Git 记录 diff 和 Commit,可按文件恢复或审计式回退
遇到超时靠记忆判断做到哪一步27 次执行及中间结果都由平台保存
找数据 gap人工解析 XML,再逐表查询数据库AI 维护全局计划,各 Runtime 在正确资产执行查询
生成 120 万 URL人写一次性脚本并手工检查分片AI 设计流程,数据库和 Shell 批量执行、自动验证
处理经验留在个人脑中或临时文档形成资产关联的 Knowledge 和 Playbook
后续更新等人记得再次操作Schedule 每周读取水位自动增量
周期运行成本人工值守,或每次重新调用 AIShell Runner 快速执行,不消耗 LLM Token

Opsx 的核心价值:让 AI 形成完整的运维闭环

复盘这次实践,Opsx 的核心并不是“给 AI 一个 Shell”,而是 Landing Page 上强调的设计:先知道资产,复用 Opsx 已经学到的知识,再确定性地行动。 每次操作都从已解析的资产身份、真实拓扑、影响上下文和明确的 Runtime 路由开始,而不是依赖 LLM 猜测。

更准确地说,Opsx 是运维中枢,LLM 提供推理能力,Issue 保存当前任务上下文,资产图谱提供事实边界,Memory、Discovery Report、Knowledge 和 Playbook 构成长效记忆,Claude Code 等 Agent 则是可以替换的“手”。Runtime 把这些手安全地连接到源码、主机、数据库和 OSS,Git 提供可审计、可回退的安全网,Schedule 则把已经验证的动作变成稳定的“自动反射”。

资产图谱:Identity · Metadata · Relations · Topology
知识上下文:Memory · Discovery · Knowledge · Playbook
                 Opsx Issue / LLM
                    判断与调整计划
              Agent / Shell + Runtime
              repo · DB · OSS · host
             证据回流并更新资产与知识

在 Sitemap 案例中,资产图谱先确定 repo-modb-front 的身份、代码位置及其与前端服务的关系,再以它为锚点,从同一 Workspace 的资产和关联关系中定位应用主机、只读备库和 OSS,并为每个动作选择正确的 Runtime。已有 Knowledge 提供环境经验,缺失的事实则通过执行和人工纠偏补齐。Claude Code 维护同一个问题上下文,但实际操作由多只“手”完成:仓库 Runtime 检查代码、Git 和文件,数据库 Runtime 查询只读备库,OSS Runtime 借助阿里云 CLI 核对云端对象。

每次操作的现象、失败原因和结果都会返回 Issue,LLM 再依据新证据调整计划——包括从不完整的 ES 数据纠正到 MogDB 原始数据。独立任务可以由不同 Agent 和 Runtime 并行处理;有依赖的步骤则在证据返回后继续推进。即使经历失败和取消,资产身份、知识上下文和任务进度也不会随一次执行结束而丢失。

最终,AI 解决未知问题,Memory 和 Knowledge 更新资产认知,Playbook 保存复杂方法,Git 管理变更与回退,Shell Schedule 以零推理 Token 持续复用成果。Opsx 不是又一个会执行命令的 Agent,而是一套基于资产和知识的确定性运维系统:执行能力可以替换,持续积累的资产事实、证据和运维智慧不会丢失。

最终得到的,不只是一批 XML

这次实践最终完成了:

  • 完成存量治理:重新启动 Sitemap 维护,核对并补齐十类内容,共 1,204,599 个 URL;
  • 升级存储与发布方式:将大文件从前端仓库迁移到 OSS,仓库只保留入口和增量状态;
  • 控制生产风险:使用阿里云 CLI、MogDB 只读备库和 Git,让资源操作可复核、数据库不可写、代码修改可回退;
  • 把经验变成平台记忆:基于资产身份和架构关系确定执行路径,并将人的纠偏、执行证据和复杂方法沉淀为 Knowledge 与 Playbook;
  • 把一次治理变成持续机制:创建资产绑定的每周 Shell Schedule,正常路径以确定性方式执行,不依赖 LLM,也不消耗推理 Token。

最终得到的不是一批 XML,而是一套能持续运行的 Sitemap 维护机制:AI 负责解决第一次的不确定性,Opsx 连接资产、知识与执行,Shell 则稳定复用已经验证过的成果。