今日开源[第43期]last30days-skill

last30days (last30days-skill) 项目解读

仓库:https://github.com/mvanhorn/last30days-skill
当前版本:v3.18.4(2026-07-29)
许可证:MIT(No tracking. No analytics.)
解读时间:2026-07-30


目录

  1. 项目名称、作者与背景
  2. 部署过程与运行条件
  3. 代码框架、技术栈与核心代码
  4. 优势、不足与创新点
  5. 总结

1. 项目名称、作者与背景

1.1 名称

last30days(仓库名 mvanhorn/last30days-skill,斜杠命令 /last30days)。Slogan:

"An AI agent-led search engine scored by upvotes, likes, and real money - not editors."
(由人群投票、点赞、真金白银打分的 AI 代理搜索引擎,而非由编辑打分。)

项目徽章自述为 GitHub Trending #1 Repository Of The Day,并被 Trendshift 收录。

1.2 作者

  • Matt Van Horn(GitHub ID:mvanhorn)—— 项目创建者与维护者。
  • v3 引擎架构由社区贡献者 @j-sperling 主导设计(预研解析、Best Takes 评分、跨源聚类合并等)。
  • 社区驱动极强:截至 v3.11.1 已有 175 个合并 PR,其中 122 个来自 52 位社区贡献者;安全加固、多语言、Windows 兼容等大量工作由社区完成。

1.3 作用

/last30days 是一个 AI Agent 技能(Agent Skill):跨 Reddit、X、YouTube、TikTok、Instagram、Hacker News、Polymarket、GitHub、Digg、arXiv、Techmeme、LinkedIn、StockTwits、Threads、Pinterest、Bluesky、Perplexity、Web、小红书、Truth Social 等 20+ 信源并行检索任意主题(人物、公司、产品、技术、"X vs Y"),按人群互动度(点赞、upvote、真金白银押注的赔率)而非 SEO 排名打分,再由 AI Agent 综合成一页带来源引用、可调用的简报。

典型用法:/last30days Peter Steinberger/last30days what's exploding in AI agents?/last30days OpenClaw vs Hermes vs Paperclip/last30days Listen Labs --hiring-signals

1.4 背景与动机

  • 孤岛痛点:每个平台都是"带墙的花园"(独立 API、token、鉴权),没有任何单一 AI 能同时访问全部。Google 不碰 Reddit 评论与 X 帖子;ChatGPT 有 Reddit 合作但搜不了 X/TikTok;Gemini 有 YouTube 没 Reddit;Claude 原生都没有。
  • 核心洞察Google 聚合的是编辑;last30days 搜索的是人。 一条 1500 upvote 的 Reddit 讨论比无人阅读的博客强;一条 3.6M 播放的 TikTok 比新闻稿更能说明文化相关性;Polymarket 上 $66K 成交量的赔率比专家猜测更难反驳。
  • 作者初衷:为了跟上 AI 领域的日更速度——社区的 Reddit/X 极客总是最先知道,而训练数据总是落后几个月。后来扩展为销售前摸透一家公司、会议前读某人近况、旅行前看园区动态等通用研究工具。
  • 解锁点:用户"自带 key + 浏览器会话"后,Agent 就能一次性桥接所有平台、互相打分、告诉你什么才重要——"不是更好的一个搜索引擎,而是被 Agent 桥接起来的十几个互不相连的平台"。

2. 部署过程与运行条件

2.1 这是什么形态

这是一个 Python 引擎 + 宿主 Agent 技能 的组合。真正的"智能"分两层:

  1. Python 引擎scripts/last30days.py 及其 lib/ 下的 90+ 模块):负责信源检索、打分、聚类、渲染。
  2. 宿主 Agent(Claude Code / Codex / Cursor / 等):负责"规划(planner)"与"裁判(judge)"——由 LLM 决定检索谁、如何综合,因此 SKILL.md 是一份 1400+ 行的强契约来约束模型行为。

2.2 部署(安装)方式

宿主 安装命令 更新
Claude Code(推荐) /plugin marketplace add mvanhorn/last30days-skill/plugin install last30days 市场自动更新
Grok / xAI grok plugin marketplace add ...grok plugin install last30days grok plugin update last30days
Codex / Cursor / Copilot / Gemini CLI 等 50+ Agent Skills 宿主 npx skills add mvanhorn/last30days-skill -g-g 全局) npx skills update last30days -g
claude.ai 网页 下载 last30days.skill → Customize > Skills > Upload 重新下载上传
Claude Desktop 下载对应平台 .mcpb 拖入 Settings > Extensions(以 MCP server 运行) 重新拖入
OpenClaw clawhub install last30days-official clawhub update last30days-official
手动(开发者) git cloneln -s .../skills/last30days ~/.claude/skills/last30days

即"部署"= 把技能装进宿主的 skills 目录(或装成插件/MCP),数据默认存 ~/Documents/Last30Days/(Windows:C:\Users\<you>\Documents\Last30Days\)。

2.3 运行条件

类别 条件
Python 3.12+(零运行时依赖pyproject.tomldependencies = []);无 3.12 时若 uv 在 PATH 会自动装一个托管版 CPython 3.12(一次性 ~28MB)
宿主 支持 Agent Skills 的 AI 编码工具(Claude Code、Codex、Cursor、Copilot、Gemini CLI、Grok、OpenClaw、Windsurf、Cline 等 50+)
零配置可用源 Reddit(含评论)、Hacker News、Polymarket、GitHub、Web、StockTwits —— 无需任何 key,首次运行向导 30 秒解锁更多
免 key 但需装 CLI arXiv、Techmeme(自动装的免费 CLI)、Digg(digg-pp-cli,需置于 PATH)
可选 key X(XAI_API_KEY 或浏览器 cookie)、YouTube(yt-dlp)、TikTok/Instagram/Threads/Pinterest/LinkedIn/YouTube 评论(ScrapeCreators,1 万免费调用)、Perplexity/Brave(Web 搜索后端)等
首次向导依赖 会从浏览器读取 x.com cookie(仅内存、不落盘)以解锁 X;会装 yt-dlp、Digg/arXiv/Techmeme CLI
凭据存储 ~/.config/last30days/.env、进程环境变量、macOS Keychain(last30days-<KEY>)、Linux pass(1)、宿主自带 auth 均可
Claude Desktop 特别说明 要求本地有 Python 3.12+;Windows 支持暂缓,等各平台 manifest 入口就绪

2.4 关键命令示例

# 直接引擎调用(脚本 / 开发 / cron 用)
python3 skills/last30days/scripts/last30days.py "AI coding agents" --emit=json

# 主题无关的趋势发现(one-shot)
python3 skills/last30days/scripts/last30days.py --discover "AI agents"

# 趋势监控:持久化到 SQLite + 观察列表
python3 skills/last30days/scripts/last30days.py "OpenClaw" --store
python3 skills/last30days/scripts/watchlist.py           # 定时跑,可选 Slack/webhook 推送
python3 skills/last30days/scripts/briefing.py            # 日/周摘要

# 健康诊断
python3 skills/last30days/scripts/last30days.py doctor

3. 代码框架、技术栈与核心代码

3.1 技术栈

维度 内容
语言/运行时 Python 3.12+dependencies = []零运行时第三方依赖,几乎纯标准库)
打包 .skill(Agent Skills 包)、.mcpb(Claude Desktop MCP 包)、.claude-plugin / .codex-plugin / .grok-plugin / .agents/plugins(各宿主插件清单)
外部 CLI(可选) yt-dlp(YouTube 转写)、digg-pp-cli / arxiv-pp-cli / techmeme-pp-cli(免费)、gh(GitHub)
外部 API(可选) ScrapeCreators(TikTok/Instagram 等)、Perplexity/OpenRouter(Sonar)、Brave/Exa(Web)、xAI(X)
Node.js lib/vendor/bird-search 内嵌的 vendored Bird client,用于 X 搜索(无 Node 则走 cookie/API 路径)
测试 2,700+ 测试,pytest,覆盖率门槛 84%fail_under = 84
发布工程 towncrier + 锁步发布(GitHub Actions),changelog 碎片目录 changelog.d/
安全 OpenSSF Scorecard、构建来源证明(provenance attestation)、Semgrep、OSV-Scanner、PR 依赖审查门;Hermes 扫描无 CRITICAL

设计哲学:引擎本身零依赖、可离线核心运行;所有"高级能力"都是可插拔的可选后端(BYO keys / 浏览器 cookie / 免费 CLI)。

3.2 代码模块(仓库结构)

last30days-skill/
├── skills/last30days/
│   ├── SKILL.md              ← 运行时"契约"(真相源,1400+ 行,11 条 LAW)
│   ├── scripts/
│   │   ├── last30days.py     ← 引擎主入口(CLI)
│   │   ├── setup-*.sh / setup-keychain.sh   ← 首次向导 + Keychain 配置
│   │   ├── store.py / watchlist.py / briefing.py  ← SQLite 趋势存储 / 观察列表 / 摘要
│   │   ├── evaluate_search_quality.py / verify_v3.py / test-*.sh  ← 质量评估与回归
│   │   ├── build-skill.sh    ← 从源码打包 .skill
│   │   └── lib/              ← 90+ 引擎模块(见下)
│   └── (references, templates)
├── mcp/                      ← MCP 服务器源码(Go)
├── docs/                     ← 文档(JSON 导出参考、eval 指引等)
├── hooks/                    ← 会话钩子(如 check-config.sh 自动建目录)
├── tests/                    ← 2700+ 测试套件
├── .claude-plugin/ .codex-plugin/ .grok-plugin/ .agents/plugins/  ← 各宿主插件清单
├── pyproject.toml / uv.lock
├── AGENTS.md / CL AUDE.md / CONCEPTS.md / CONFIGURATION.md / CONTRIBUTING.md
└── README.md

lib/ 模块地图(按职责分组):

分组 模块(举例)
编排/核心 pipeline.py(流水线)、planner.py(规划)、fanout.py(并行扇出)、query.pyresolve.py(实体解析)、fusion.py(融合)、rerank.py(重排)
评分/聚类 relevance.pyfreshness.pycluster.pydedupe.pynormalize.pyquality_nudge.pycategories.pysnippet.py
信源适配器 reddit*.py(_public/_rss/_shreddit/_arctic/_keyless/_enrich/_listing)、bird_x.pyxai_x.pyxquik.pyyoutube_yt.pytiktok.pyinstagram.pyhackernews.pypolymarket.pygithub.pyarxiv.pydigg.pytechmeme.pylinkedin.pystocktwits.pythreads.pypinterest.pybluesky.pytruthsocial.pyxiaohongshu_api.pytrustpilot.pydripstack.pyjobs.py
信号/分析 signals.pyhiring_signals.pycompetitors.pyprescriptions.pyentity_extract.pytopic_shape.py
配置/环境 env.pyskill_meta.pysetup_wizard.pyregisters.pyproviders.pybackends.py
渲染/发布 render.pyhtml_render.pyhtml_publish.pyfeed.pylibrary.pylibrary_index.py
抓取/网络 http.pyweb_fetch_keyless.pyweb_search_keyless.pyperplexity.pyhosted.pygrounding.pytranscribe.py
Cookie 提取 cookie_extract.pychrome_cookies.pysafari_cookies.py
诊断/健康 doctor.pyhealth.pypreflight.pypermission_preflight.py
其他 dates.pycjk.py(CJK 分词)、discovery_handoff.pyui.pysubproc.pylog.pyschema.py
内嵌依赖 vendor/bird-search/(vendored Node Bird client for X)

3.3 核心架构:引擎 + 宿主 LLM 协作

不同于传统"程序自己思考"的工具,last30days 把思考权交给宿主 LLM,引擎只做检索与打分。SKILL.md 反复强调两条铁律:

  • LAW 7 — YOU ARE THE PLANNER:命名实体主题必须用 --plan 显式传计划给引擎,因为"你(宿主模型)就是 LLM provider,不需要外部规划服务"。
  • LAW 11 — YOU ARE THE JUDGE:趋势发现用三命令协议——--discover --nominate-only(引擎扫榜提名)→ 宿主裁判(命名/判垃圾/打分值/写角度)→ --discover --judgments 深研 → --discover --finalize 渲染。
用户话题
   │
   ├─[宿主 LLM] 解析意图 + 实体解析 (resolve.py: X 账号/GitHub 仓库/子版块/频道)
   │
   ├─[引擎 fanout.py] 并行扇出到所有已配置信源 (reddit/x/youtube/...)
   │      每个适配器: 检索 → 排序(engagement/relevance/freshness) → 取 top
   │
   ├─[引擎 fusion/cluster/dedupe] 跨源聚类合并 (无线+reddit+X = 一个 cluster)
   │
   ├─[宿主 LLM = Judge] 把"证据块"综合成 What I learned 叙述 + KEY PATTERNS
   │      + 编织社区原声 (Best Takes) + 引用可读化 (LAW 8/9)
   │
   └─[引擎 render] 透传 emoji-tree 页脚 (✅ All agents reported back!)
       │
       ▼
   单页简报 (markdown / html / json) + 存入 LAST30DAYS_MEMORY_DIR

3.4 核心代码一:引擎调用契约(SKILL.md frontmatter 节选)

---
name: last30days
version: "3.18.4"
description: "Research what people actually say about any topic in the last 30 days.
  Pulls posts and engagement from Reddit, X, YouTube, TikTok, Hacker News,
  Polymarket, GitHub, and the web. Includes a doctor health check."
argument-hint: 'last30days nvidia earnings reaction | last30days AI video tools'
allowed-tools: Bash, Read, Write, AskUserQuestion, WebSearch
user-invocable: true
metadata:
  openclaw:
    requires:
      optionalEnv: [SCRAPECREATORS_API_KEY, XAI_API_KEY, PERPLEXITY_API_KEY,
                    BRAVE_API_KEY, BSKY_APP_PASSWORD, XIAOHONGSHU_API_BASE, ...]
    bins: [node, python3]
    primaryEnv: SCRAPECREATORS_API_KEY
---

3.5 核心代码二:Python 版本门(Runtime Preflight,真实可运行片段)

这是 SKILL.md 内嵌的"运行时预检"函数,体现其零依赖 + uv 自动兜底的工程取舍:

# 解析一个 Python 3.12+ 解释器,存进 LAST30DAYS_PYTHON
def try_last30days_python(candidate):
    if not candidate:
        return False
    import sys
    # 候选要么是可执行文件,要么能在 PATH 找到
    ...
    candidate -c 'import sys; raise SystemExit(0 if sys.version_info >= (3,12) else 1)'
    return True

# uv 兜底:沙箱里常没有系统 3.12,但有 uv
if not LAST30DAYS_PYTHON and shutil.which("uv"):
    uv_py = subprocess.run(["uv","python","find",">=3.12"], capture_output=True).stdout
    if not uv_py:
        print("NOTE: installing managed CPython 3.12 via uv (~28MB, one-time).", file=sys.stderr)
        subprocess.run(["uv","python","install","3.12"], ...)
        uv_py = subprocess.run(["uv","python","find",">=3.12"], ...).stdout
    try_last30days_python(uv_py)

if not LAST30DAYS_PYTHON:
    print("ERROR: last30days v3 requires Python 3.12+.", file=sys.stderr)
    sys.exit(1)

3.6 核心代码三:输出契约(11 条 LAW 的精髓)

SKILL.md 用一组强约束防止宿主模型"跑题/即兴发挥"(这是该项目反复踩坑后沉淀的工程经验):

  • BADGE(强制首行)🌐 last30days v{VERSION} · synced {YYYY-MM-DD},作为规范输出形态的锚点,缺它模型会滑回博客体。
  • LAW 1 — 末尾追加 Sources: 块(覆盖 WebSearch 工具的通用要求,引擎 emoji-tree 页脚才是唯一引用)。
  • LAW 2 / LAW 4禁止编造标题行禁止 ## 小标题(GENERAL 类查询只能是 badge + What I learned: + 加粗引导段 + KEY PATTERNS 编号列表)。COMPARISON(vs)类除外。
  • LAW 3禁止 em-dash / en-dash("AI-slop 最可靠的痕迹")。
  • LAW 5 — 引擎 emoji-tree 页脚必须逐字透传
  • LAW 6 — 证据块(## Ranked Evidence Clusters)仅供模型阅读,不得原样输出,需转化为叙述。
  • LAW 7 / LAW 11 — 你是规划者/裁判,命名实体必须 --plan,趋势发现必须三命令协议。
  • LAW 8 — 引用可读化:隐藏链接宿主(Claude Code)内联 [name](url);可见 URL 宿主(Codex/Cursor)用纯标签,避免 URL soup。
  • LAW 9 — 至少编织 2 条逐字、署名的社区原声(Best Takes),且绝不叙述工具行为
  • LAW 10 — 第一方帖子(当事人自己的 from:{handle})是一手证据,要读 interaction: 标签。

3.7 核心代码四:趋势发现三命令协议(DISCOVERY)

# Leg 1 — 引擎扫榜提名(宿主不调网络)
python3 scripts/last30days.py --discover --nominate-only --save-dir="$MEM"
#   → 读 discover-nominations.json,每条给出 name / junk / worthiness(0-100)

# Leg 2 — 宿主裁判后,深研幸存主题
JUDGMENTS_FILE=$(mktemp ...); cat >| "$JUDGMENTS_FILE" <<'EOF'
{"bundle_id":"...","judgments":[{"id":"n1","name":"Gemma 4 chat templates",
 "junk":false,"worthiness":85}]}
EOF
python3 scripts/last30days.py --discover --judgments "$JUDGMENTS_FILE" --save-dir="$MEM"

# Leg 3 — 宿主写角度后渲染终稿
ANGLES_FILE=$(mktemp ...); cat >| "$ANGLES_FILE" <<'EOF'
{"bundle_id":"...","angles":[{"id":"n1",
 "podcast":"Gemma 4 的模板改动悄悄让一年社区微调失效了?",
 "x_article":"Gemma 4 模板变更悄悄作废了一年的社区微调。"}]}
EOF
python3 scripts/last30days.py --discover --finalize --angles "$ANGLES_FILE" \
  --emit=compact --save-dir="$MEM"

4. 优势、不足与创新点

4.1 优势

  1. "搜人而非搜编辑"的独特价值:按 upvote/点赞/真金白银赔率排序,而非 SEO/编辑权重,能挖到 Google/ChatGPT/Gemini 各自墙内看不到的社区真相。
  2. 桥接孤岛:通过 BYO keys + 浏览器 cookie,一次性并行检索 20+ 互不相连的平台并互相打分——这是单点搜索引擎做不到的。
  3. 零配置即开即用:Reddit/HN/Polymarket/GitHub/Web/StockTwits 免 key;arXiv/Techmeme/Digg 免费 CLI 自动装;首次向导 30 秒解锁更多。
  4. 零运行时依赖 + 自动兜底dependencies = [],纯标准库;无 3.12 时 uv 自动装托管版——极大降低部署摩擦。
  5. 多宿主覆盖:Claude Code / Codex / Cursor / Copilot / Gemini / Grok / OpenClaw 等 50+ 宿主,且提供 .skill/.mcpb/各插件清单多种打包形态。
  6. 质量门控严苛:2,700+ 测试、覆盖率门槛 84%、供应链安全(Scorecard/证明/Semgrep/OSV)、Hermes 零 CRITICAL——工程成熟度远超多数个人项目。
  7. 结构化可机读输出--emit=json 提供版本化 agent profile,便于接入工作流/定时任务;--store + watchlist.py + briefing.py 形成趋势监控闭环。
  8. 社区驱动且安全加固:52 位贡献者、175 PR;XSS 修复、cookie 临时文件锁定、跨源混淆等大量工作来自社区。
  9. 丰富的使用模式:发现(discovery)、对比(single-pass comparison)、雇佣信号、观察列表、可订阅研究库(Atom feed)、本地全文检索——覆盖面极广。

4.2 不足与风险

  1. 契约自身脆弱:1400+ 行 SKILL.md + 11 条 LAW 本质上是"用超长提示词约束 LLM 行为"。SKILL.md 自己记载了多个 named failure mode(如 v3.0.6 公开版 0/8 回归:模型把 /last30days 当普通关键词即兴发挥),说明该方案对宿主模型遵循长契约的能力高度敏感,长上下文易"读不到后面的 LAW"。
  2. 完整能力依赖付费/外部服务:TikTok/Instagram/Threads/Pinterest/LinkedIn/YouTube 评论与备份路径依赖 ScrapeCreators(免费 1 万调用后用完或需 PAYG);Perplexity/Brave 为付费/限免费量——"免费"体验与"全功能"体验差距明显。
  3. 隐私与信任成本:为解锁 X 需读取浏览器 cookie(虽声明仅内存不落盘),且需同意 ScrapeCreators 等第三方数据流转,对隐私敏感用户是门槛。
  4. 质量上限受宿主模型限制:规划者与裁判都是同一个宿主 LLM,存在"裁判即选手"的潜在偏差;SKILL.md 用强契约去堵,但无法根除。
  5. 维护面巨大:90+ 模块、20+ 信源适配器,每个都有独立 auth/API/反爬 quirks(如 README 记载的 YouTube 对比模式 fan-out 超时修复 #901),长期维护成本高。
  6. 平台支持不均:Claude Desktop 的 Windows 支持暂缓;部分源(小红书/Truth Social/DripStack)需本地服务或明确 opt-in,并非开箱即用。
  7. "真金白银"评分有前提:Polymarket 等预测市场仅对存在对应赌注的主题有效,并非所有话题都有赔率可作信号。
  8. Token/耗时成本:多源并行扇出 + 宿主 LLM 多次裁判(尤其 discovery 三命令 + 深研),在长主题/趋势发现下可能较慢、较贵。

4.3 创新点 / 亮点

  1. "社交相关性 > SEO 相关性"的排序范式:把人群投票与真金白银(Prediction-market odds)作为信号源,重新定义"什么重要",是对传统搜索排名的直接挑衅。
  2. SKILL.md-as-Contract 的"提示词工程契约化":把行为约束写成 11 条 LAW + 强制 badge + 逐字透传页脚,并用 STEP 0 防陈旧克隆、用"命名失败模式"反向收敛模型行为——这是 Agent Skill 工程化的高水平样本。
  3. "宿主即规划者/裁判"的架构:引擎只做检索-打分-渲染,把思考权完全交给宿主 LLM(YOU ARE THE PROVIDER),避免内置规划器的能力瓶颈,也契合 Agent Skills 的运行模型。
  4. 三命令发现协议(host-judged discovery):把"趋势发现"拆成引擎提名 → 宿主裁判 → 深研 → 写角度 → 渲染,明确分工、可中断、可审计,是对"开放式研究"问题的优雅解法。
  5. 零依赖 + uv 自动兜底dependencies = [] 却能在缺 Python 3.12 时自建运行时,兼顾可移植性与零安装摩擦。
  6. 多形态打包:同一份引擎同时产出 .skill.mcpb.claude-plugin.codex-plugin.grok-plugin.agents/plugins,真正"一处开发、五十处宿主运行"。
  7. 质量与安全左移:84% 覆盖率门槛、towncrier 锁步发布、OpenSSF Scorecard + provenance attestation + Semgrep + OSV + PR 依赖审查门,把开源供应链安全做成硬性关卡。
  8. 从研究到监控的闭环--store(SQLite) + watchlist.py + briefing.py + 可订阅 Atom feed,把"一次性研究"升级为"持续情报订阅"。

5. 总结

last30days(/last30days) 是由 Matt Van Horn 维护、MIT 协议的 AI Agent 研究技能,本质是一套 "零依赖 Python 引擎 + 宿主 LLM 充当规划者/裁判" 的多源社会信号搜索引擎。它跨 20+ 平台并行检索,按人群互动度与真实押注(而非 SEO)打分,综合成带来源引用的简报,并支持趋势发现、对比、雇佣信号、观察列表与研究库订阅。

其亮点在于独特的相关性范式、把 LLM 行为约束"契约化"的工程实践、零依赖可自举的部署,以及覆盖 50+ 宿主的多形态打包与严苛的质量/安全门控;主要短板集中在 1400 行契约对模型遵循度的脆弱依赖全功能对付费/外部服务的依赖、以及 90+ 模块的庞大维护面。对想做"Agent 原生研究工具 / 多源情报聚合 / Skill 工程化"的开发者,是一份兼具范式启发与工程参考价值的项目。


本文档基于项目 README、SKILL.md、scripts/ 与 lib/ 模块清单、pyproject.toml 等公开文件解读整理。

posted @ 2026-07-30 19:56  zhang-yd  阅读(42)  评论(0)    收藏  举报