关于 last30flames
用于近期网络主题研究的技能,会收集带来源的研究上下文,再由运行它的模型撰写简报。它并行查询网页、Hacker News、Lobste.rs、Bluesky 和 GitHub,并支持主题消歧、对比研究及保存上下文。
主要功能
- 01并行收集五类来源
- 02网页内容抓取为完整 Markdown
- 03按公开 API 获取互动数据
- 04歧义主题解析与查询细化
- 05自动拆分对比主题
- 06保存并复用研究上下文
适用场景
- 01撰写带引用的近期主题简报
- 02比较两个或多个产品近期动态
- 03追踪项目的 GitHub 活动及社区反响
- 04保存研究上下文供后续会话使用
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ firecrawl/ last30flames --skill last30flames安装后在 Claude Code 中输入/last30flames确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
.env.examplebun.lockpackage.jsontsconfig.jsonscripts/bluesky.tsconfig.tsderive-sides.test.tsderive-sides.tsfirecrawl.tsformat.test.tsformat.tsgithub.tshackernews.tshtmlify.tsindex.tslobsters.tsresolve.tsrun.shtypes.tsurl.ts详细介绍
last30flames
围绕一个主题研究近期网络内容,并撰写一份简短、有来源依据的简报。
此技能由一个轻量引擎和你的综合分析组成。引擎会收集来源并输出一份整洁、带编号的研究上下文;你(运行此技能的模型)阅读该上下文并撰写简报。
**无需密钥。**引擎不会调用大模型(由你进行综合分析),并通过 Firecrawl CLI 访问 Firecrawl;未设置密钥时,CLI 会使用无需密钥的免费层。如果环境中已设置 FIRECRAWL_API_KEY,CLI 会自动使用它,以获得更高的限额和并发能力——因此,密钥只是速度升级选项,而非必需条件。用户无需重新安装,先在无密钥状态下启动,之后再设置 FIRECRAWL_API_KEY(或运行 firecrawl login),下一次运行时即可完成身份验证。
工作原理
五个来源并行运行:
- Firecrawl Search——将网页搜索结果抓取为完整页面 Markdown,而非摘要片段。
- Hacker News(公共 Algolia API)——积分数 + 评论数。
- Lobste.rs(公共 JSON Feed)——积分数 + 评论数。
- Bluesky(公共 AT Protocol API)——点赞数 + 转发数 + 回复数。
- GitHub(官方 API)——星标数 + 最近的推送活动。
互动数据仅来自公开提供这些数据的 API。此技能绝不会访问 Reddit、X、TikTok、Instagram,或任何需要登录或 Cookie 的内容。
运行引擎
任何支持技能的 Agent 框架都可以运行此引擎。你已经知道 SKILL.md 的绝对路径,因为你刚刚读过它;接下来调用它旁边的 scripts/run.sh。该脚本会自动定位自身,首次运行时安装依赖,并接受主题以及可选的 --days N 时间范围(任意数字,例如 7、30、365;默认值为 30):
bash <SKILL_DIR>/scripts/run.sh "<TOPIC>" --days 30
将 <SKILL_DIR> 替换为此文件所在的目录。不要依赖 $CLAUDE_PLUGIN_ROOT 或当前工作目录——启动器会处理这两者。唯一的要求是有 bun 二进制文件;无需 API 密钥(仅在需要提高 Firecrawl 限额时设置 FIRECRAWL_API_KEY)。
进度会输出到 stderr;带编号的研究上下文会输出到 stdout。请阅读 stdout——它就是你的证据。
先消除有歧义主题的歧义(建议)
如果主题可能指向多个对象——某个人的姓名、与常见事物同名的产品(“Apple”“Cursor”)、单独的用户名——请先运行一次成本较低的解析流程,再进行主要收集:
bash <SKILL_DIR>/scripts/run.sh --resolve "<TOPIC>"
该流程会输出候选身份(网页标题 + 描述、GitHub 仓库和用户候选项),不会抓取任何页面。阅读候选项并决定:
- 2-4 条经过细化的子查询,用于明确目标对象(例如,对于 AI 编辑器“Cursor”,可使用
"Cursor AI editor"、"Cursor IDE agent")。 每条子查询都会增加 Firecrawl 搜索和抓取的工作量,因此运行时间会随查询数量增加——请使用能明确目标对象的最少数量,通常是 2 条。 - 如果主题是个人或项目,则确定匹配的 GitHub 登录名和/或 所有者/名称仓库。
然后使用这些信息运行主要收集流程,并为每条子查询传入一次 --query:
bash <SKILL_DIR>/scripts/run.sh "<TOPIC>" --days 30 \
--query "<subquery 1>" --query "<subquery 2>" \
--github-user <login> --github-repo <owner/name>
引擎会针对每条子查询搜索网络、Hacker News、Lobste.rs 和 Bluesky(最多 4 条,并去重重叠结果),同时将 GitHub 搜索范围限定为指定的登录名/仓库。所有标志都是可选的——主题清晰具体时,可以完全跳过解析,像以前一样直接运行一次即可。解析流程本身不会做任何决定;决定由你来做。
对比主题(“X vs Y”)
当主题是对比两到三项内容(“cursor vs zed”、“bun versus deno”)时,引擎会在一次运行中为每一方完整收集信息,并按各方对研究上下文进行分组,同时连续编号引文。
主题中无论大小写只要包含“vs”或“versus”,就会自动拆分,因此简单写法即可生效。唯一例外是全大写的“VS”,这样“best VS Code extensions”之类的主题会保留为单方;若要比较名称中包含“VS”的内容,请使用 --compare:
bash <SKILL_DIR>/scripts/run.sh "cursor vs zed" --days 30
网页抓取预算(--limit)由各方共享,因此与单独运行相比,对比中每一方抓取的页面都会更少;如果希望每一方都达到完整的深度,请传入更高的 --limit(例如,两方对比时使用 --limit 10)。
若要让各方的结果更精准,请每一方传入一次 --compare;其后任何 --query、--github-user 或 --github-repo 标志都会归入对应的 --compare 范围(如果名称存在歧义,请先对每一方分别运行 --resolve):
bash <SKILL_DIR>/scripts/run.sh "cursor vs zed" \
--compare "Cursor" --query "Cursor AI editor" --github-repo getcursor/cursor \
--compare "Zed" --query "Zed editor" --github-repo zed-industries/zed
根据分组后的上下文综合撰写逐项对比简报:说明各方在这段时间内的变化,然后直接比较(通过互动数据衡量热度、值得注意的发布活动、最适用的场景)。 像往常一样在文中引用双方;编号在各方之间连续,因此不会冲突。
保存并复用上下文(可选)
默认不写入任何文件,只综合撰写简报。只有用户提出要求时才保存(例如“保存上下文”、“我之后还会用到”)。
保存的上下文位于 ~/.last30flames/ 下,按话题文件夹分组,以便将一系列相关调用作为一个整体重新加载。话题文件夹只是一个带名称的子目录;每次调用都会保存到各自的文件中,这样每次调用的 [1]、[2] 引文编号都能保持完整(绝不要将两个上下文合并到一个文件中,否则编号会冲突):
~/.last30flames/<thread>/
<slug>-<YYYY-MM-DD>.md # one file per engine call
**保存时:**重定向引擎的 stdout,以保留原始的编号研究上下文(也就是可复用的证据,而不是简报)。先确定话题文件夹:
- 如果用户指定了话题(“把它保存到我的 ai-agents research”),将其转换为 slug,记为
<thread>。 - 否则,复用本次对话中之前保存时使用的话题,让相关调用归入同一文件夹。
- 如果上述情况都不适用,则根据主题生成
<thread>,并告知用户你选择的名称,以便之后引用。
通过将主题转换为 slug 来生成 <slug>(转为小写、用连字符替换空格、删除标点),让文件名能说明这次调用的主题。然后创建文件夹并写入文件,最后报告确切路径:
mkdir -p ~/.last30flames/<thread>
bash <SKILL_DIR>/scripts/run.sh "<TOPIC>" --days 30 > ~/.last30flames/<thread>/<slug>-<YYYY-MM-DD>.md
由于重定向会将研究上下文写入文件而非 stdout,Bash 输出中只会显示 stderr 进度信息。如果用户还想在本次会话中获取简报,请先 Read 已保存的文件以获取上下文,然后照常综合撰写。
如果用户明确指定了其他路径,请按其要求操作。
复用时(后续会话):用户无需记住确切名称。如果他们以较宽泛的方式提及已保存的研究(“加载我的 ai-agents research”),请列出 ~/.last30flames/ 下的话题文件夹,并按话题名称匹配;然后 Read 该文件夹中的每个 .md 文件,并综合其中所有内容,同时将引文按来源文件区分命名空间,避免不同调用的编号冲突。
如果要重新加载单次调用而非整个话题,请根据 <slug>-<date> 名称匹配单个文件。如果没有匹配项,请询问用户保存位置。
由于每个文件名的格式为 <slug>-<YYYY-MM-DD>.md,仅凭文件名就能确定主题和保存日期,无需外部记忆。在综合之前,请根据 --days 窗口检查每个文件的日期:如果当前日期距保存日期已超过指定天数,则时效性已无法保证;请提醒用户上下文已过时,并提供重新获取最新信息的选项。
按复用方式处理的提示(不要重新运行引擎):
last30flames load my ai-agents research
last30flames using my saved ai-agents research, what did I find on local inference?
撰写简报
根据编号来源,撰写几段简洁的文字,要求:
- 开篇说明这段时间真正的新进展或正在发生的变化,而不是背景信息。
- 每项说法都要有来源依据,并以内联引用标注,例如
[1]、[3]。 - 使用互动数据(HN 点数/评论数、GitHub 星标)作为判断人们实际关注点的信号,并优先考虑互动量高的内容。
- 如实说明证据不足之处,不要编造细节。如果 HN 或 GitHub 返回的信息很少,也要坦诚说明。
简报末尾附上一份精简的 来源 列表,让每条内联引用都可点击。每个实际引用的来源单独占一行,并使用内联引用中的相同编号,格式为 Markdown 链接:
Sources:
[1] [Title of the page](https://example.com/article) - example.com
[3] [Show HN: Something](https://news.ycombinator.com/item?id=123) - news.ycombinator.com
只列出引用过的来源——这是给读者查阅的参考列表,不是研究背景材料的完整罗列。切勿将原始研究背景材料粘贴回来。
可分享的 HTML 简报(可选)
当用户要求提供可分享版本的简报(例如“让这份内容方便分享”“给我一个 HTML 文件”“提供一份可以放进 Slack/邮件/Notion 的版本”)时,除了正常的聊天回复,还要生成一份自包含的深色模式 HTML 文件。该文件使用内联 CSS,不含 JavaScript 或外部资源,可离线使用,并且在任何地方的渲染效果都相同。
首先,将你撰写的简报(包括编号相同的 Sources: 列表)以 Markdown 格式写入线程文件夹,按照上文保存流程中的要求准确选择 <thread> 和 <slug>:
mkdir -p ~/.last30flames/<thread>
# Write the brief markdown to ~/.last30flames/<thread>/<slug>-<YYYY-MM-DD>-brief.md
bun <SKILL_DIR>/scripts/htmlify.ts ~/.last30flames/<thread>/<slug>-<YYYY-MM-DD>-brief.md
转换器会将标题、段落、列表、链接和内联 [N] 引用转换为 HTML——每条引用都会变成指向来源列表中相应条目的可点击跳转链接;转换器会在 Markdown 文件旁写入 <slug>-<YYYY-MM-DD>-brief.html,并打印输出路径。
将该路径告知用户。
如果用户指定了其他输出位置,请通过 -o <path> 传入。
转换的是你撰写的简报,不是原始研究背景材料——切勿将引擎的标准输出转换为 HTML。