news 2026/9/8 23:29:22

last30days v3.0.9「Self-Debug Release」技术解读:引擎拒绝门、跨平台顶级热评与多 Harness 部署

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
last30days v3.0.9「Self-Debug Release」技术解读:引擎拒绝门、跨平台顶级热评与多 Harness 部署

last30days v3.0.9「Self-Debug Release」技术解读:引擎拒绝门、跨平台顶级热评与多 Harness 部署

【免费下载链接】last30days-skillAI agent skill that researches any topic across Reddit, X, YouTube, HN, Polymarket, and the web - then synthesizes a grounded summary项目地址: https://gitcode.com/GitHub_Trending/la/last30days-skill

导读

本文围绕仓库中的历史发布说明 docs/releases/v3.0.9.md 展开,解读 last30days 这款「跨 Reddit、X、YouTube、HN、Polymarket 与 Web 的 30 天话题研究 Agent Skill」在 v3.0.9 这一次被命名为The Self-Debug Release的版本中做了什么。你将看到三个可复用的关键能力:①引擎如何在「40 岁生日礼物」这类人口统计式购物查询上主动拒绝并反问问清上下文(对应今天的 skills/last30days/scripts/lib/preflight.py 源码);②TikTok/YouTube 顶级热评如何获得与 Reddit 同等的渲染地位;③一种「让模型自己调试自己的输出违约」的工程方法,以及该版本把部署面扩张到 Hermes、Windows、claude.ai、Codex CLI 等多个宿主平台的全部细节。

说明:docs/releases/v3.0.9.md是一份历史版本发布说明。仓库主线此后持续迭代(聚合 CHANGELOG.md 目前顶部版本已远高于 v3.0.9),但本文所有实现证据均来自当前仓库中仍然存在、可核验的文件与代码。


版本概览:一次由「五个 Opus 自己给自己找病根」驱动的发布

发布说明在 Highlights 里给出了两个核心结论:

  1. 头号修复:引擎对birthday gift for 40 year old这类查询不再埋头跑 5 分钟垃圾检索,而是先抛出一个澄清问题;
  2. 头号功能:TikTok 与 YouTube 的顶级评论现在与 Reddit 一样,以第一等的醒目程度渲染进最终综述。

而「Self-Debug(自我调试)」这个标签,指的是v3.0.9 的修复方式是让 5 个彼此独立的 Opus 4.7 实例分别拿到自己先前失败(v3.0.7 / v3.0.8)的输出,然后自己调试自己。结果是:

  • 其中3 个收敛到同一诊断:SKILL.md体积太大、VOICE CONTRACT 里的 LAWs 放得太深,模型根本读不到(一个实例甚至明确说:试图 Read 时撞上 25K token 上限,就放弃了而不是分块读完);
  • 其中2 个收敛到同一条建议:引擎应当直接拒绝人口统计式购物查询,而不是指望模型自觉遵守;
  • 另有 2 个指出:WebSearch 工具自带的「Sources: 必须」提示在优先级上压过了 LAW 1,导致输出尾巴上反复泄漏无关来源列表。

作者把这些诊断原样变成代码("I copy-pasted their diagnoses into code"),最终在先前失败的话题上拿到5/5 规范合规。这条叙事与聚合版 CHANGELOG.md 中 v3.0.9 条目的记录一致:发布说明还额外给出了当时出现的0/8 公共回归(连续 8 次调用 Opus 把 Skill 当成通用关键词即兴发挥、违反 LAW 2/LAW 4)作为背景——Self-Debug 正是对这 0/8 的回应。


引擎侧 Class 1 拒绝门:把「不该跑」变成代码而不是措辞

为什么需要一道硬拒绝门

发布说明给出了核心推理:birthday gift for 40 year old这类人口统计式购物字面短语,并不是 Reddit、X、TikTok 上真实礼物讨论会使用的词汇。让引擎照常检索,返回的只会是低信号、泛泛而谈的内容——文档记录了一次真实失败:2026-04-18 的验证运行最终返回的是r/todayilearned与一批无关 drama 帖子。

与其继续在 SKILL.md 里用越来越重的措辞约束托管模型「别去跑这类查询」,v3.0.9 选择在引擎前端物理拦截:由两个 Opus 实例共同给出的「engine should refuse demographic-shopping queries outright」诊断被实现为一个新的前端模块。

实现:preflight.py 与 main() 前门的配合

当前仓库中该模块仍在,即 skills/last30days/scripts/lib/preflight.py。其模块 docstring 明确写着:检测 Class 1(人口统计式购物)关键词陷阱并返回结构化 REFUSE 消息,调用方在 skills/last30days/scripts/last30days.py 的 main() 入口把消息写到 stderr 并以退出码 2结束;一条注定失败的查询不会触发任何 pipeline 工作。模式注释说明这套规则来自 SKILL.md Step 0.45 的散文描述,且「只有 Class 1 被实现,因为只有它在 v3.0.8 有被验证过的失败模式」。

代码层面,拦截逻辑分两类模式(_CLASS_1_PATTERNS_QUALIFIER_PATTERNS):

类别匹配目标(正则语义,非完整字面)效果
Class 1 命中(拒绝候选)(birthday)? gift(s)/present(s) for N-year-oldbest/top … for men/women/kids/teens/dads/moms/husbands/wives/brothers/sisters/friendswhat to buy/get/gift for …gift(s)/present(s) for 丈夫/父亲/朋友/老板…等开头的查询触发check_class_1_trap()的拒绝逻辑
限定词(放行候选)$金额budgetwho loves/likes/is into/enjoyshobbies,或N-year-old + 兴趣名词(如year old runner,只要该名词不是关系称谓)视为用户已补齐上下文,跳过拒绝门放行

_RELATIONSHIP_WORDS(husband/wife/dad/mom/brother/sister/friend/boss/coworker/son/daughter/grandma…)的存在是为了区分两种情况:year old runner是兴趣、可放行;year old husband只是把人口统计式购物换了个说法,仍然拒绝。

调用点确认于 skills/last30days/scripts/last30days.py#L3356-L3361:

if not os.environ.get("LAST30DAYS_SKIP_PREFLIGHT"): from lib import preflight refuse_msg = preflight.check_class_1_trap(topic) if refuse_msg: sys.stderr.write(refuse_msg) return 2

即:只有显式设置LAST30DAYS_SKIP_PREFLIGHT=1时拒绝门才被绕过,其余情况命中即写 stderr 并return 2

REFUSE 消息内容与冒烟测试

命中后写给 stderr 的结构化消息(preflight.py 中_refuse_message()生成)包含三部分:

  1. 说明该查询命中 Class 1 模式、为何引擎跑它会产出低信号内容(引用 2026-04-18 返回r/todayilearned的实证);
  2. 提示托管模型向用户追问至少一项上下文:hobbies(cooks / runs / reads / gaming / outdoors / golf / music)、relationship(husband / dad / friend / boss / brother)、budget range
  3. 给出两条出路:用户补齐信息后以丰富化查询重跑;或用户坚持「直接跑」,则以LAST30DAYS_SKIP_PREFLIGHT=1显式绕过。

发布说明中的冒烟测试正是围绕它设计的:执行/last30days birthday gift for 40 year old应当先抛出澄清问题而不是启动引擎;如果引擎照常运行,说明本地插件缓存是旧的,需要重复一次/plugin update。这一行为在当前仓库的 tests/test_preflight.py 中有成体系的回归覆盖(围绕正向命中、带限定词放行、空 topic 等场景),保证「拒绝门」这个结构约束不会在后续迭代中被悄悄放松。


顶级热评成为一等公民:从 Reddit 推广到 TikTok 与 YouTube

发布说明把「TikTok 和 YouTube 的顶级评论现在和 Reddit 一样渲染」称为v3.0.0 以来最大的一次用户可见输出变化。溯源链路是:

  • 社区最初推动的是 Reddit 富评论(PR #143 的原始推动)——它种下了「💬 Top comment醒目处理」这个模式;
  • PR #260 把这个模式泛化到每个 TikTok 视频与 YouTube 视频上:各自取互动最高的那条评论,获得与 Reddit 顶级评论相同的视觉地位;
  • PR #265 紧随其后修复了 ScrapeCreators 的url=参数与 YouTube 评论/字幕的新响应结构,否则富集根本不会真正生效——这正是「功能 + 修管道」成对发布的典型样板。

从当前仓库的渲染层可以印证这套输出契约确实存在:skills/last30days/scripts/lib/render.py 在紧凑渲染的证据区对Reddit、YouTube、TikTok、HackerNews统一消费item.metadata["top_comments"],输出形如:

Top comment {attribution}{vote_part}: {截断到 200 字符的评论摘录}

(见 render.py#L1860-L1876)。也就是说,"最受讨论的声音必须进入综述"这条产品原则,在 v3.0.9 从单一 Reddit 来源扩展为所有支持评论富集的主流来源

配套输出契约:BADGE 前置与 END-OF-CANONICAL-OUTPUT

顶级评论是输出内容的一等公民,而输出本身的"规范化"则是同一枚硬币的另一面。Self-Debug 的三个 Opus 实例都指出「LAWs 放得太深、SKILL.md 太大」,于是 v3.0.9 做了结构性搬迁:OUTPUT CONTRACT(BADGE + LAWS)从第 1094 行附近移到文件顶部。这一改动在当前仓库的 skills/last30days/SKILL.md 中依然可见——文件在开篇(约 98-113 行)就放置了 SKILL CONTRACT 与 OUTPUT CONTRACT,并明确警告模型不要把/last30days当成可以即兴发挥的通用检索关键词。

同时引擎侧由渲染层保证每段输出以规范徽标开头:render_compact的第一行输出是🌐 last30days v{version} · synced {today}(见 render.py#L71-L75),并新增END-OF-CANONICAL-OUTPUT 边界——聚合 CHANGELOG 称之为"要求二次合成必须先主动无视一个可见边界才能继续",把"不得追加多余 Sources 尾巴"从一句建议变成引擎产物的物理边界。针对"WebSearch 工具自带的 MANDATORY Sources 提醒覆盖了 LAW 1"的诊断,LAW 1 现在直接引用那条提醒的原话并在 last30days 输出域内声明其已被 OVERRIDE。


部署面的一次大扩张:六个宿主平台与更多首装路径

v3.0.9 一个被低估的主题是表面面积扩张:Skill 从"Claude Code 专用"走向"Claude Code、Codex、Hermes、Gemini、claude.ai、OpenClaw 都能跑"。逐条拆解:

Hermes AI Agent 成为一等部署目标(PR #228)

scripts/sync.sh会检测~/.hermes/skills/research,并把完整 Skill(SKILL.md、scripts、lib 模块、fixtures)同步进 Hermes 的技能目录,与 Claude Code / Codex 并列。同步分支统一使用根目录 SKILL.md(修掉了此前.hermes-plugin/SKILL.md回退造成的"读到错文件"隐患)。

Windows 原生可用(PR #227 + #225)

  • PR #227 稳定了内置的 Bird X 搜索客户端在 Windows 终端上的运行时问题;
  • PR #225 修复了保存输出的 UTF-8 编码;
  • 两者叠加后,Windows 用户无需变通即可获得完整 v3 体验。

Linux 权限检查停止误报(PR #216)

check_perms此前固定调用 BSD 风格stat,导致 Linux 上已经正确 chmod 600 的.env仍收到虚假的权限告警。修复为优先使用 GNUstat语法,让检查与实际文件权限一致。

claude.ai 直接安装(PR #242 / #244)

新增scripts/build-skill.sh配合.gitattributesexport-ignore管道,把 Skill 打包成可上传 claude.ai 的.skill文件(文件数上限 200)。注意:这与"Claude Code/plugin install拉取同一份 git archive"曾经互相踩踏——v3.0.1/v3.0.2 曾因.gitattributesskills/与插件清单一起排除出 tarball 而导致安装包损坏,v3.0.3 回退后才恢复。这个版本的历史教训值得后来者在调整打包排除规则时反复核对。

OpenAI Codex CLI 原生发现(PR #219)

.agents/skills/last30days/SKILL.md真实文件(而非符号链接,Codex 的加载器会跳过 symlink)存在,配合.codex-plugin/plugin.json作为命名空间标记,使 Skill 在 Codex 于仓库目录内运行时以last30days:last30days注册。当前仓库根目录下仍可找到 .claude-plugin/plugin.json 与 .codex-plugin/plugin.json 等插件清单。

/last30days斜杠命令(PR #267)

插件用户直接键入/last30days <topic>,Claude Code 的自动补全会前缀匹配到规范的/last30days:last30days双命名空间形式——不必再手打完整命名空间。

配置默认值与版本元数据对齐

  • INCLUDE_SOURCES从"未设置"改为默认空字符串(PR #223),新安装缺环境变量不再导致来源包含逻辑出错;
  • SKILL.md 版本头与同步目标版本对齐(PR #217),再关闭 SKILL.md 头与 plugin.json 之间残留的漂移(PR #229)——"我到底装在哪个版本上"不再靠猜。

稳定性与贡献者基建:一次"不性感但防止六个月后六份 bug 报告"的扫尾

发布说明特意点明了一批不显眼但关键的可靠性/基建改动:

多密钥 SCRAPECREATORS_API_KEY 轮换(PR #268)设置SCRAPECREATORS_API_KEY_1SCRAPECREATORS_API_KEY_2… 后,密钥撞上速率限制时引擎自动轮换,而不是整次运行失败。对每天跑查询的重度用户,这是"429 随机出现"与"零接触可靠"之间的差别。注:聚合 CHANGELOG 也记载了更早版本曾误删多密钥轮换、之后又恢复的历史(v3.3.0 条目"Restored multi-key rotation… via random.choice per run"),说明这条能力是社区反复守护的契约之一。

Reddit HTTP 层重构(PR #207/#208/#209)统一为http.get(params=...)助手、让_parse_date干净地拒绝垃圾输入、把_sc_headers收敛为http.scrapecreators_headers。当前仓库可以同时看到这两处落点:http.py#L880-L882 的get()与 http.py#L1222-L1225 的scrapecreators_headers()(返回x-api-key+ JSON Content-Type 头)。发布说明的评价很实在:这类 PR 防止的是未来六个 bug 报告。

Bird X 互动字典硬化(PR #234)bird_x遇到全None的 engagement 字典时改为跳过而不是崩溃。当前仓库 bird_x.py#L729-L753 中可以看到这段防御:逐字段尝试转 int、转不动则置None,最后engagement if any(v is not None for v in engagement.values()) else None——互动数据全部为空的极端情况不再杀死整个运行。

离线质量评估(PR #233)新增 fixtures/eval_topics.json 作为评估夹具。文件里是一组带query_type(comparison / how_to / breaking_news / product / opinion / prediction / concept / factual)与rationale的话题清单,例如 "best budget noise cancelling headphones 2026"(product)、"odds of US recession 2026"(prediction)。贡献者与维护者可以用它在不烧线上 API 额度的前提下对综述质量做回归检查——文档明确指出,正是这套夹具让"每次发布都验证 5/5 规范合规"变得在财务上可行。

兼容性守护(PR #230)恢复遗留--days别名的向后兼容,任何在 2.x 时代已针对它写脚本的用户升级到 v3 不会断。

仓库卫生(PR #232).venv.coveragehtmlcov.memsearch移出跟踪树,保持 PR diff 干净。

社区致谢的范围发布说明还单列了两张感谢名单:一张是 v3.0.0 以来的 PR 作者(j-sperling、stephenmcconnachie、zaydiscold、iliaal、Chelebii、george231224、Gujiassh、hnshah、shalomma、BryanTegomoh 等),另一张是塑造 v3 功能集的 roadmap 贡献者(uppinote20 的富评论、zerone0x 的 GitHub 来源、thinkun 的 Reddit 富集超时、thomasmktong 的纯 Python Reddit 回退、zl190 的 HN 趋势合并等),以及那 5 个自我调试的 Opus 4.7 实例。


升级、验证与冒烟测试

发布说明为使用者提供了完整的操作路径,以下命令按 v3.0.9 时代的 Claude Code 插件工作流原样给出(若仓库主线已升级,插件实际安装的版本以官方 marketplace 为准):

全新安装:

/plugin marketplace add mvanhorn/last30days-skill /plugin install last30days@last30days-skill

已安装则更新:

/plugin update last30days /reload-plugins

验证版本(应输出"version": "3.0.9"):

cat ~/.claude/plugins/cache/last30days-skill/last30days/*/.claude-plugin/plugin.json | grep version

冒烟测试:

/last30days birthday gift for 40 year old

预期行为:先抛出澄清问题再决定是否运行。若引擎仍然照常跑了,说明本地缓存是旧的——重复一次插件更新。把这条冒烟测试与上面 preflight.py 的代码对照看,就能完整理解"结构约束(引擎拒绝)> 措辞约束(SKILL.md 提示)"这句话在这个项目里的含义。


回到方法论:当编排下的 LLM 反复违约,去问它为什么

v3.0.9 最值得被"搬运到别的项目"的东西不是任何单个修复,而是发布说明末尾那套自调试问答——作者没有去猜"模型为什么无视规则",而是把失败输出交给模型自己审

  • "你读 SKILL.md 了吗?" → "我试着 Read,撞上 25K token 上限就放弃了,而不是分块读完。"
  • "为什么尾巴上多出 Sources 块?" → "WebSearch 工具自己的提醒写着 MANDATORY,优先级不清楚。"
  • "为什么冒出自拟章节标题?" → "我对 Peter Steinberger 有很强的先验,直接写了篇小论文而不是透传证据。"
  • "为什么读了错误的文件?" → "path glob里先出现了.agents/skills/last30days/SKILL.md。"

五个实例中三个说"把 LAWs 移到顶部",两个说"让引擎强制,让模型想不遵守都不行"。作者两个都做了。完整的手法就是一句话:当受编排的 LLM 持续破坏契约时,不要跟它争辩——让它调试自己,然后把它们点名的根因转写成结构性的强制约束(代码门、可见边界、文件搬迁、输出徽标)。这既解释了本发布说明中拒绝门与 BADGE 前置的由来,也是当前仓库 skills/last30days/SKILL.md 里那些"反向指着失败模式说话"的契约段落的共同设计逻辑。

【免费下载链接】last30days-skillAI agent skill that researches any topic across Reddit, X, YouTube, HN, Polymarket, and the web - then synthesizes a grounded summary项目地址: https://gitcode.com/GitHub_Trending/la/last30days-skill

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/8 23:24:57

uncorr. ECC 显示2是什么意思?服务器内存告警排查全流程

我接手过不少说新不新、说老不老的服务器&#xff0c;最怕的不是性能不够&#xff0c;而是安静跑着的机器突然被一条硬件告警打断。有一回巡检&#xff0c;BMC的事件日志里躺着一行字&#xff1a;Uncorrectable ECC Error, DIMM_A2, Event Count 2。当时看到“Uncorrectable”这…

作者头像 李华