SuperAPI AI Directory

cheat-trends

Writing & research

View repository

Updated 10-16 08:49

About this skill

/cheat-trends — trend fetching

Multi-adapter mode: read each trend-sources adapter's output → deduplicate → rough-score → write to candidates.md。

Overview

[用户:抓热点]
  ↓
[Phase 0: 读 .cheat-state.json 拿 enabled adapters]
  ↓
[Phase 1: 对每个 adapter 调 fetch]
  ↓
[Phase 2: normalize 到 candidate-schema]
  ↓
[Phase 3: 去重(vs candidates / predictions / trends-history)]
  ↓
[Phase 4: 对每个新 item 粗打分(调 cheat-score 内联逻辑)]
  ↓
[Phase 5: 排序 + 询问用户哪些加入 candidates.md]
  ↓
[Phase 6: 写入 + 更新 trends-history.jsonl 缓存]

Constants

  • TREND_SOURCES = ["manual-paste"] — list of enabled adapters (default is manual-paste only, the most reliable)
  • LOOKBACK_HOURS = 24 — fetch trends from the last N hours
  • MAX_PER_SOURCE = 20 — max N items per adapter
  • DEDUPE = true — deduplication toggle
  • AUTO_SCORE = true — after fetching, automatically call cheat-score for rough scoring
  • MIN_COMPOSITE_TO_SUGGEST = 6.0 — items below this score are not recommended for the user to add to the candidate pool (still written to trends-history to avoid re-recommending next time)

💡 Override at call time:/cheat-trends — sources: manual-paste,aihot,weibo-hot — max-per: 10

Inputs

Required Source
.cheat-state.json Default sources
adapters/trend-sources/<name>.md Implementation description of each adapter
candidates.md Deduplication reference
predictions/*.md Deduplication reference (already published items are not recommended again)
.cheat-cache/trends-history.jsonl Historical fetch deduplication cache

Workflow

Phase 0: Read enabled adapters

# 伪代码
state = read('.cheat-state.json')
enabled_adapters = args.sources or state.get('enabled_trend_sources', ['manual-paste'])

If enabled_adapters is empty → output guidance:

你目前没有启用任何热点源。

最快配法:
- 临时跑:/cheat-trends — sources: manual-paste,aihot
- 永久启用:编辑 .cheat-state.json 的 enabled_trend_sources 数组

可用 adapter(详见 adapters/trend-sources/):
- manual-paste(默认,永远能用)
- aihot(AI 热点聚合,无需 key)
- weibo-hot(微博热搜,无需 key)
- zhihu-hot(知乎热榜,无需 key)
- trendradar-mcp(TrendRadar MCP 服务,需配置)

Phase 1-2: Call fetch + normalize for each adapter

For each adapter, read the adapters/trend-sources/<name>.md fetch interface described in (actually Bash calling underlying Python / shell / WebFetch):

Adapter Implementation mechanism
manual-paste Ask the user: "Paste your candidate URL/title list for today (one per line)" → parse each line, do WebFetch on URLs to expand snippets
aihot Read the fetch interface described in adapters/trend-sources/aihot.md
weibo-hot Read the fetch interface described in adapters/trend-sources/weibo-hot.md
zhihu-hot Read the fetch interface described in adapters/trend-sources/zhihu-hot.md
trendradar-mcp Read the fetch interface described in adapters/trend-sources/trendradar-mcp.md

Each adapter outputs items conforming to candidate-schema.md .

Graceful degradation: single adapter failure (missing API key / endpoint 503 / expired cookie) → skip that adapter,do not throw an exception, and explain in the summary:

✅ aihot: 拉到 18 条
✅ weibo-hot: 拉到 15 条
✅ zhihu-hot: 拉到 12 条
⚠️  trendradar-mcp: 跳过(MCP 服务未配置——配置见 adapters/trend-sources/trendradar-mcp.md)

Phase 3: Deduplication

According to the "deduplication protocol" in candidate-schema.md :

  1. Compute an id for each item (sha256(source_type + normalized_title + url_path)[:12])
  2. Check whether candidates.md already contains this id → skip
  3. Check whether predictions/*.md already contains this id → skip
  4. Check whether .cheat-cache/trends-history.jsonl already contains this id and rejected_at != null → skip

Write deduplication statistics to the summary report.

Phase 4: Rough scoring

AUTO_SCORE=true when enabled, for each new item:

  1. Use the item's snapshot_text as input
  2. Score the 7 dimensions according to the current rubric (do notcall the /cheat-score sub-skill for IO; reuse the scoring logic inline)
  3. Compute composite
  4. Give a one-sentence rationale

Note: rough scoring ≠ formal prediction. Prediction must be based on the final draft (edited by the user); the scoring here is only a rough filter for "whether it's worth expanding into a piece".

AUTO_SCORE=false when enabled, when items are written to candidates.md, composite=null, and manual /cheat-score。

Phase 5: Sort + Ask

Sort by composite descending, filter out composite < MIN_COMPOSITE_TO_SUGGEST of:

🔥 抓热点完成。各源拉取统计:
- manual-paste: 5 条(用户输入)
- aihot: 18 条
- weibo-hot: 15 条
跳过 trendradar-mcp(MCP 服务未配置)

去重后剩 27 条新 item。
粗打分后 12 条 composite ≥ 6.0:

| # | 标题 | source | composite | bucket | rationale |
|---|---|---|---|---|---|
| 1 | 为什么我们都讨厌主动联系朋友 | aihot | 8.4 | 30-100w | ER+QL 双 5,AB 普适 |
| 2 | "她不一样"的一千种变体 | weibo-hot | 8.1 | 30-100w | MS 候选维度高 |
| 3 | ...... |

哪些加入 candidates.md?
- 全部加 → 回 "all"
- 选几个 → 回 "1, 3, 5"
- 都不要 → 回 "none"(这些会被记到 trends-history 避免下次重复推)

Phase 6: Write to disk

After user response:

  1. Selected items → by candidate-schema.md 's "Markdown representation" format append to candidates.md
  2. All fetched items (whether selected or not) → append to .cheat-cache/trends-history.jsonl:
    {"id": "...", "title": "...", "source": "...", "snapshot_at": "...", "rejected_at": null|"<ISO>", "fetched_at": "<ISO>"}
    

Phase 7: Status update

{
  "last_trends_run_at": "<ISO>",
  "last_trends_added_count": 5
}

Key Rules

  1. Do not throw exceptions. Single adapter failure → skip + report. All adapters fail → error "all sources failed", with troubleshooting guidance
  2. manual-paste is always in. Even if all other adapters are broken, manual-paste mode must work—it is the fallback
  3. Deduplication is a hard constraint. Same id is not pushed repeatedly; items the user rejected are not pushed again for 6 months
  4. Rough scoring must be honestly labeled. In the entry in candidates.md, mark composite (rough, snapshot-based), to avoid confusion with prediction's fine scoring
  5. Do not go directly into predictions/. trends only produces candidates; predict is another action

Refusals

  • "Directly scrape Douyin trending feed without cookies" → reject. Douyin's anti-scraping is extremely strict; without cookies it will definitely fail; guide to the douyin-session adapter configuration documentation
  • "Skip deduplication and write in everything scraped" → reject. It will pollute the candidate pool, and the next recommend ranking will fail
  • "Skip rough scoring and directly write raw titles" → allow (AUTO_SCORE=false), but prompt the user that they will subsequently need /cheat-score to enter the recommend pool

Integration

  • Upstream: user-configured .cheat-state.json 's enabled_trend_sources array
  • Downstream:/cheat-recommend directly reads candidates.md sorting—as soon as trends finishes writing, recommend sees it immediately
  • And /cheat-init: users who selected "no candidate pool" in onboarding Q4 are guided here
  • And /cheat-status: the status dashboard shows "Last trend scrape: X days ago / Candidate pool pending cleanup: Y items"

Adapter implementation notes

Each adapters/trend-sources/<name>.md must document the following:

  1. Dependencies:API key / cookie / package
  2. fetch interface: invocation method (python script path / shell command / API endpoint)
  3. Output schema: must conform to candidate-schema.md
  4. Failure modes: common errors + graceful degradation behavior
  5. Stability level: ★ 1-5 stars

See adapters/HOWTO.md(to be implemented in batch 3).