agent-fleet-manager
一个通用引擎,用于由一组 worker(普通抓取器、爬虫或 LLM agent)进行大规模、重复性的信息采集。你只需注册要检查的目标和检查频率;引擎会调度到期任务、以隔离批次将工作租约出去、记录返回结果、通过内容哈希检测变更、在失败时退避,并为每一次写入保留可审计的账本。一个 SQLite 文件就是整个系统,仅依赖 Python 标准库。
它源自一个生产系统:在那里,由 LLM agent 和普通抓取器组成的混合编队按日和周的节奏追踪数千个信息源。这是对其中可通用部分的彻底重写:记账。引擎从不解释某个信息源“是什么”——route 字段对它毫无意义,却对你的 worker 意味着一切——这也是同一个引擎能够运行截然不同编队的原因。
这类系统的常见用途
- 销售线索挖掘。 注册目标公司的招聘页面、新闻页面和融资公告。招聘页面哈希变化就是一个招聘信号;你的 worker(或读取 diff 的 LLM agent)会把它转化为一条带时间戳和凭证的销售线索。
- 竞争对手与价格监控。 定价页、功能页、更新日志、应用商店列表——按节奏检查,带有可触发告警的
changed标志和可绘制成图的历史记录。 - 监管与合规追踪。 政府机构页面、法规数据库、发布的指引。哈希账本还可用作变更何时出现、你何时看到的证据。
- 研究语料维护。 必须保持最新的数据集、预印本订阅源、文档集。由于一切操作按哈希幂等,重新摄取是安全的。研究工具示例:alphaXiv。
- 市场与列表监控。 招聘板、房产列表、拍卖品——任何“最先发现变化”就是价值所在的场景。
在所有这些场景中,引擎的贡献都是一样的:你的数千个信息源中哪些此刻到期、哪些真正发生了变化、哪些正在失败并退避,以及这一切的凭证。
模型设计
五张表(见 agentfleet/schema.sql):
- source —— 一个待检查对象:一条路由、一个节奏、一个
next_due_at、一个错误连击计数 - action —— 一个工作单元;状态流转为
QUEUED → LEASED → RUNNING → DONE | FAILED,在剩余尝试次数内会被重新入队 - batch —— 租约给某个 worker 的一批 action,附带一个只有该 worker 才会触碰的写作用域目录
- observation —— 一次检查的结果:内容 sha256、字节数、耗时、凭证路径、
changed标志 - change_log —— 每一次规范化写入,都标注执行者和原因
三条规则支撑整个设计。worker 从不写入规范化状态;它们只把结果文件放进自己的写作用域,由父进程在 reconcile 阶段合并进来,因此崩溃或行为异常的 worker 最多只能弄坏自己的临时目录。变更检测基于内容哈希,因此任何一次运行都可以安全地重复。每一次规范化写入都有归属,当多个 agent 共享同一个数据库时,这一点至关重要。
调度规则:成功时设置 next_due_at = now + cadence;失败时设置 next_due_at = now + cadence × min(2^streak, 16),并最多重试 3 次。
快速上手
python -m agentfleet.cli add-source --db fleet.db acme-careers https://example.com/careers --cadence 3600
python -m agentfleet.cli sweep --db fleet.db
python -m agentfleet.cli status --db fleet.db
python -m agentfleet.cli stats --db fleet.db
sweep 将到期的信息源入队、租出批次、通过 HTTP 抓取每条路由并进行对账。stats 打印每个信息源的变更率、错误率、中位数与 p95 延迟,以及整个编队的汇总数据。python examples/demo.py 可在本地文件上运行完整流程,无需网络。测试:python tests/test_engine.py。
自带你的 worker
内置执行器是一个函数 route -> (status, content_bytes)。对于外部编队(LLM agent、容器、其他机器),调用 lease() 获取清单,把每个批次交给一个 worker,并让 worker 把 {action_id}.json 结果文件写入其 write_scope:
{"action_id": 7, "source_id": 3, "status": "ok", "sha256": "…", "bytes": 4096,
"started_at": "2026-08-31T19:50:21Z", "finished_at": "2026-08-31T19:50:22Z", "elapsed_ms": 812.4}
然后调用 reconcile(conn, batch_id)。引擎把缺失的结果文件视为失败,因此失效的 worker 会自行了结。LLM agent 之所以能成为优秀的 worker,正是因为这份契约如此之窄:读取清单,以你认为最好的方式执行检查,写入结果文件,其他什么都不要碰。SKILL.md 教会一个编码 agent 操作整个流程。
在 Grafana 中查看
这些表在结构上天然就是 span 形态的,因此遥测数据只需一次导出:
python -m agentfleet.cli export-otel --db fleet.db --endpoint http://localhost:4318
它将 run 映射为 trace、batch 映射为父 span、action 映射为子 span(附带信息源名称、哈希、字节数、尝试次数和 changed 标志等属性),并将 OTLP/HTTP JSON 发送到任何采集器,包括 Grafana Cloud OTLP 网关。省略 --endpoint 即可在标准输出上查看 JSON。
Apache-2.0 许可证。由 Dreamers Inc 构建。