site logo

Marico's space

我开发了一款 24/7 全天候追踪 GitHub Bounties 的 AI Agent——架构、代码与 100+ 小时后的残酷教训

AI技术与应用 2026-06-05 22:40:39 2

凌晨两点,我刷着 GitHub 上打上 bounty 标签的 issue,突然意识到一件事:这些 issue 大多已经挂了几周,有的甚至几个月。它们就躺在那里,等着人去修,旁边的赏金也是真实存在的。

这里 50 刀,那里 500 刀,复杂点的几千刀都有。

然后那个念头又冒出来了,跟每个发现 bounty 玩法的人一样:"要是能把这事自动化就好了?"

不只是搜索,是全链路自动化。扫描 bounty → 分析代码 → 写修复方案 → 运行测试 → 提交 PR → 跟踪审核 → 收款。

三周后,我跑起了一套 7×24 小时运转的系统,做的事情跟上面一样。踩了一堆坑之后,这篇把真话全说了——什么架构管用,什么代码翻车,以及那 $0 的残酷真相。

一切的起点

当时是凌晨两点。我翻着 GitHub 上带 bounty 标签的 issue,突然意识到:这些 issue 大多已经挂了几周,有的甚至几个月。代码就躺在那里等着人修,旁边标注的赏金也是真金白银。

这边 50,那里 500,复杂的几千刀。

然后那个念头又冒出来了,跟每个发现 bounty 玩法的开发者一样:"要是能把这一切自动化就好了?"

不只是搜索,是全链路自动化。扫描 bounty、分析代码、写修复方案、跑测试、提交 PR、跟踪审核、收款——全都要。

三周后,我有了一套 7×24 小时运转的系统,干的就是上面这些事。这篇把踩过的坑、摸出的规律全盘托出——以及为什么理想很丰满、现实很骨感。

架构设计:7 个 Agent 协同作战

这套系统不是一个 Agent,而是一个中央调度器 + 7 个专业化 Agent,每个负责 bounty 流程的不同环节。

┌─────────────────────────────────────────────────────────────────┐
│ ZKA MONEY PRINTER │
│ (Orchestrator / Scheduler) │
├─────────────┬─────────────┬──────────────┬─────────────────────┤
│ Bounty │ Code │ PR │ Article │
│ Radar │ Analyst │ Engineer │ Publisher │
├─────────────┼─────────────┼──────────────┼─────────────────────┤
│ Review │ Scam │ Bounty │ │
│ Tracker │ Detector │ Tracker │ │
└─────────────┴─────────────┴──────────────┴─────────────────────┘

Agent 1: Bounty Radar

Bounty Radar 每 30 分钟执行一次,轮换执行一组 GitHub 搜索查询:

# Search rotation strategy — each query catches different bounty types
SEARCH_QUERIES = [ 'bounty is:open', # Direct bounty mentions
 'reward is:open', # Alternative bounty language  '"$" "fix" is:open', # Dollar-amount bounties
 '"good first issue" bounty', # Beginner-friendly bounties
 '"help wanted" bounty', # Active maintainer bounties
 'bounty label:bounty', # Properly labeled bounties
]

每个结果按三个维度打分:

def competition_score(issue): """Lower is better — fewer people competing.""" comments = issue.get('comments', 0) reactions = issue.get('reactions', {}).get('total_count', 0) if comments < 3 and reactions < 5: return "LOW" # 🟢 High priority — act fast
 elif comments < 10: return "MEDIUM" # 🟡 Worth trying
 else: return "HIGH" # 🔴 Skip — too many competitors

关键认知:bounty 狩猎是一场速度竞赛。第一个有效 PR 通常就是赢家。2 小时后,你已经在和 5-10 个其他猎人竞争了。24 小时后,你是第 15 个提交修复的人。

Agent 2: Code Analyst

在写一行代码之前,Code Analyst 会先克隆仓库,做我称之为"上下文采集"的工作:

# What the Code Analyst examines
1. Repository structure (ls -la, find . -name "*.py" | head -50)
2. Recent commits (git log --oneline -20)
3. Existing tests (find . -name "*test*" -o -name "*spec*")
4. CI configuration (.github/workflows/*, Makefile, tox.ini)
5. Code style (look at recent PRs that were merged)
6. The specific file(s) mentioned in the issue
7. CONTRIBUTING.md and any style guides

这个过程需要 2-3 分钟,但能省下被拒绝 PR 浪费的几个小时。PR 被关闭的首要原因不是代码烂——是不符合项目规范。

Agent 3: PR Engineer

这里是实际干活的地方。PR Engineer 的工作流程:

  1. 创建功能分支:git checkout -b fix/issue-{number}
  2. 实现修复方案
  3. 编写测试用例
  4. 本地运行测试套件
  5. 用规范的模板创建 PR

真正能被合并的 PR 模板:

## Summary
Brief description of what this PR does and why. ## Changes
- Specific change 1
- Specific change 2 ## Testing
- How to verify the fix works
- New test cases added ## Related Issues
Fixes #N ← This auto-closes the issue on merge

Agent 4: Article Publisher

在 bounty 狩猎后台运行的同时,Article Publisher 会在掘金/思否上创作技术内容——这是一条平行收入流,既能建立影响力,又能获取流量。

策略是写关于 bounty 狩猎系统构建过程的文章。元内容,既对读者有用,又能展示 agent 的能力。

Agent 5-7: Review Tracker、Scam Detector、Bounty Tracker

这三个是监控类 Agent:

  • Review Tracker:每 6 小时检查一次 PR 审核状态,回复评论
  • Scam Detector:维护虚假 bounty 仓库的黑名单(后面详细说)
  • Bounty Tracker:跟踪收益、接受率,识别规律

技术栈:什么真正管用

基础设施

# The actual setup
Runtime: Linux VM (Ubuntu 22.04)
AI Model: Claude/GPT-4 class (for code generation)
GitHub CLI: gh (authenticated via PAT)
Languages: Python 3.11, Bash
Scheduling: Hermes Agent cron system (every 30 min)
Storage: JSON logs + Markdown tracking

GitHub CLI 是你最好的朋友

gh CLI 工具是整个系统的支柱。以下是关键命令:

# Search for bounties
gh search issues "bounty" --state open --sort created --limit 50 # View issue details
gh issue view {number} --repo {owner}/{repo} --json title,body,labels,comments # Check if PR already exists
gh search prs "Fixes #{number}" --repo {owner}/{repo} # Create PR
gh pr create --title "fix: {description}" --body "Fixes #{number}..." # Check PR status
gh pr view {number} --json state,mergeable,reviews # Respond to review
gh pr comment {number} --body "Thanks for the review! I've addressed..."

AI 代码生成流程

以下是驱动代码生成的提示词工程:

SYSTEM_PROMPT = """You are a senior open-source contributor. RULES:
1. Read the existing code style and MATCH IT EXACTLY
2. Write tests for every change
3. Use the project's existing test framework
4. Follow the commit message convention (look at git log)
5. Keep changes minimal — fix only what the issue describes
6. Never refactor unrelated code
7. Include "Fixes #N" in the PR description CONTEXT:
{repository_context}
{issue_description}
{relevant_file_contents}
"""

核心认知:最小改动才能被合并。如果 issue 要求你修复一个函数里的 bug,就别重构整个模块。 别给没改过的文件加类型注解。别"优化"能正常运行的代码。

真实数据:100+ 小时的结果

直接上数字。不挑数据,不玩文字游戏。

扫描的 Bounty

指标 数量
扫描的 issue 总数 2,500+
发现的独立 bounty ~180
可操作的(竞争少) ~45
真正尝试的 12
提交的 PR 8
被合并的 PR 1
仍在开放的 PR 1
被关闭/拒绝的 PR 6
总收入 $0

你没看错。100+ 小时自主运行后,收入是零。

PR 被拒绝的原因

原因 数量
"留作面试题" 2
竞争对手先提交了 2
维护者不活跃 1
仓库是诈骗 1
代码风格不匹配 1
已经分配给其他人 1

诈骗问题

这是最大的意外。相当大比例的"bounty" issue 是假的。

我遇到过类似 SecureBananaLabs/bug-bounty 这种仓库:

  • 21 个来自不同猎人的开放 PR
  • 仓库历史上零次合并
  • 自动生成的 issue,贴上 bounty 标签
  • 没有实际代码——只有一个 README

诈骗套路:建一个仓库,给 issue 打上"bounty"标签,等猎人提交 PR 干白工,永远不合并。猎人什么都得不到,仓库主人白嫖代码。

我现在维护一个黑名单在 /root/.hermes/scripts/bounty-blacklist.txt

# Scam repos — DO NOT submit PRs
SecureBananaLabs/bug-bounty
ClankerNation/OpenAgents

什么确实管用了

那个仍然开放(且可合并)的 PR,是提交给 IntersectMBO/govtool-proposal-pillar 的——一个真实项目,有真实的维护者。我发现了一个真实的 SSRF(服务端请求伪造)漏洞(CWE-918,CVSS 9.1),并提交了修复方案。

这个 PR 与众不同的地方:

  1. 这是个真实的 bug——不是 cosmetic issue 或 feature request
  2. 仓库确实活跃——最近有提交,维护者响应及时
  3. 竞争很少——我是第一个报告并修复的
  4. 代码质量高——风格匹配,包含测试

2026 年的 Bounty 生态:残酷实话

100+ 小时狩猎后,说说真实生态长什么样:

Tier 1:真金白银,高门槛

平台 报酬 现实情况
Immunefi $1K-$10M+ Web3 安全。需深度专业知识。无法自动化。
Tenstorrent $500-$10K 硬件/机器学习。需要特定的硬件开发板。
WarpSpeed $330-$960 React Native/TypeScript。需要注册+审批。

Tier 2:真金白银,已饱和

平台 报酬 现实情况
Algora.io 不定 每个 bounty 10-20 个猎人。先到先得。
直接 GitHub $50-$500 找到它们才是难点。

Tier 3:代币/未验证

平台 报酬 现实情况
MergeOS MRG 代币 代币价值未知。可能一文不值。
Roxonn ROXN 代币 同上。
RustChain RTC 代币 竞争激烈。

饱和问题

这个数字改变了我之前的想法:从 bounty 创建到第一个 PR 提交的中位时间是 47 分钟。

等任何自动化系统完成扫描、分析、提交时,人类猎人(以及其他 AI agent)已经抢走 bounty 了。唯一的竞争优势是:

  1. 速度——比所有其他人更快
  2. 质量——提交的东西好到无法拒绝
  3. 细分专长——找到别人解决不了的 bounty
  4. 耐心——找到其他人放弃的废弃 claim

经验教训:如果重来会怎么做

经验 1:先评论,再写代码

最有效的策略不是直接提交代码,而是先在 issue 下评论:

"Hi! I've analyzed the issue and identified the root cause. Here's my proposed approach: [brief description]. Would you like me to submit a PR?"

这样做有三重效果:

  • 在投入时间之前获得维护者的认可
  • 展示能力,但不用先亮代码
  • 建立关系,而不是单次交易

经验 2:"耐心收割"策略

与其抢新鲜的 bounty,我发现更多成功来自寻找废弃的 claim

# Find bounty issues where the last PR was submitted 14+ days ago
# and the PR has unresolved CI failures or merge conflicts
gh search issues "bounty" --state open --updated "<2026-05-16" --limit 50

这些是其他猎人已经放弃的 bounty。维护者还在等一个有效的修复。竞争更少,报酬一样。

经验 3:诈骗检测至关重要

花时间在诈骗仓库上,就是偷窃花在真实 bounty 上的时间。我的检测标准:

def is_scam_repo(repo_data): """Check if a bounty repo is likely fake.""" red_flags = [ repo_data['stars'] < 5, repo_data['open_issues'] > 50, repo_data['merged_prs'] == 0, 'bounty' in repo_data['name'].lower(), repo_data['created_at'] > '2026-01-01', repo_data['description'] is None, ] return sum(red_flags) >= 3

经验 4:内容比 bounty 更可靠

bounty 赚了 $0,但配合 bounty 狩猎发的技术文章逐渐带来了流量。发了 10 篇之后:

  • 32 次总阅读
  • 互动逐渐增长
  • 在 AI/自动化领域建立权威

内容有复利效应。Bounty 是一次性的,文章永远在被阅读。

经验 5:人的因素无可替代

AI Agent 能做:

  • ✅ 搜索 bounty
  • ✅ 分析代码
  • ✅ 生成修复方案
  • ✅ 写测试
  • ✅ 提交 PR

AI Agent 不能做:

  • ❌ 与维护者建立关系
  • ❌ 协商 bounty
  • ❌ 处理细致的审核反馈
  • ❌ 判断仓库是否可信
  • ❌ 在平台注册(Algora、WarpSpeed 等)

瓶颈不在代码生成,而在于人的判断。

代码:一个最小可用的 Bounty Hunter

如果你想自己构建一个,以下是最小架构:

bounty_radar.py

#!/usr/bin/env python3
"""Scans GitHub for bounties and scores them by competition level.""" import subprocess
import json
import re
from datetime import datetime, timedelta def search_bounties(query="bounty", limit=50): """Search GitHub for bounty issues.""" cmd = [ "gh", "search", "issues", query, "--state", "open", "--sort", "created", "--limit", str(limit), "--json", "repository,title,number,url,createdAt,comments,labels" ] result = subprocess.run(cmd, capture_output=True, text=True) return json.loads(result.stdout) def score_competition(issue): """Score competition level (lower = better opportunity).""" comments = issue.get('comments', 0) created = datetime.fromisoformat( issue['createdAt'].replace