算法艺术创作
algorithmic-art
通过代码和可调参数创作生成艺术与交互式视觉效果。
gdelt-event-mining【设计与创意】Use when a caller needs to query GDELT 2.0 (Global Database of Events, Language, and Tone) for industry events, theme velocity, inflection detection, or macro trend grounding. Supports events_by_theme, inflection_scan, and location_events operations. Reusable by founder-ideation (for trend-first team data), research-*, geopolitical-market-impact, and…
独立 GitHub 快照 · 自动分类 · 以原作者文档为准
Extract structured event signal from GDELT 2.0 — the public global news event cube. Returns normalized event records, theme velocity, and inflection tier detection with provenance. One-shot research tool, not a live stream.
Scope: GDELT 2.0 Event DB, Global Knowledge Graph (GKG), Doc DB. Does NOT provide idea generation — callers do that with the data.
Callers:
founder-ideation (Phase 1) — feeds trend-first team with inflection signalgeopolitical-market-impact — cross-references event codes with market impact modelingProven pattern source: The trading wiki's signals:news stream (news.py at
/path/to/projects/trading/src/data_pipeline/news.py) combines GDELT + RSS with TopicMatcher and
heat scoring. Documented pain: GDELT hits rate-limit (429) periodically. This skill ports the
pattern (GDELT query + 429 retry + RSS fallback + theme heat scoring) but not the
Redis-streaming / live-poller infrastructure. Research use case = one-shot.
events_by_themeFetch events in one or more GDELT themes within a time window.
Inputs:
operation: "events_by_theme"
themes: list[string] # V2Theme codes, e.g. ["ECON_TAXATION", "LEG_REGULATORY"]
locations: list[string] # optional — ISO-3 country codes (e.g. ["USA", "GBR"])
lookback_days: int # default 30
limit: int # default 500, max 2000
Approach:
api.gdeltproject.org/api/v2/doc/doc)SOURCEURL (same URL reported by multiple outlets)limit records sorted by date descOutput:
events:
- event_id: string # GDELT GlobalEventID
date: string # ISO date
actor1:
name: string
country: string
type: string # CAMEO actor type code
actor2: { ... } # optional
event_code: string # CAMEO event code (e.g. "030" = "Express Intent to Cooperate")
event_description: string # human-readable from CAMEO
themes: list[string] # V2Themes
locations: list[string]
tone: float # -100..+100 from GDELT's tone analysis
source_url: string
source_name: string
metadata:
data_source: "gdelt-event-mining v1, pulled YYYY-MM-DD"
operation: "events_by_theme"
queried_at: timestamp
query_count: int
gaps: list[string]
See references/gdelt-api-reference.md for query syntax.
inflection_scanDetect themes that are inflecting (current velocity / baseline velocity ratio exceeds threshold).
Inputs:
operation: "inflection_scan"
themes: list[string] # themes to scan
locations: list[string] # optional geographic filter
lookback_days: int # current window, default 7
baseline_days: int # baseline window, default 30 (must be ≥ 7)
threshold_ratio: float # minimum inflection ratio, default 2.0
limit: int # max inflections to return, default 50
Approach:
velocity_current = count_lookback / lookback_daysvelocity_baseline = count_baseline / baseline_daysratio = velocity_current / velocity_baselinereferences/industry-inflection.md):
WARM: 1.5 ≤ ratio < 2.5HOT: 2.5 ≤ ratio < 5FIRE: ratio ≥ 5Output:
inflections:
- theme: string
velocity_current: float # events per day in lookback
velocity_baseline: float # events per day in baseline
ratio: float
tier: enum # WARM | HOT | FIRE
top_events:
- event_id: string
date: string
location: string
actor1: string
actor2: string
event_description: string
source_url: string
tone: float
hypothesis: string # 1-sentence LLM-generated "why is this inflecting"
# prefixed with "hypothesis:" so caller knows it's not evidence
metadata:
data_source: "gdelt-event-mining v1"
operation: "inflection_scan"
queried_at: timestamp
lookback_days: int
baseline_days: int
gaps: list[string]
location_eventsFetch events by location (useful for "what's happening in {country} around {industry}").
Inputs:
operation: "location_events"
locations: list[string] # ISO-3 country codes
themes: list[string] # optional filter
lookback_days: int # default 30
limit: int # default 500
Same output format as events_by_theme, just filtered by location.
GDELT 2.0 uses the V2Themes taxonomy — a hierarchical catalog with tens of thousands of codes. For founder-ideation use cases, callers don't need the full catalog — they need the common themes that map to industries.
See references/theme-taxonomy.md for the curated founder-relevant theme list, including:
Plus mapping tables: theme → industry → typical founder use case.
GDELT 2.0 uses CAMEO (Conflict and Mediation Event Observations) event codes for event types. For founder use cases, the interesting subsets are:
01x — Make public statement (announcement signals)02x — Appeal (demand signals)03x — Express intent to cooperate (deal signals)04x — Consult (due-diligence signals)05x — Engage in diplomatic cooperation (alliance signals)06x — Engage in material cooperation (deal-signed signals)07x — Provide aid (funding signals)08x — Yield (concession / policy change signals)09x-19x — Investigate / demand / reject / threaten (escalation signals)20x — Use conventional military forceFor ideation, codes 01x-08x are usually most relevant (signals of activity, not conflict). For
risk / regulatory / geopolitical ideation, 10x-20x are also useful.
See references/theme-taxonomy.md#cameo-codes for the full list with founder use-case examples.
https://api.gdeltproject.org/api/v2/doc/doc?query=<query>&mode=ArtList&format=json×pan=<N>days
theme:ECON_TAXATIONsourcelang:eng sourcecountry:UStimespan:7days or explicit date rangeArtList (article list), TimelineVolInfo (volume over time), ToneChart (tone histogram)http://data.gdeltproject.org/gdeltv2/<timestamp>.gkg.csv.zip
Downloadable 15-minute update files. Richer metadata (themes, tone, people, orgs, locations). Used when caller needs full entity extraction rather than headlines. Heavier, use sparingly.
http://data.gdeltproject.org/gdeltv2/<timestamp>.export.CSV.zip
CAMEO-coded event records. Actor1, Actor2, event code, tone, location, URL.
See references/gdelt-api-reference.md for full query syntax, rate limits, and response schemas.
When GDELT rate-limits or is down, the skill falls back to a curated RSS feed list per industry. The fallback is NOT equivalent in coverage (RSS is English-only, typically US/UK outlets, no CAMEO codes) but provides degraded continuity.
Default RSS feed list (configurable per caller):
feeds.reuters.com/reuters/businessNewsfeeds.reuters.com/reuters/technologyNewswww.ft.com/?format=rss (where accessible)www.bloomberg.com/feed/podcast/etf-report.xmlnews.google.com/rss/search?q=<theme>&hl=en-USRSS fallback mode:
event_code: null, tone: null, event_id: rss:<feed>:<guid>metadata.data_source: "gdelt+rss_fallback v1"metadata.gaps: ["gdelt_unavailable: <reason>"]See references/ratelimit-handling.md for the full fallback decision tree.
# Pseudo-code — agent emits this at runtime
import time, urllib.request
def fetch_with_backoff(url, max_retries=5):
backoff = 1
for attempt in range(max_retries):
try:
return urllib.request.urlopen(url, timeout=30).read()
except urllib.error.HTTPError as e:
if e.code == 429:
time.sleep(backoff)
backoff *= 2
continue
raise
except Exception:
time.sleep(backoff)
backoff *= 2
continue
raise RuntimeError("GDELT unavailable after retries")
Circuit breaker:
See references/ratelimit-handling.md for the full protocol.
references/gdelt-api-reference.md — Doc API / GKG / Events endpoint reference, query syntax,
response schemas, example queriesreferences/theme-taxonomy.md — Curated V2Themes list, CAMEO event codes, industry mapping
tablesreferences/industry-inflection.md — Velocity scoring, tier thresholds, false-signal guards,
niche calibrationreferences/ratelimit-handling.md — Backoff protocol, circuit breaker, RSS fallback decision
tree, known GDELT pain points (ported from trading wiki)| Anti-Pattern | Why It Fails | Correct Approach |
|---|---|---|
| Parallelizing > 2 GDELT queries | GDELT's shared infra responds with 429 under load; parallelism makes it worse, not better | Sequentialize with small concurrency cap; use RSS fallback if needed |
| Hitting GDELT with broad queries and filtering client-side | Wastes bandwidth, trips rate limits faster | Push filters server-side via theme + location + date params |
| Trusting tone scores as sentiment ground truth | GDELT tone is approximate; tuned for news articles, not social media | Use tone as a secondary signal, cross-reference with content |
| Treating 429 as a permanent error | Over-reacts to transient rate limits, loses access | Exponential backoff (1→2→4→8→16s); circuit breaker at 3 consecutive failures |
| Baseline < 7 days for inflection scan | Single-day noise triggers false inflections | Enforce baseline_days >= 7 at input validation |
| Skipping RSS fallback because "RSS is worse" | Degraded data is better than no data when GDELT is down | Always configure RSS fallback, mark output with degradation flag |
| Emitting inflection hypotheses without the "hypothesis:" prefix | Callers mistake LLM speculation for GDELT evidence | Always prefix LLM-generated hypothesis with hypothesis: so callers (and founder-ideation) know it's interpretive, not raw signal |
reddit-signal-mining or (Phase 2) hn-pain-mining, etc.