“请帮我圈出最近7天内在广州、使用iOS、关注抖音财经频道、观看超过5条视频的用户。”
在字节跳动,每天都有数万次这样的“人群圈选”需求,用于广告投放、私域推送、AB实验、推荐策略。背后的圈选系统必须支持灵活组合、实时计算、千万级处理。本篇我们将带你构建一个简化版标签圈选引擎,覆盖标签逻辑表达 → 用户匹配计算 → 圈选结果生成全流程。
🧠 一、人群圈选系统的典型场景
| 场景 | 举例 |
|---|
| 精准广告投放 | 圈出“高消费意愿 + 特定品类兴趣”的人群 |
| 用户分层运营 | 根据用户行为进行等级划分,触发不同运营策略 |
| 私域推送 | 找到“活跃高价值用户”,分批发送微信/短信 |
| 推荐系统干预 | 给“未完成引导页的新用户”定制内容分发逻辑 |
🏗️ 二、字节圈选系统的架构流程(简化)
+-------------------+
| 标签体系(TDS) |
+-------------------+
↓
+------------------------+
| 圈选表达式引擎(DSL) |
+------------------------+
↓
+------------------------+
| 实时计算引擎(Flink) |
+------------------------+
↓
+------------------------+
| 圈选结果缓存 + 查询接口 |
+------------------------+
⚙️ 三、实战:构建简化版标签圈选引擎(Node.js 示例)
1. 定义标签字段及其支持的值
const userProfiles = [ { uid: 'u001', os: 'iOS', city: '广州', views: 8, tags: ['财经', '科技'] },
{ uid: 'u002', os: 'Android', city: '北京', views: 3, tags: ['搞笑'] },
{ uid: 'u003', os: 'iOS', city: '广州', views: 12, tags: ['财经'] },
];
2. 圈选表达式解析(可扩展为 DSL)
function match(user, query) {
return (
user.os === query.os &&
user.city === query.city &&
user.views >= query.minViews &&
user.tags.includes(query.tag)
)
}
const query = {
os: 'iOS',
city: '广州',
minViews: 5,
tag: '财经'
}
const result = userProfiles.filter(u => match(u, query))
console.log("圈选结果:", result.map(u => u.uid))
✅ 输出:['u001', 'u003']
🔍 四、工程化场景的进阶能力
| 能力 | 字节实现方式 |
|---|
| 标签系统接入 | 支持画像标签、兴趣标签、内容互动标签(TDS) |
| 圈选 DSL | 用户可视化圈选器 → 转为 SQL/DSL 表达式 |
| 实时圈选 | 接入 Flink + 实时标签流 + BloomFilter |
| 圈选缓存 | Redis + HBase 缓存圈选结果,供下游系统调用 |
| 圈选校验 | 支持样本导出 + 相似人群对比分析 |
🧬 五、推荐系统/广告投放如何用圈选?
| 用途 | 场景 |
|---|
| 精准曝光 | 只给“兴趣在科技且过去一周活跃”的用户展示某广告 |
| 冷启动内容 | 找“兴趣未知、首次登录”的人群做策略干预 |
| 渠道归因 | 圈出“从抖音企业号进入并下单”的人群做 ROI 分析 |
| AB实验流量 | 精准圈出“满足某特征组合”的实验目标人群 |
✍️ 六、总结与思考
- 圈选系统 = 标签体系 + 表达式引擎 + 实时计算 + 缓存服务
- 字节跳动的圈选平台支持亿级人群在秒级圈出 + 多系统无缝调用
- 小团队完全可以用 JSON 表达式 + Node.js/SQL + Redis 构建“轻量级圈选平台”
🎁 拓展阅读推荐
- 字节跳动《精准人群圈选系统架构分享》视频讲座
- 腾讯云:人群圈选平台建设白皮书
- Flink 实时特征圈选处理场景实录(含 SQL 示例)