Files
agent-radar/README.md
T

182 lines
8.4 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# agent-radar · 全球智能体开源应用追踪
持续追踪全球 AI Agent 开源应用,输出**深度分析文章**(发布在 [blog.apescale.com](https://blog.apescale.com) 可巴蒂栏目),
并**镜像源码**到 `gitinbox` 组织做代码级跟踪。
设计原则:**每新增一个项目,边际成本递减,横向对比能力自动增强。**
所有项目共用同一套五维 schema,因此对比矩阵、赛道图、总纲索引都能由脚本自动生成,
人只需要做「研判与写作」这部分不可替代的工作。
---
## 收录标准
满足任一即可收录,但会标注不同 `status`:
| status | 含义 | 判定 |
| --- | --- | --- |
| `active` | 持续追踪 | 有实际影响力,或技术路线有代表性,值得长期跟进 |
| `watch` | 观察中 | 早期项目,方向有意思但尚未验证 |
| `archived` | 归档 | 停更 / 被收购 / 路线变更 |
**不收录**:纯模型权重、纯数据集、无公开代码的论文复现、营销型空壳仓库。
---
## 目录结构
```
agent-radar/
├── README.md # 本文件
├── schema/
│ ├── project.schema.yaml # 五维档案字段定义 + 枚举(也是脚本的骨架生成源)
│ └── license-tiers.yaml # 许可证成色分级 → 镜像可见性规则
├── data/
│ ├── registry.yaml # 收录总表,驱动批量抓取
│ ├── projects/<id>.yaml # 每项目一份五维档案
│ └── snapshots/<id>.jsonl # 指标时间序列(追加式,一行一天)
├── articles/
│ ├── 00-overview.md # 总纲文源文(含矩阵占位符,由脚本回填)
│ └── <id>.md # 项目深度文源文
├── templates/project-article.md # 文章固定章节模板
├── scripts/ # 抓取 / 生成 / 镜像 / 发布脚本
└── site/ # 【规划中】由同一份档案生成的静态总览页,尚未实现
```
---
## 五维档案
每个项目一份 `data/projects/<id>.yaml`,字段定义见 `schema/project.schema.yaml`:
| 维度 | 回答的问题 |
| --- | --- |
| `identity` | 它是谁、谁在做 |
| `business` | 它靠什么活着、为谁活着 |
| `scenario` | 它在什么场合被用、产出什么 |
| `tech` | 它怎么做到的、抽象在哪一层 |
| `ecosystem` | 它的社区动能(多数由脚本自动刷新) |
| `risk` | 它的坑在哪、宣称与实测的落差 |
> `risk.claim_vs_reality` 是最不该留空的字段。它逼着每篇分析去核实
> 「项目方宣称 vs 实际状态」,防止文章退化成 README 复读。
---
## 许可证分级 → 镜像可见性
**新增项目时的第一判断项。** 规则见 `schema/license-tiers.yaml`:
| 级 | 判定 | 成色 | 镜像可见性 |
| --- | --- | --- | --- |
| L1 | MIT / Apache-2.0 / BSD / ISC / GPL / MPL | 完全开源 | `public` |
| L2 | AGPL / SSPL / BUSL / Elastic-2.0 | 有限开源 | `public`(档案标注限制) |
| L3 | NOASSERTION + 自定义 source-available | 源码可得、非开源 | **`private`** |
| L4 | 无 LICENSE / proprietary | 不可得 | 不镜像,仅存链接 |
定错级的代价:L3 项目被公开镜像,等于替对方做了一次未经授权的公开分发。
---
## 新增一个项目的 SOP
```bash
# 1. 建档(自动抓许可证并定级 L1-L4)
python3 scripts/new_project.py --repo owner/name
# 2. 手工填档案五维度 —— 重点填 risk.claim_vs_reality
$EDITOR data/projects/<id>.yaml
# ⚠️ 补完时**不要整块覆盖**下面这三个块,它们由脚本回写:
# ecosystem.metrics(fetch_stats 写)
# mirror (mirror_sync 写)
# article (publish_emlog 写)
# 整块替换 ecosystem 会把 metrics 一起删掉,表现为矩阵里指标静默变空。
# 真踩了也别慌:fetch_stats 用 upsert_block 会自动把 metrics 长回来
# (python3 scripts/fetch_stats.py --id <id> --force)。
# 3. 刷新指标(放在填档之后,别反过来)
python3 scripts/fetch_stats.py --id <id>
# 4. 镜像源码(按许可证等级自动决定 private / public)
bash scripts/mirror_sync.sh --id <id>
# 5. 成文(套 templates/project-article.md)
$EDITOR articles/<id>.md
# 6. 发布到 emlog(可巴蒂 sid=17),emlog_id 会自动回写档案
python3 scripts/publish_emlog.py --article <id>
# 7. 回填总纲并更新总纲文
python3 scripts/build_matrix.py
python3 scripts/publish_emlog.py --article 00-overview
# 8. 入库
git add -A && git commit -m "track: <name>" && git push
```
### ⚠️ 更新总纲文时必读
emlog 的 update 接口**不传 `--content` 就会清空正文**。
保护点应该是「**本地正文非空**」,而不是「update 前先 detail 取回线上全文」——
本脚本的 content 永远来自本地 Markdown 源文件,不存在"忘了传"的情况;
反过来,emlog 的 detail 接口**查不到草稿**,如果把保护建立在 detail 上,
草稿就永远无法转正。所以 `publish_emlog.py` 的判据是:本地正文非空即放行,
detail 只作为可选的健全性检查。
如果你手工调 emlog 脚本更新总纲,记住同一件事:**确保传了 `--content`**。
### 两类文章,ID 落点不同
`publish_emlog.py` 按「有没有同名项目档案」自动分流,**不需要手工指定**:
| 文章类型 | 文件名 | ID 落点 |
| --- | --- | --- |
| 项目深度文 | `articles/<id>.md`(有 `data/projects/<id>.yaml`) | 档案的 `article` 块 |
| 跨项目文章 | `articles/00-*.md`(总纲、横评、专题) | `articles/<id>.meta.yaml` |
新增一篇 `00-` 开头的文章不用做任何额外配置,发完就有 meta。
反过来,如果某天需要给跨项目文章单独建档,只要 YAML 一出现,脚本会改走档案路径——
先按「是不是项目文」分流,再决定写哪儿。
### 文章索引不需要手工维护
总纲里 `<!-- INDEX:BEGIN/END -->` 之间的内容由 `build_matrix.py` 生成,
事实源是两处:项目档案的 `article` 块 + `articles/*.meta.yaml`。
这段原本是手抄的,结果横评文发了、索引里却没有它——**手写的索引每发一篇文章就漂移一次**。
现在只需要在发完文章后重跑 `build_matrix.py`,没深度文的项目会自动标注「待发布」并指向现有横评。
---
## 脚本一览
| 脚本 | 作用 | 降级行为 |
| --- | --- | --- |
| `new_project.py` | 建档 + 自动判许可证等级 | API 失败时生成未定级骨架,要求人工填 |
| `fetch_stats.py` | 抓指标 + 累积时间序列快照 | 无 `GITHUB_TOKEN` 则匿名降级;当日缓存;失败沿用上次快照并标 `stale` |
| `build_matrix.py` | 生成对比矩阵 + 赛道图 / 象限图 + 文章索引 | 项目 <4 个出分层图,≥4 个才出象限图;索引缺标记则跳过并警告 |
| `mirror_sync.sh` | 源码镜像同步 | 大仓(>300MB)提示并支持 treeless clone 降级 |
| `publish_emlog.py` | emlog 发布 / 更新 | 本地正文为空时拒绝 update(防清空线上) |
---
## 已知约束
- **GitHub API 限额**:无 `GITHUB_TOKEN` 时匿名限额 60 次/小时。
项目数超过约 20 个后批量刷新会受限,建议配置 token。
- **GitHub 下载带宽**:本机到 GitHub 实测约 **50 KB/s**(走沙箱代理 56 KB/s,
直连 27 KB/s 且 github.com 常被阻断)。591 MB 的仓全量镜像需要 3 小时以上。
大仓一律先 `--depth 1`,后续再用脚本的增量加深补齐。
- **Gitea 推送上限**:前置 nginx 的 `client_max_body_size` 约 **50 MB**
(实测 48 MB 放行、64 MB 拒绝)。超限会在传完所有对象后才收到 HTTP 413。
脚本内置体积闸门,超限自动降级为「源码快照」(剔除非源码素材,通常能减一半以上)。
彻底解法是在服务器 nginx 配置里放开该值。
- **浅仓不能直接推送**:Git 服务端默认 `receive.shallowUpdate = deny`,
推浅仓会被拒。脚本在推送前自动 `--unshallow` 补齐历史;
若补齐失败则降级为快照(丢历史但保住代码)。
- **磁盘占用**:源码镜像是全量裸仓。4 个项目已占约 800 MB。
大仓可用 `--filter=blob:none` 做 treeless 镜像。
- **象限图阈值**:样本 <4 个时象限图没有统计意义,此阶段只出赛道分层图。
4 个也只是示意,不构成统计结论。