@nifinet: https://x.com/nifinet/status/2078851409068654639

X AI KOLs Timeline 工具

摘要

一份关于使用Codex构建自我改进外呼系统的指南:AI代理会读取历史结果、编辑评分和策略文件、运行测试,并生成拉取请求供人工审核。其核心理念是将上市策略逻辑视为版本化代码,通过市场反馈持续优化。

https://t.co/5OcZk7ZJF8
查看原文
查看缓存全文

缓存时间: 2026/07/20 21:32

如何基于 Codex 构建一个自我优化的外呼系统

今年早些时候,Andrej Karpathy(@karpathy)将一个智能体指向了自己的训练代码,并让它运行了两天。它执行了 700 个实验,保留了其中 20 个超过基准的,使模型训练速度提升了 11%。然后他说了一句很有意思的话:任何能够廉价评估的指标,都可以交给智能体集群来处理。回复率就是一个能够廉价评估的指标。

我花了一些时间,琢磨如何将这个循环瞄准外呼场景。我的构建方案是:Codex 读取上周的结果,编辑外呼系统运行时所用的评分和策略文件,运行一次测试,然后发起一个 Pull Request。它会附上证据和得分,提出对规则手册的修改,然后等待人工审批。发送和合并不在循环之内。

我曾经多次搭建过第一个循环:感知市场、对客户评分、根据信号撰写内容、检查消息、记录结果、从回复中学习。本文介绍的是第二个循环,即编辑第一个循环的那个循环。这个构建思路就是:将 GTM(市场推广)视为可版本化的代码,并且它会根据市场反馈不断改进。

Repo(代码仓库)

从文件夹开始。结构很重要,因为 Codex 只能改进它能读取和编辑的内容。

codex-self-improving-outbound/
  AGENTS.md
  README.md
  config/
    scoring.yaml
    plays.yaml
  prompts/
    improve_scoring.md
    improve_prompt.md
    pr_summary.md
  memory/
    outcomes.jsonl
  evals/
    fixtures.yaml
    score.py
  scripts/
    append_outcome.py
    run_codex_step.sh
    propose_improvement.py
    open_pr.sh
    weekly_tune.sh
  examples/
    outcomes.sample.jsonl
    weekly-pr.md

这个仓库特意保持简洁。config/scoring.yaml 保存决定哪些信号重要的规则。prompts/ 保存用于撰写消息的策略。memory/outcomes.jsonl 保存市场的反馈。evals/score.py 是一个门控机制,用来判断一个提议的修改是否有效。AGENTS.md 是 Codex 在触碰任何东西之前必须读取的法则。

先在本地离线运行第一个版本。不接入 CRM、不接入数据补充工具、不接入发送系统。改进循环应该先在本地文件上证明自己,然后才能接近真正的外呼机器。

第一步:先写好法则

在编写评分文件、提示文件之前,先写好 AGENTS.md。这个文件能让智能体既有用又受约束。

# 自优化外呼规则

你根据结果来优化外呼系统。

硬性规则:
- 绝不要发送消息。
- 绝不要爬取或补充真实用户数据。
- 绝不要自我合并。
- 只编辑此仓库内的文件。
- 一次只更改一个概念。
- 每个提议的更改都必须引用 memory/outcomes.jsonl 中的结果。
- 在更改成为 PR 之前,必须先改进 evals/score.py。
- 如果评估结果没有提升,撤销你的编辑并停止。

允许的编辑:
- config/scoring.yaml
- config/plays.yaml
- prompts/*.md

必需输出:
- 更改的文件
- 每个更改的理由
- 更改前的得分
- 更改后的得分
- Pull Request 摘要

这条法则只有一个任务:缩小工作范围。没有它,Codex 会试图通过扩大范围来帮忙。它会增加更多数据、触碰更多文件、调用更多工具,或者自动化一个应该由人工把控的步骤。在这里,工作范围更小:读取结果、提出一个文件改动、证明它有效,然后等待。

理想状态: 你在审批 PR 之前可以阅读这条法则,并清楚知道 Codex 被允许做什么。

出错的情况: 法则变成了一纸合规文件。如果 AGENTS.md 需要目录,那就已经太长了。保持它的可操作性。

第二步:将判断逻辑移到配置中

大多数外呼判断逻辑存在于某人的头脑中。然后团队购买软件,却期望软件能改进一个它无法看到的决策。把判断逻辑移到文件中。

signals:
  competitor_comparison:
    weight: 8
    reason: "买家正在比较替代方案"
  implementation_page_visit:
    weight: 6
    reason: "买家正在检查这个方案是否可以安装"
  job_repost:
    weight: 5
    reason: "职位仍然开放且紧急"
  funding_event:
    weight: 5
    reason: "预算或授权可能已发生变化"
  generic_download:
    weight: 1
    reason: "对内容感兴趣,购买意图较弱"

thresholds:
  draft: 6
  human_review: 10

negative_signals:
  student_research: -8
  vendor_pitch: -6
  competitor: -10

这个文件一开始是一个可见的假设。如果某个通用下载应该计为零分,团队可以指着具体那一行进行修改。如果某个实现页面访问的信号强度超过了你的预期,Codex 可以提出差异并展示支持该观点的结果行。

不要把这套逻辑埋在一个 Python 函数里。如果规则是可见的,团队就可以审阅它、对它提出异议、并在不需要把销售判断变成工程重构的情况下加以改进。

理想状态: 文件足够小,可以进行讨论。五个信号是一个不错的初始版本。

出错的情况: 评分文件变成了一个万能抽屉。二十个信号、六个阈值、以及针对每种边缘情况的例外规则,会让优化器过拟合。从窄处开始,让结果告诉你下一个调节旋钮应该放在哪里。

第三步:将结果作为记忆写入

最重要的文件是 memory/outcomes.jsonl。每次接触对应一行,在结果已知时写入:

{"date":"2026-07-01","account":"Northwind Finance","signal":"competitor_comparison","play":"migration_note","score":8,"outcome":"reply","reason":"asked for migration notes"}
{"date":"2026-07-01","account":"Bluepeak Studio","signal":"generic_download","play":"resource_followup","score":1,"outcome":"no_reply","reason":"content-only intent"}
{"date":"2026-07-02","account":"KiteOps","signal":"implementation_page_visit","play":"implementation_angle","score":6,"outcome":"reply","reason":"asked about implementation timeline"}
{"date":"2026-07-02","account":"Atlas Recruiting","signal":"job_repost","play":"hiring_angle","score":5,"outcome":"bad_fit","reason":"student research request"}

reason 字段是整个关键。no_reply 几乎什么也没告诉你。content-only intent 告诉下一轮运行这个信号可能不值得起草。bad_fit 只有在原因解释为什么时才有用。asked about implementation timeline 这种细节是可以改变权重的信息。

在构建优化器之前先构建验证器:

构建 scripts/append_outcome.py。它接受:
- date
- account
- signal
- play
- score
- outcome: reply | meeting | no_reply | bad_fit | bounced
- reason

它拒绝:
- 缺失字段
- 未知的 outcome
- 空的 reason
- 未来的日期

将有效的行追加到 memory/outcomes.jsonl。打印追加的行。

这就是复利开始的地方。一个仪表盘可以告诉你一次活动表现不佳。一份干净的结果日志可以告诉 Codex,在下一次运行之前应该更改哪个信号、策略或措辞。

理想状态: 一周后,一个陌生人可以读取这个文件,分辨出哪些信号产生了回复,哪些策略导致了对不匹配客户的对话,以及哪些内部偏爱被市场忽视了。

出错的情况: 团队在周五靠记忆补充结果。成功的案例留存下来,不匹配的原因变得模糊,系统从虚构中学习。在结果确定时立即写入该行。

第四步:构建评估门控

在 Codex 编辑任何东西之前,它需要一个它无法解释过去的测试。

创建 evals/fixtures.yaml

cases:
  - account: Northwind Finance
    signals: [competitor_comparison, implementation_page_visit]
    expected: human_review
    note: "两个强信号出现在同一个客户"
  - account: Bluepeak Studio
    signals: [generic_download]
    expected: ignore
    note: "仅内容意图"
  - account: KiteOps
    signals: [implementation_page_visit]
    expected: draft
    note: "实施意图应达到草稿阈值"
  - account: Atlas Recruiting
    signals: [job_repost, student_research]
    expected: ignore
    note: "不匹配标记抵消了信号"

然后创建 evals/score.py

构建 evals/score.py。读取 config/scoring.yaml 和 evals/fixtures.yaml。
对于每个案例:
1. 对每个信号求和权重。
2. 加上负面信号惩罚。
3. 路由该客户:
   - score >= thresholds.human_review => human_review
   - score >= thresholds.draft => draft
   - 否则 => ignore
4. 比较路由结果与预期。
打印每个预测。
以 score=0.00 到 score=1.00 的格式打印最终准确率。
只有当准确率为 1.00 时才以 0 退出。

第一个门控应该足够小以便理解,足够敏锐以便捕捉真正的失误。在我的第一次运行中,基线有一个案例失败了:

Northwind Finance: predicted=human_review expected=human_review
Bluepeak Studio: predicted=ignore expected=ignore
KiteOps: predicted=ignore expected=draft
Atlas Recruiting: predicted=ignore expected=ignore
score=0.75

这很好。系统的实现意图低于草稿阈值,因此它忽略了一个测试用例认为应该收到消息的客户。最好在测试中捕获这一点,而不是在一个月后错失客户时才意识到。

理想状态: 一个命令返回一个数字,每个失败的案例都能轻松审查。

出错的情况: 测试用例只包含明显的成功案例。然后任何鲁莽的更改都能通过。把难处理的案例也纳入门控:弱意图、不匹配、无回复、过时信号,以及你希望系统跳过的那些客户。

第五步:让 Codex 提出一个评分修改

现在 Codex 可以编辑了。创建 prompts/improve_scoring.md

你改进外呼评分系统。

读取:
- AGENTS.md
- config/scoring.yaml
- memory/outcomes.jsonl
- evals/fixtures.yaml

你的工作:
1. 找到一个应该更改的评分规则。
2. 理由必须引用 memory/outcomes.jsonl。
3. 只更改 config/scoring.yaml。
4. 运行 python3 evals/score.py。
5. 如果评分提高,保留更改。
6. 如果评分持平或下降,撤销你的更改并停止。

输出:
- 更改的具体行
- 导致更改的结果行
- 更改前的评分
- 更改后的评分
- 该更改是否应该成为 PR

不要编辑 prompts。不要添加新信号。不要触碰发送流程。

通过仓库包装器运行它:

scripts/run_codex_step.sh improve_scoring

我的第一个优化器版本犯了一个有用的错误。它追逐了看起来最干净的回复信号。在小小的结果日志中,competitor_comparison 的回复率最高,所以优化器想增加它的权重。评估结果仍然是 0.75,因此更改被拒绝。这正是门控存在的原因。一个较弱系统会接受这个说法,因为它听起来合理。但这个系统提出了一个更好的问题:这个更改是否修复了已知的失误?

第二次尝试找到了最小且有效的编辑:

- implementation_page_visit: 4
+ implementation_page_visit: 6

评估通过了:

Northwind Finance: predicted=human_review expected=human_review
Bluepeak Studio: predicted=ignore expected=ignore
KiteOps: predicted=draft expected=draft
Atlas Recruiting: predicted=ignore expected=ignore
score=1.00

这就是循环变得有用的时刻。它更改了一条规则,一个理由,并针对测试用例证明了更改的有效性。

理想状态: 提出的差异是无聊且可追溯的:一行更改,一个基于结果的理由,一个评估的改进。

出错的情况: Codex 同时更改了三个权重和两个提示。现在没人能分辨哪个更改起了作用。保持法则严格:每个提议只改一个概念。

第六步:单独改进提示文件

评分只是系统的一半。消息模板也会衰退。上个月有效的措辞,这个月开始听起来千篇一律。在一个细分市场获得回复的问题,在另一个细分市场却被忽视。内部觉得尖锐的短语,在市场上却受到惩罚。

将提示改进视为一个独立通道,这样 Codex 就不会在同一 PR 中混合评分和文案。

创建 config/plays.yaml

plays:
  migration_note:
    prompt_file: prompts/plays/migration_note.md
    use_when:
      - competitor_comparison
    banned_lines:
      - "thought this might be relevant"
      - "quick question"
  implementation_angle:
    prompt_file: prompts/plays/implementation_angle.md
    use_when:
      - implementation_page_visit
    banned_lines:
      - "checking out our solution"
      - "would love to chat"

然后创建 prompts/improve_prompt.md

你改进一个外呼策略。

读取:
- AGENTS.md
- config/plays.yaml
- memory/outcomes.jsonl
- 所选策略的提示文件

选择一个至少有 10 个结果的策略。找出:
- 在积极结果中出现的行或结构
- 在 no_reply 或 bad_fit 结果中出现的行或结构
- 任何应该被禁止的短语

对该策略的提示做一次小编辑。

规则:
- 不要更改评分。
- 不要创建新策略。
- 不要添加新渠道。
- 引用结果行。
- 写出修改前后的指令。

然后如果有文案评估,则运行它。如果不存在文案评估,则打开一个标记为 review_required 的 PR。

有些改进可以自动评分。其他改进仍然需要品味。如果没有文案评估,Codex 可以提出提示编辑,但它应该将 PR 标记为待审查,而不是假装该编辑已被证实。

理想状态: Codex 说:“这个短语出现在七个无回复结果中,所以我把它加到了 banned_lines”,或者“积极回复引用了第一句中的实现细节,所以我加强了这个策略,要求必须包含那个细节。”

出错的情况: 因为一次消息获得回复,优化器就重写了整个语气。提示的编辑应该比你直觉认为的更小。

第七步:通过 Pull Request 交付更改

这是控制层。Codex 编辑文件,运行评估,编写 PR 摘要。由人工审查并合并。

创建 prompts/pr_summary.md

为这个外呼改进编写一个 Pull Request 摘要。包括:

1. 什么更改了。
2. 为什么更改,引用结果行。
3. 更改前的评分。
4. 更改后的评分。
5. 更改的文件。
6. 风险。
7. 审查者应该检查什么。

保持简短。不要说该更改已经上线。

创建 scripts/open_pr.sh

#!/usr/bin/env bash
set -euo pipefail

branch="codex/weekly-tune-$(date +%Y-%m-%d)"
git checkout -b "$branch"
git add config prompts evals memory
git commit -m "Codex weekly outbound tune"
body="$(cat outputs/pr-summary.md)"
python3 scripts/create_pr.py \
  "$branch" \
  "Codex weekly outbound tune" \
  "$body"

PR 应该读起来像是一个队友写的:

更改:
- 将 implementation_page_visit 从 4 提高到 6。

原因:
- KiteOps 有实现页面的意图,并回复了实现时间线。
- 之前的评分将该客户路由到了“忽略”。

更改前:
- 评估评分 0.75

更改后:
- 评估评分 1.00

审查者检查:
- 确保实现意图足够具体。
- 保持通用下载的权重较低。
- 仅当与实际的销售判断一致时才合并。

这就是安全系统。Codex 完成繁琐的工作。操作者保持标准。

理想状态: 每周一个 PR,差异小,理由清楚,评估通过。

出错的情况: 有人因为审查感觉像阻力而给了 Codex 合并权限。那一分钟就区分了改进系统和漂移系统。

第八步:设定周期

不要每次回复后都运行。那样会导致系统对某个大嗓门客户过度拟合。让一周过去,让结果累积,然后进行调优。

创建 scripts/weekly_tune.sh

#!/usr/bin/env bash
set -euo pipefail

cd "$(dirname "$0")/.."

python3 evals/score.py || true
scripts/run_codex_step.sh improve_scoring
python3 evals/score.py
scripts/run_codex_step.sh pr_summary > outputs/pr-summary.md
scripts/open_pr.sh

然后 cron:

0 8 * * MON cd ~/codex-self-improving-outbound && scripts/weekly_tune.sh

如果使用 GitHub Actions,保持同样的结构:

name: weekly-outbound-tune
on:
  schedule:
    - cron: "0 8 * * 1"
  workflow_dispatch:
jobs:
  tune:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-python@v5
        with:
          python-version: "3.11"
      - run: pip install -r requirements.txt
      - run: python3 evals/score.py || true
      - run: scripts/weekly_tune.sh

前两次调优手动执行。阅读每个差异。观察 Codex 在样本量较少时试图更改什么。一旦提议变得无聊,就将其放在计划任务上。

理想状态: 每周出现一个 PR,附有证据、差异和评估结果。你合并、编辑或关闭它。

出错的情况: 任务运行,无人审查,PR 堆积。一个自我优化的系统仍然只有一个人类把关。

相似文章

@nifinet: https://x.com/nifinet/status/2064397495036440907

X AI KOLs Timeline

一份关于使用Claude Code构建AI驱动的GTM(上市策略)大脑的详细指南,涵盖五个核心组成部分——Sense、Remember、Judge、Act、Learn——以实现有判断力的基于客户的主动 outreach,而不仅仅是数量。

@jxnlco: https://x.com/jxnlco/status/2057153744630890620

X AI KOLs Following

这个推文串讨论了使用Codex编码代理的最佳实践,重点包括持久线程、语音输入、引导、队列,以及其从代码生成扩展到完整计算机工作流程自动化的能力。

@PaulSolt: https://x.com/PaulSolt/status/2073470146115490230

X AI KOLs Following

Paul Solt 分享了一个详细的工作流程,利用 Codex 智能体循环实现夜间自主构建功能,包括管理线程、心跳检测和自动 PR 审查。该技术从单次提示转向设计好的智能体循环,使得只需极少的人工干预即可实现持续开发。