signal-scanner

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

Signal Scanner

信号扫描器

Scheduled scanner that detects buying signals on TAM companies and watchlist personas, writes them to the
signals
table, and sets up downstream activation.
定时扫描工具,用于检测目标市场(TAM)公司及观察列表人物的购买信号,将其写入
signals
表,并为下游激活流程做准备。

When to Use

使用场景

  • After TAM Builder has populated companies and personas
  • As a recurring scan (daily/weekly) to detect timing-based outreach triggers
  • When you need to move from static lists to intent-driven outreach
  • 在TAM Builder完成公司及人物数据填充后使用
  • 作为周期性扫描(每日/每周),检测基于时间节点的触达触发条件
  • 当你需要从静态列表转向基于意向的触达时使用

Prerequisites

前置条件

  • SUPABASE_URL
    +
    SUPABASE_SERVICE_ROLE_KEY
    in
    .env
  • APIFY_TOKEN
    in
    .env
    (for Phase 2 signals)
  • ANTHROPIC_API_KEY
    in
    .env
    (optional, for LLM content analysis)
  • TAM companies populated via
    tam-builder
  • Watchlist personas created for Tier 1-2 companies
  • .env
    文件中配置
    SUPABASE_URL
    +
    SUPABASE_SERVICE_ROLE_KEY
  • .env
    文件中配置
    APIFY_TOKEN
    (用于第二阶段信号检测)
  • .env
    文件中配置
    ANTHROPIC_API_KEY
    (可选,用于LLM内容分析)
  • 通过
    tam-builder
    完成TAM公司数据填充
  • 为Tier 1-2公司创建观察列表人物

Signal Types

信号类型

PrioritySignalLevelSourceCost
P0Headcount growth (>10% in 90d)CompanyData diffsFree
P0Tech stack changesCompanyData diffsFree
P0Funding roundCompanyData diffsFree
P0Job posting for relevant rolesCompanyApify linkedin-job-search~$0.001/job
P1Leadership job changePersonApify linkedin-profile-scraper~$3/1k
P1LinkedIn content analysisPersonApify linkedin-profile-posts + LLM~$2/1k + LLM
P1LinkedIn profile updatesPersonApify linkedin-profile-scraper~$3/1k
P2New C-suite hireCompanyDerived from person scansFree
优先级信号层级来源成本
P0员工人数增长(90天内增长>10%)公司数据差异免费
P0技术栈变更公司数据差异免费
P0融资轮次公司数据差异免费
P0相关岗位的招聘信息公司Apify linkedin-job-search~$0.001/条招聘信息
P1领导层岗位变动人物Apify linkedin-profile-scraper~$3/1000条
P1领英内容分析人物Apify linkedin-profile-posts + LLM~$2/1000条 + LLM费用
P1领英资料更新人物Apify linkedin-profile-scraper~$3/1000条
P2新C-suite高管招聘公司从人物扫描结果推导免费

Config Format

配置格式

See
configs/example.json
for full schema. Key sections:
  • client_name
    — which client's TAM to scan
  • signals.*
    — enable/disable each signal type with thresholds
  • scan_scope
    — filter by tier, status, lead_status
完整配置 schema 请参考
configs/example.json
。核心配置项:
  • client_name
    — 要扫描的客户对应的TAM
  • signals.*
    — 启用/禁用各信号类型并设置阈值
  • scan_scope
    — 按层级、状态、潜在客户状态过滤

Database Write Policy

数据库写入规则

CRITICAL: Never write signals or update lead statuses without explicit user approval.
The signal scanner writes to multiple tables:
signals
(insert),
enrichment_log
(insert),
companies
(patch snapshots), and
people
(patch lead_status). These writes affect downstream outreach decisions — bad signals lead to bad outreach timing.
Required flow:
  1. Always run
    --dry-run
    first
    to detect signals without writing to the database
  2. Present the dry-run results to the user: signal count, types, top signals, affected companies/people
  3. Get explicit user approval before running without
    --dry-run
  4. Only then run the actual scan that writes to the database
Why this matters:
  • Signals drive outreach timing — incorrect signals trigger premature outreach
  • lead_status
    changes from
    monitoring
    to
    signal_detected
    are hard to undo across many records
  • Snapshot updates affect future signal diffs — bad snapshots cascade into future scans
  • Enrichment log entries track Apify credit spend
The agent must NEVER pass
--yes
on a first run.
The
--yes
flag is only for pre-approved scheduled scans where the user has already validated the signal detection logic.
重要提示:未经用户明确批准,绝不能写入信号或更新潜在客户状态。
信号扫描器会写入多个表:
signals
(插入)、
enrichment_log
(插入)、
companies
(更新快照)、
people
(更新lead_status)。这些写入操作会影响下游触达决策——错误的信号会导致触达时机不当。
必填流程:
  1. 务必先执行
    --dry-run
    ,检测信号但不写入数据库
  2. 向用户展示试运行结果:信号数量、类型、顶级信号、受影响的公司/人物
  3. 获得用户明确批准后,再执行无
    --dry-run
    的扫描
  4. 只有此时才能运行实际写入数据库的扫描
为何这很重要:
  • 信号驱动触达时机——错误信号会触发过早触达
  • lead_status
    monitoring
    变为
    signal_detected
    后,大量记录的回滚操作难度大
  • 快照更新会影响未来的信号差异检测——错误快照会导致后续扫描出现连锁问题
  • enrichment log条目会跟踪Apify的积分消耗
智能体绝不能在首次运行时使用
--yes
参数。
--yes
标志仅适用于用户已验证过信号检测逻辑的预批准定时扫描。

Usage

使用方法

bash
undefined
bash
undefined

Dry run first (ALWAYS DO THIS) — detect signals without writing to DB

先执行试运行(务必先做这一步)—— 检测信号但不写入数据库

python skills/capabilities/signal-scanner/scripts/signal_scanner.py
--config skills/capabilities/signal-scanner/configs/my-client.json --dry-run
python skills/capabilities/signal-scanner/scripts/signal_scanner.py
--config skills/capabilities/signal-scanner/configs/my-client.json --dry-run

Full scan (only after user reviews dry-run results and approves)

完整扫描(仅在用户查看试运行结果并批准后执行)

python skills/capabilities/signal-scanner/scripts/signal_scanner.py
--config skills/capabilities/signal-scanner/configs/my-client.json
python skills/capabilities/signal-scanner/scripts/signal_scanner.py
--config skills/capabilities/signal-scanner/configs/my-client.json

Test mode (5 companies max)

测试模式(最多5家公司)

python skills/capabilities/signal-scanner/scripts/signal_scanner.py
--config configs/example.json --test --dry-run
python skills/capabilities/signal-scanner/scripts/signal_scanner.py
--config configs/example.json --test --dry-run

Free signals only (skip Apify)

仅检测免费信号(跳过Apify)

Set all Apify signals to enabled: false in config

在配置中将所有Apify信号设置为enabled: false

undefined
undefined

Flags

命令行标志

FlagEffect
--config PATH
Path to config JSON (required)
--test
Limit to 5 companies, 3 people
--yes
Auto-confirm Apify cost prompts. Only use for pre-approved scheduled scans.
--dry-run
Detect signals but don't write to DB. Always run this first.
--max-runs N
Override Apify run limit (default 50)
标志作用
--config PATH
配置JSON文件路径(必填)
--test
限制为最多5家公司、3个人物
--yes
自动确认Apify成本提示。仅适用于预批准的定时扫描。
--dry-run
检测信号但不写入数据库。务必先执行此操作。
--max-runs N
覆盖Apify的运行次数限制(默认50次)

Output

输出

Signals table writes

写入signals表

Each signal includes:
client_name
,
company_id
,
person_id
,
signal_level
(company or person),
signal_type
,
signal_source
,
strength
,
signal_data
(JSON),
activation_score
,
detected_at
,
acted_on
,
run_id
.
每个信号包含:
client_name
company_id
person_id
signal_level
(公司或人物)、
signal_type
signal_source
strength
signal_data
(JSON格式)、
activation_score
detected_at
acted_on
run_id

Other database writes

其他数据库写入操作

  • Person
    lead_status
    updated to
    signal_detected
    when activation_score >= threshold
  • Company
    metadata._signal_snapshot
    updated for next diff cycle
  • Person
    raw_data._signal_snapshot
    updated for next diff cycle
  • enrichment_log
    entries with
    tool='apify'
    ,
    action='search'
    or
    'enrich'
    , plus
    credits_used
  • 当activation_score达到阈值时,将人物的
    lead_status
    更新为
    signal_detected
  • 更新公司的
    metadata._signal_snapshot
    ,用于下一轮差异检测
  • 更新人物的
    raw_data._signal_snapshot
    ,用于下一轮差异检测
  • enrichment_log
    中插入条目,包含
    tool='apify'
    action='search'
    'enrich'
    ,以及
    credits_used

Console output

控制台输出

  • Summary stats printed to stdout
  • 汇总统计信息将打印到标准输出

Activation Score

激活评分

activation_score = strength * recency_multiplier * account_fit

Recency:   <24h = 1.5, 1-3d = 1.2, 3-7d = 1.0, 1-2w = 0.8, 2-4w = 0.5
Account:   Tier 1 = 1.3, Tier 2 = 1.0, Tier 3 = 0.7
activation_score = strength * recency_multiplier * account_fit

时效性:   <24小时 = 1.5, 1-3天 = 1.2, 3-7天 = 1.0, 1-2周 = 0.8, 2-4周 = 0.5
客户层级:   Tier 1 = 1.3, Tier 2 = 1.0, Tier 3 = 0.7

Connects To

关联模块

  • Upstream:
    tam-builder
    (provides companies + people)
  • Downstream:
    cold-email-outreach
    (acts on signals)
  • 上游:
    tam-builder
    (提供公司+人物数据)
  • 下游:
    cold-email-outreach
    (根据信号执行操作)

File Structure

文件结构

signal-scanner/
├── SKILL.md
├── configs/
│   └── example.json
└── scripts/
    └── signal_scanner.py
signal-scanner/
├── SKILL.md
├── configs/
│   └── example.json
└── scripts/
    └── signal_scanner.py