跳转到内容

选择语言

当前语言: 简体中文

如何用 last30days 来完成基于社交网络的 AI 调研需求

编辑此页
HagiCode for Windows Microsoft Store artwork
HagiCode for Windows 已上线 Microsoft Store
HagiCode for Windows 现已正式登陆 Microsoft Store,Windows 用户可以直接从商店完成安装并接收渠道更新。现在就打开商店页看看吧。
打开 Microsoft Store

如何用 last30days 完成基于社交网络的 AI 调研需求

社交网络上每天都有人在表态:发帖、投票、争吵、退订、迁移。这些散落在 Reddit、X、YouTube 评论、TikTok、Hacker News、Polymarket 上的声音,单独看只是噪音,攒到一起却是一份相当真实的民意切片。问题只在于——没人愿意为了一个调研结论,手动去八个平台翻三十天的帖子。

last30days 这个 skill 就是为此而生的。它会替你把上面这些渠道的近三十天内容拉到一起、按主题合成。而 preset task 这一层,则把”调用 last30days”这件事,从一句需要记参数的指令,变成一个填好就能跑的表单。

这篇文章想聊的,不是 last30days 本身有多好用,而是 HagiCode 怎么用 preset task 这套编排机制,把”一个 skill 编排出四种调研姿态”这件事做扎实的。毕竟,skill 是能力,preset 是把能力变成产品的胶水。

背景:preset 想省下的,其实是那句被反复说的话

preset task 体系最早是 preset 级绑定一个 skill。也就是说,一个 preset 对应一个 skill,调用方式相对单一。可现实里,同一个能力往往要以不同姿态被使用——同样是 last30days,有时候你想做泛调研,有时候你想做竞品对比,有时候你只想针对某个产品做提示词风格的分析。

把这些不同的使用方式硬塞进一个交互流程里,界面会越来越乱;拆成四个独立 skill,又重复造轮子。于是设计上往中间走了一步:允许在 command 级绑定 skill。一个 preset 下挂多个 command,每个 command 自描述自己要调用哪个 skill、用什么参数;而 preset 层的 requirements 则作为权威清单,声明这个 preset 一共依赖哪些 skill。

这样一来,界面归界面,执行归执行。谁愿意把界面样式和执行逻辑揉成一团呢。

一个 skill,四种 mode

last30days 这个 preset 就是这个范式的样板:一个 skill,四个 command。四个 command 对应四种调研姿态:

  • general(泛调研):给一个 query,让 last30days 自己去各平台捞近三十天的相关讨论,再合成结论。
  • comparison(对比):明确给出要对比的对象,让 skill 围绕”谁更好/谁更差/各自痛点”组织素材。
  • competitors(竞品):聚焦于某个产品的竞品生态,调用 last30days 自带的 --competitors flag。
  • prompting(提示词风格):关注人们实际上在怎么用、怎么提问,偏向用法与心智模型。

四个 command 在 commands.json 里全部声明 "skill": "last30days",但各自的 prelude(参数与提示)不同。前端抽屉里用户选的是 mode、写的是 query、勾的是目标仓库;至于背后拼出哪条指令,由 preset 自己决定。用户不必记参数,也不必知道 --competitors 这种 flag 的存在。

两层数据:commands.json 与 task-preset.json

preset 包里有两个文件分担职责,分得相当干净:

  • commands.json:描述”有哪些 command、每个 command 长什么样”。每个 command 自带 skill 字段,说明它要调用哪个 skill;还带着自己的 prelude 模板,说明怎么把这个 command 拼成一行指令。这是 command 级的自描述。
  • task-preset.json:描述”这个 preset 整体需要什么”。它持有 requirements(声明依赖的 skill 清单)、inputs 定义、inputBindings,以及 selectionMode 之类的元信息。这是 preset 级的权威清单。

两层各自的边界很清楚:command 负责说”我需要这个 skill”,preset 负责说”我这个 preset 允许用到哪些 skill”。如果某个 command 声明了一个 skill,但 preset 的 requirements 里没有,校验就会报错——diagnostic 是 command-skill-not-in-requirements。这种显式的失败,比静默退化要好得多。

单行注入:/{skill} {prelude}

把 skill 真正接进执行流程的,是一个不起眼的小机制:单行注入。

PresetTaskCatalogProvider 里有个方法叫 CombineCommandSkillPrelude。逻辑很简单:如果一个 command 声明了 skill,并且它渲染出来的 prelude 行不是以 /{skill} 开头,那就把 /{skill} 前置上去。最后交给执行器的,是形如:

/last30days {commandPrelude}

这样的一行独立指令。紧接着才是 user.hbs 渲染出来的正文:模式塑形、query、目标仓库边界、以及”非交互、记录假设”的约束。

为什么要这么做?因为 last30days 这类 skill 本身就是按”收到 /{skill} 指令”来加载和运行的。preset 不能假设 skill 会自动被触发,必须显式地把这条指令喂进去。一行而已,却是整个链路能跑通的关键。

五段式技术链路

把上面这些串起来,从用户点提交到结论回连仓库,一共是五段:

  1. 前端选单:用户在 CreatePresetTaskDrawer 里选 mode、写 query、勾目标仓库。resolveCommandPreview 镜像后端的拼装逻辑,实时把预览指令显示给用户看;buildTargetScopeMarkdown 按 read/write 分组,把仓库边界算成一段 markdown。
  2. 后端校验:请求落到 SessionsController.PresetTasks.TryResolvePresetTaskRequestAsync。它先校验 inputs/targets/derived 的键是不是在白名单里、command id 是不是在 catalog 内、selectionMode 是不是 single,再跑 PresetTaskRequirementCheckService.CheckAsync:对每个 requirements 里的 skill,通过 LocalSkillCommandAdapter 查本地 skill inventory,按 CacheKey 去重。
  3. 提示词渲染:根据 locale 渲染对应的 user.hbs,把 last30daysMode、last30daysQuery、targetScopeMarkdown、targetRepositories 注入进去。user.hbs 明确禁止 AskUserQuestion,要求执行器在遇到歧义时记录假设而不是反问——这是非交互执行的硬边界。
  4. skill 加载与执行:执行器收到拼好的 prompt。/last30days 作为独立指令在最前,触发 skill 加载。skill 内部按自己的 LAWs 跑:Step 0.45 做 keyword-trap 预检(防止 query 被误当成 handle/subreddit),Step 0.5/0.55 解析定向渠道,Step 0.75 让推理模型自己生成 --plan,然后跑 Python 引擎去 Reddit/X/YouTube/TikTok/Instagram/HN/Polymarket/Web 拉数据,Step 2 用 WebSearch 补充,Step 2.5 追加到 raw 文件,最后按 LAWs 合成结论。
  5. 结论回连:合成出的结论带回到 preset 的上下文里。目标仓库的 read/write 边界,是靠 prompt 里的 targetScopeMarkdown 软约束的——preset 告诉 skill”你只能读这几个、能写那几个”,skill 在自己的执行里遵守这条边界。

几条实践要点

  • 非交互边界要写进模板。user.hbs 里禁用 AskUserQuestion,不是建议,是硬约束。preset 跑起来后没有人坐在屏幕前回答反问,所以歧义必须靠”记录假设”来消化。
  • 能预置的 flag 就预置。竞品 mode 直接把 --competitors 写进 prelude,用户不需要知道这个 flag 的存在。preset 的意义就是把专业参数藏到合适的人手里。
  • skill 去重靠 CacheKey。requirements 里同一个 skill 出现多次也没关系,PresetTaskRequirementCheckService 按 CacheKey 去重,不会重复检查、重复加载。
  • 仓库边界是软约束。read/write 边界靠 prompt 注入,不是靠沙箱。这意味着 skill 是否听话,部分取决于它对 prompt 的遵循程度。这是一个现实的折中。
  • 失败要明确,不要静默。skill 缺失就报 requirement check 失败,返回 400,并在前端给出”一键安装”入口(openSkillGalleryForSkill)。让用户知道哪里坏了、怎么修,比悄悄退化成”没有 skill 也能跑”要负责得多。
  • 迁移要无破坏。从 preset 级 skill 到 per-command skill 的演进,是向后兼容的。老的 preset 级声明仍然有效,新的 command 级声明是叠加能力,不是替换。步子迈太大,容易扯着,何必呢。

preset task 把一个 skill 变成四种产品形态,靠的不是什么精巧的算法,而是几处边界划得干净的契约:command 自描述、preset 权威清单、单行注入、非交互硬约束、显式失败。把这些拼起来,“用 last30days 做社交网络调研”这件事,才从一句需要记参数的指令,变成了一个填表就能跑的功能。

至于这些声音攒到一起到底能说明什么,那是 last30days 自己的活儿了……

开始使用 HagiCode

一次安装,几分钟上手

HagiCode for Windows 在 Microsoft Store 免费提供。打开商店即可安装并保持更新;也可以先对比各版本与定价,再决定从哪个渠道开始。