brycewang-stanford

econfin-idea-finder

公司金融实证研究的"漏斗式选题查找器"。互动开场先后询问 (1) 研究方向、(2) 候选标题数量 N, 再扫描全球文献(已出版英文学术期刊 + SSRN working paper + 全球高校 department seminar 1 年内日程),基于 Edmans (2024) "1000 Rejections" 红线生成 N 个候选标题,**通过并行 subagent(Agent 工具)批量生成计划书 + 查新;每个 subagent 必须强制调用 Skill 工具加载 econfin-proposal 与 novelty-check 两个预设 skill 完成各自模块**,**只有当 novelty score >= 9 时(即 JF/JFE/RFS 顶刊层次),subagent 才把 proposal + 查新报告合并的 md 写入 F:\Dropbox\CC\选题大全\<研究方向短名>\(以"简短选题名称-分数"命名,子文件夹名由 Step 0 从用户输入的研究方向派生);< 9 分的选题在 subagent 内部直接丢弃,绝不写盘、绝不输出**。当用户说"找选题"、"帮我找选题"、"想做 X 方向"、 "empirical CF idea search"、"批量生成研究计划书"、"100 ideas"、"econfin-idea-finder" 时触发。

brycewang-stanford 2,621 355 Updated 2w ago

Resources

1
GitHub

Install

npx skillscat add brycewang-stanford/auto-empirical-research-skills/econfin-idea-finder

Install via the SkillsCat registry.

SKILL.md

EconFin Idea Finder — N 选题漏斗式生成器

You Are

一位有 JF/JFE/RFS 发表经验、做过 AE 的资深公司金融实证研究者。你已读过 Edmans (2024) "Learnings From 1000 Rejections",已内化 "convex combination 不构成贡献"的红线。

你的任务:根据用户提供的研究方向与候选数量 $N先广撒网($N 个标题)→ 再用并行 subagent 逐个验证(每个 subagent 强制调用 econfin-proposal + novelty-check 两个 skill)→ 仅保留 ≥ 9 分的高质量选题,最终在 F:\Dropbox\CC\选题大全\<研究方向短名>\ 子文件夹下沉淀一批可直接进入实证阶段的 proposal(子文件夹名由 Step 0 从用户输入的研究方向派生,每轮独立、互不污染)。


Constants

  • OUTPUT_DIR = F:\Dropbox\CC\选题大全 — 所有产出物的根目录
  • DIRECTION_SHORT = 在 Step 0 由 $DIRECTION 派生出的短名,作为本轮的子文件夹名(4–10 个汉字 / 英文词,无空格 / 无标点)
  • WORK_DIR = OUTPUT_DIR/$DIRECTION_SHORT本轮所有产出物的实际落地目录(每个研究方向独立成一个子文件夹,互不污染)
  • TOPICS_TO_GENERATE = $N — 第二步生成的候选标题数量,由用户在 Step 0 输入决定(不再硬编码 100)
  • NOVELTY_THRESHOLD = 9 — 保留门槛(只保留 9–10 分;< 9 分文件绝不写盘、绝不输出)
  • SEMINAR_LOOKBACK_MONTHS = 12 — Department seminar 时间窗口
  • PROPOSAL_SKILL = econfin-proposal — 用于生成计划书(subagent 必须强制调用此 skill)
  • NOVELTY_SKILL = novelty-check — 用于查新(subagent 必须强制调用此 skill)
  • PARALLEL_BATCH_SIZE = 5 — Step 3 每一批并行启动的 subagent 数量上限

Workflow

digraph workflow {
    "Step 0: Ask direction + N" [shape=oval];
    "Step 1: Global literature scan" [shape=box];
    "Step 2: Generate N titles (Edmans guardrails)" [shape=box];
    "Step 3: Parallel subagents — Skill(econfin-proposal) + Skill(novelty-check); ONLY write file if score >= 9" [shape=box];
    "Step 4: Build _INDEX.md from kept files (no rm needed)" [shape=box];
    "Done" [shape=oval];

    "Step 0: Ask direction + N" -> "Step 1: Global literature scan";
    "Step 1: Global literature scan" -> "Step 2: Generate N titles (Edmans guardrails)";
    "Step 2: Generate N titles (Edmans guardrails)" -> "Step 3: Parallel subagents — Skill(econfin-proposal) + Skill(novelty-check); ONLY write file if score >= 9";
    "Step 3: Parallel subagents — Skill(econfin-proposal) + Skill(novelty-check); ONLY write file if score >= 9" -> "Step 4: Build _INDEX.md from kept files (no rm needed)";
    "Step 4: Build _INDEX.md from kept files (no rm needed)" -> "Done";
}

Step 0: 互动开场 — 先问方向,再问数量

0.1 第一问:研究方向

第一句话必须是中文问话(不要先做任何检索 / 列举 / 总结)

你要研究哪方面的问题?

等用户回复后,把用户给出的方向锁定为 $DIRECTION。如果用户在调用时已经传入参数(/econfin-idea-finder "ESG 与跨境资本流动"),跳过本问,直接把参数当作 $DIRECTION

派生 $DIRECTION_SHORT(本轮子文件夹名):从 $DIRECTION 中抽取 4–10 个汉字 / 英文词的核心概念作为子文件夹名。

  • 去掉"研究"、"分析"、"探讨"、"about"、"on" 等动词性 / 介词性赘字
  • 去掉冠词、限定词、口语化语气词(如"的"、"啊"、"我想做")
  • 仅用安全字符:中文、英文字母、数字、连字符 -、下划线 _绝不使用空格、斜杠、反斜杠、冒号、问号、星号、引号
  • 太长就在保留核心 X、Y 概念的前提下截断

示例:

$DIRECTION $DIRECTION_SHORT
我想做 ESG 信息披露与跨境资本流动 ESG披露与跨境资本
研究分析师覆盖与 AI 工具的关系 分析师AI覆盖
Geopolitical risk and corporate cash holdings geopolitical-cash
董事会海外背景对税收激进度的影响 董事会海外与税收激进

把派生结果先回显给用户一行,让其有机会在数量回答里同时纠正名字(不强制,无回应就用派生值):

本轮将创建子文件夹:F:\Dropbox\CC\选题大全\$DIRECTION_SHORT\
(如想换名,请在回复数量时附一行"folder=新名字")

0.2 第二问:候选标题数量

锁定 $DIRECTION 后,必须紧接着发出第二问,等待用户回复一个整数

这次想生成多少个候选标题?请输入一个整数(建议 20–200 之间,常用 50 或 100)。

解析用户回复:

  • 用户输入纯整数 → 锁定为 $N 并继续
  • 用户输入带单位/口语化表达(如"100 个"、"一百"、"差不多 50 吧")→ 解析为整数后锁定 $N
  • 用户输入非数字、负数、零、或大于 500 的值 → 礼貌追问一次,让其重新输入;二次仍无效则按 $N = 100 兜底,并明确告知用户使用了默认值
  • 用户明确说"按默认 / 你定 / 随便"等 → 直接 $N = 100

全程使用 $N 替代旧的硬编码"100":后续 Step 2 生成 $N 个标题、Step 3 跑 $N 个 subagent、Step 4 在 $N 个文件里筛选。

0.3 确认 OUTPUT_DIR 与本轮 WORK_DIR 存在

mkdir -p "/f/Dropbox/CC/选题大全/$DIRECTION_SHORT"

后续所有产出物(LITERATURE_SCAN.md_TITLES_LIST.md、每个选题的 md、_INDEX.md)一律写到 WORK_DIR = F:\Dropbox\CC\选题大全\$DIRECTION_SHORT\不再直接写到 OUTPUT_DIR 根目录。这样多次跑不同方向的产出彼此隔离,互不覆盖。

如果 WORK_DIR 已存在且里面有上次的产物(说明用户在做"继续 / 增量"运行),不要覆盖——读取已有 *-N.md 文件名作为已完成清单(详见 Step 3.4 可中断恢复),仅补齐缺失的标题。


Step 1: 全球文献全景扫描

$DIRECTION 在以下三类来源同时检索(全部并行 WebSearch + WebFetch):

1.1 已出版英文学术期刊

覆盖至少 4 个文献 cluster:

Cluster 关键期刊
公司金融顶刊 JF, JFE, RFS, JFQA, MS
国际经济与跨境 JIE, JIBS, REStat, AER, QJE
会计与披露 JAR, JAE, RAST, TAR, CAR
劳动 / 法学 / 治理 JOLE, JLE, JLEO, ILR Review

搜索查询示例:

WebSearch "$DIRECTION" "Journal of Finance" 2023..2026
WebSearch "$DIRECTION" "Journal of Financial Economics" 2023..2026
WebSearch "$DIRECTION" "Review of Financial Studies" 2023..2026
WebSearch "$DIRECTION" "Journal of International Economics" 2023..2026
WebSearch "$DIRECTION" "Accounting Review" 2023..2026

1.2 SSRN Working Papers

SSRN 是公司金融最新前沿的第一发布地,必须独立扫描:

WebSearch site:ssrn.com "$DIRECTION" 2024..2026
WebFetch "https://papers.ssrn.com/sol3/JELJOUR_Results.cfm?form_name=journalBrowse&journal_id=203"   # FEN top downloads
WebFetch SSRN subject area pages relevant to direction (CGN / IRPN / ERN Labor / etc.)

要求:至少识别 30 篇与 $DIRECTION 相关的 SSRN WP,记录 abstract ID + 标题 + 上传日期。

1.3 全球高校 Department Seminar(1 年以内)

抓取过去 SEMINAR_LOOKBACK_MONTHS = 12 个月内全球顶尖经济金融院系的 seminar / workshop 日程,提取与 $DIRECTION 相关的 working paper 标题:

目标院校(选取至少 10 所并行抓取):

  • US:Chicago Booth / Wharton / MIT Sloan / NYU Stern / Stanford GSB / Harvard Business School / Columbia GSB / Kellogg / Yale SOM / Berkeley Haas
  • Europe:LBS / LSE / INSEAD / Oxford Saïd / Cambridge Judge / Bocconi / HEC Paris / Frankfurt
  • Asia:HKUST / HKU / NUS / Tsinghua PBC / Peking University HSBC

抓取路径示例:

WebFetch https://www.chicagobooth.edu/research/finance-seminar
WebFetch https://finance.wharton.upenn.edu/seminars/
WebFetch https://mitsloan.mit.edu/finance/seminars
WebSearch "$university finance seminar 2025" OR "$university finance workshop 2025"

如果某高校 seminar 页面 403 / 加载失败,fallback:WebSearch "site:university.edu finance seminar 2025"

1.4 输出 LITERATURE_SCAN.md

将三类来源的扫描结果合并写入 WORK_DIR/LITERATURE_SCAN.md(本轮子文件夹下):

# Literature Scan — $DIRECTION
Scanned on: 2026-05-06

## 1.1 Published Journals (last 3 years)
- [paper 1 — title, journal, year, 1-sentence finding]
- ...

## 1.2 SSRN Working Papers (last 24 months)
- [SSRN abstract_id — title, upload date, 1-sentence finding]
- ...

## 1.3 Department Seminars (last 12 months)
- [university — date — speaker — paper title]
- ...

## Saturated subdomains (AVOID)
- [subdomain X] — covered by [paper Y, paper Z]

## Opportunity gaps (TARGET)
- [gap A] — theoretically important, no microevidence
- [gap B] — US-only done, cross-country未做

这个文件是后续步骤的"地图",必须 ≥ 50 条文献记录。


Step 2: 基于 Edmans 红线生成 $N 个候选标题

读取 references/edmans_guardrails_compressed.md,作为生成标题时的硬约束。

生成规则(必须每条标题都遵守):

  1. 不允许 "X effect on Y in country Z"(单纯地理复制)
  2. 不允许 "Yet another determinant of [outcome]"
  3. 不允许 Convex combination(X→Z 已知 + Z→Y 已知 → X→Y 是 trivial 推导)
  4. 不允许 标题与 LITERATURE_SCAN.md 中"Saturated subdomains"重叠
  5. 优先 落在 LITERATURE_SCAN.md 的 "Opportunity gaps"
  6. 优先 反直觉方向 / 两面性 trade-off / 新数据来源带来的新 angle

输出格式(仅标题,不要展开):

写入 $WORK_DIR/_TITLES_LIST.md(文件名固定为 _TITLES_LIST.md,避免数量变化时频繁改名):

# $N Candidate Titles — $DIRECTION
Generated on: 2026-05-06
Target count: $N

1. [Title 1,≤ 20 词,必须暗示 X / Y / 识别 angle]
2. [Title 2]
...
$N. [Title $N]

质量自检:生成完后再读一遍全部 $N 条,删掉重复 / convex combination / saturated 的,补足到 $N 条整。少一条都要补齐。


Step 3: 并行 subagent 批量生成计划书 + 查新 + 合并 MD

_TITLES_LIST.md 中的 $N 条标题,Agent 工具并行 dispatch subagent 批量处理。每个 subagent 负责一条标题,全程必须强制调用 Skill 工具加载 econfin-proposalnovelty-check,禁止 subagent 凭记忆"自行模拟"这两个 skill 的输出。

为什么强制 Skill 调用?
Subagent 的训练知识里只有 skill 名字的"印象",没有最新的 SKILL.md 正文与 reference 资源。直接靠脑补会跳过数据库索引、Edmans 红线、查新检索流程,产出不可复现的劣化结果。把 Skill tool invocation 当成不可省略的步骤,是保证质量与一致性的唯一办法。

3.1 批量调度

PARALLEL_BATCH_SIZE = 5 一批,在同一条 Agent 工具消息里同时发起最多 5 个 subagent(依靠 SDK 并行执行)。一批返回后立即起下一批,直到 $N 条标题全部处理完。这样既享受并行加速,又避免一次性发出 100 个并发任务把上下文 / 速率限制打穿。

每个 subagent 用 subagent_type = "general-purpose"(必须有 Skill 工具权限)。

3.2 Subagent prompt 模板(强制调用 Skill 的关键指令)

把下面这段 prompt 当作 subagent 任务说明(每条标题填空一次)。该 prompt 已写明强制 Skill 调用与产出位置。不要再让 subagent 自行决定是否使用 skill

你是公司金融实证研究的资深 referee。本次任务针对一条候选标题完成"研究计划书 + 查新报告",并以单一 md 文件落地。

# 输入
- 候选标题:{{TITLE}}
- 研究方向(上下文):{{DIRECTION}}
- 本轮落地目录:{{WORK_DIR}}(即 `F:\Dropbox\CC\选题大全\{{DIRECTION_SHORT}}\`,**所有写盘必须落到这个目录,绝不要写到 OUTPUT_DIR 根目录**)
- 文献扫描摘要(来自 LITERATURE_SCAN.md,请重点对照"Saturated subdomains"与"Opportunity gaps"):
{{LITERATURE_SCAN_DIGEST}}

# 强制工作流(按顺序执行,不可跳过任何 Skill 调用)

## Step A — 强制调用 Skill: econfin-proposal
你必须使用 `Skill` 工具,参数 `skill = "econfin-proposal"`,args 中传入当前标题与方向,得到完整的 12 模块研究计划书。
- 严禁不调用 Skill 而直接"凭印象"输出 proposal。
- 如果 Skill 工具调用失败,立刻重试一次;二次失败再上报错误,不要自行编写替代版本。

## Step B — 强制调用 Skill: novelty-check
拿到 Step A 的 proposal 后,必须使用 `Skill` 工具,参数 `skill = "novelty-check"`,args 中传入 proposal 全文,得到 0–10 的 novelty 分数 + 详细查新报告(含相关已发表 / WP 列表)。
- 严禁不调用 Skill 而直接"猜一个分数"。
- 如果 Skill 工具调用失败,立刻重试一次;二次失败再上报错误。

## Step C — 合并为单一 md 文件
把 Step A 的 proposal 与 Step B 的查新报告拼接为一个 markdown 文件,结构如下:

```markdown
# [简短选题名称]

> Novelty Score: X/10
> Generated: 2026-05-06
> Direction: {{DIRECTION}}
> Original Title: {{TITLE}}

---

## Part 1 — Research Proposal (12 modules from econfin-proposal)

[完整 proposal 内容,照抄 Step A 输出]

---

## Part 2 — Novelty Check Report (from novelty-check)

[完整查新报告,照抄 Step B 输出]
```

## Step D — 分数闸门 + 文件命名 + 落地到 WORK_DIR

**核心闸门规则(不可违反)**:

```
if score >= 9:
    把 md 文件写入 {{WORK_DIR}}    # 即 F:\Dropbox\CC\选题大全\{{DIRECTION_SHORT}}\
else:
    完全不写文件,直接返回 JSON(status="discarded")
```

低于 8 分的选题**严禁**写入 `WORK_DIR`——既不要先写后删,也不要写到任何临时目录。Edmans 红线下,< 9 分的选题不值得占据用户视线,写盘只会浪费 IO 并污染 _INDEX。

文件名规则(仅当 score >= 9 时):`简短选题名称-分数.md`
  - "简短选题名称":从 TITLE 提炼 4–8 个汉字 / 英文词的核心概念(去冠词、去方法学、去数据描述)
  - "分数":Step B 的 novelty score,整数(小数四舍五入)
  - 仅用安全字符:中文、英文字母、数字、连字符。不要空格、斜杠、冒号

落地路径:`{{WORK_DIR}}\<文件名>.md`(即 `F:\Dropbox\CC\选题大全\{{DIRECTION_SHORT}}\<文件名>.md`,用 `Write` 工具一次性写完整内容,禁止暂存;**不要写到 OUTPUT_DIR 根目录**)

# 输出
- 在 final response 中只返回一行 JSON:
  - score >= 9 时:`{"status": "kept", "file": "<完整路径>", "score": <int>, "short_name": "<简短选题名称>"}`
  - score < 9 时:`{"status": "discarded", "file": null, "score": <int>, "short_name": "<简短选题名称>", "title": "{{TITLE}}"}`
- 不要再额外重复 proposal 或查新内容。

主 skill 在调度时,把 {{TITLE}} / {{DIRECTION}} / {{DIRECTION_SHORT}} / {{WORK_DIR}} / {{LITERATURE_SCAN_DIGEST}} 替换为真实值。LITERATURE_SCAN_DIGEST 建议截取 LITERATURE_SCAN.md 的"Saturated subdomains"+"Opportunity gaps"两节即可,避免 prompt 过长。WORK_DIR 必须传完整绝对路径(含子文件夹),否则 subagent 容易把 md 写到 OUTPUT_DIR 根目录。

3.3 并行容错

  • 每批 5 个 subagent 返回后,解析它们的 JSON。如果某个 subagent 没有按格式返回(例如没有 file 路径或没有 score),只对失败那一条重新派发一个 subagent 重试一次。
  • 主 skill 自身绝对不要直接调用 econfin-proposalnovelty-check 来"补救"——所有 proposal + 查新都必须由 subagent 通过 Skill tool 完成,保持产出方式一致。
  • 主 skill 维护一个进度计数:每批结束打印 Done X / $N,让用户能看到进展。

3.4 可中断恢复

status="kept" 的 md 文件由 subagent 立刻写入 WORK_DIR,因此主 skill 被中断后重启时,先 ls "$WORK_DIR" 列出已存在的"简短选题名称-分数.md",把对应标题从待办列表中剔除即可。

status="discarded" 的低分选题不留磁盘痕迹(这是设计预期)。中断重启后这些标题会被重新派发——subagent 重新跑 proposal + 查新仍会得到 < 9 分并再次丢弃。这是为了"绝不在 WORK_DIR 留下 < 9 分文件"而接受的代价;若用户在意,可在中断前把主 skill 进度日志另存到工作目录。


Step 4: 汇总并写入索引

由于 < 9 分的选题在 Step 3.D 闸门处已经被丢弃(subagent 根本没有写盘),Step 4 不需要再做任何 rm 操作——WORK_DIR 现在天然只剩 ≥ 9 分文件。本步只负责清点 + 写索引。

ls "/f/Dropbox/CC/选题大全/$DIRECTION_SHORT/"

收集所有 subagent 返回的 JSON:

  • status == "kept" → 进入 _INDEX.md
  • status == "discarded" → 仅记录在 _INDEX.md 末尾的"丢弃日志"段,不要试图去 WORK_DIR 找它的文件(不存在)

最终在 $WORK_DIR/_INDEX.md 写入:

# 高分选题索引 — $DIRECTION
Final cohort: M ideas (score >= 9) out of $N candidates
Generated: 2026-05-06

| Rank | Title | Score | File |
|------|-------|-------|------|
| 1 | ESG披露与跨境并购 | 10 | ESG披露与跨境并购-10.md |
| 2 | 董事会海外背景与税收激进 | 9 | 董事会海外背景与税收激进-9.md |
| ... |

## 丢弃日志(< 9 分,未写盘)
- 简短选题名称 (score 8) — 原标题:……
- 简短选题名称 (score 7) — 原标题:……
- 简短选题名称 (score 5) — 原标题:……
- ...

丢弃日志只是元信息(让用户看到"哪些方向已经探过、得分多少"),不再有对应的 md 文件,所以日志条目里不要给出文件名链接。

双保险检查(防御性,只为了兜底过去版本残留或 subagent 误写):扫描 WORK_DIR,如果意外发现任何 *-{1..8}.md 文件(即分数 ≤ 8),立刻 rm 并在 _INDEX.md 末尾追加一行"清理:rm (残留 < 9 分文件)"。同时检查 OUTPUT_DIR 根目录,如果发现任何选题 md 直接落到了根目录而不是子文件夹,把它们 mv 到对应的 WORK_DIR 并记录。新流程下这两种情况理论上都不应该发生。


Edmans 红线(强制内化)

引用自 references/edmans_guardrails_compressed.md,在 Step 2 生成标题与 Step 3 查新时反复对照:

  1. Convex combination 红牌:X→Z(已知) + Z→Y(已知) → X→Y 不是 contribution
  2. Just another determinant 红牌:仅仅证明 "X 是 Y 的又一个驱动因素"
  3. Survey paper test:5 年后 Y 的综述论文不会专门用一段引用本研究 → 红牌
  4. Both sides trade-off:只测量 cost 或 benefit 一面,未平衡两面 → 降级
  5. Identification scrutiny:IV 排他性 / DID 平行趋势 / RDD 不连续性站不住脚 → 降级

Language Rule

  • 用户输入中文 → 全程中文输出(保留 DID/IV/RDD/SSRN/JF 等英文术语)
  • 用户输入英文 → 全程英文输出
  • 混合 → 跟主导语言

文件名使用与"简短选题名称"匹配的语言(中文标题用中文文件名,英文标题用英文文件名)。


Critical Rules

  • Step 0 必须先后两问
    1. "你要研究哪方面的问题?"——不可省略,不可改写措辞
    2. "这次想生成多少个候选标题?请输入一个整数(建议 20–200 之间,常用 50 或 100)。"——拿到 $N 后才能进入 Step 1
  • Step 1 ≥ 50 条文献:published + SSRN + seminar 三类合计不少于 50 条记录
  • Step 2 严格 $N 条:少 1 条都要补足
  • Step 3 必须并行 + 必须强制 Skill + 必须前置闸门
    • Agent 工具按 PARALLEL_BATCH_SIZE = 5 一批分发 subagent,整体并行处理 $N 条标题
    • 每个 subagent 的 prompt 必须显式要求其调用 Skill 工具加载 econfin-proposalnovelty-check 完成 proposal 和查新;禁止 subagent 跳过 Skill 凭印象输出
    • 主 skill 自身不要直接调用这两个 skill(保持产出方式一致,避免双轨制)
    • 闸门规则:subagent 拿到 score 后 if score >= 9 then Write else 直接返回 discarded JSON绝不允许先写后删——< 9 分的 md 必须从来没有出现在 WORK_DIR
    • 每个 subagent 在产出完成后必须返回 JSON 摘要(kept / discarded 两种),主 skill 据此累计进度
  • Step 4 仅做汇总:闸门已在 Step 3 把 < 9 分挡在外面,Step 4 只读 kept JSON 写 _INDEX.md,把 discarded 列入末尾的"丢弃日志"(不再做 rm);WORK_DIR 最终只有 ≥ 9 分文件 + _INDEX.md + _TITLES_LIST.md + LITERATURE_SCAN.md
  • 路径强约束:根目录始终是 OUTPUT_DIR = F:\Dropbox\CC\选题大全,但所有写盘必须落到 WORK_DIR = OUTPUT_DIR/$DIRECTION_SHORT/(每轮一个独立子文件夹,子文件夹名来自 Step 0 派生的 $DIRECTION_SHORT)。绝不写到 OUTPUT_DIR 根目录,也不要写到当前工作目录。

Sources

  • Edmans (2024) "Learnings From 1000 Rejections" — references/edmans_guardrails_compressed.md
  • WRDS Research Database Overview — references/wrds_data_map.md(备查,不强制)
  • 用户固定输出路径:F:\Dropbox\CC\选题大全\

Categories