# How to Build an Agent Graph That Finds Business Opportunities While You Sleep.
**作者**: NeilXbt
**日期**: 2026-07-24T14:19:48.000Z
**来源**: [https://x.com/neil_xbt/status/2080659214028984441](https://x.com/neil_xbt/status/2080659214028984441)
---

Most opportunity research dies of exhaustion.
You decide to look into something, a market, a niche, a category of deal. You spend four hours on the first candidate. You pull the numbers, run the math, check the constraints, and conclude it is marginal. Then you look at the eleven other candidates on your list and quietly stop. Not because the method was wrong, but because four hours times twelve is a week of work for a handful of verdicts, and you have a job.
The people who find good opportunities are rarely smarter analysts. They just get through more candidates. Volume is the whole edge, and volume is exactly what a manual research process cannot produce.
This article builds a system that produces volume. Not a single agent grinding through a loop, but a small graph of specialized agents: one that scans, one that analyzes, one that verifies, and a routing rule that only wakes you for the candidates worth your attention. It runs overnight. In the morning you read a short list of verdicts instead of a long list of things you should probably look into.
One warning before the build, because it shapes everything below: most tasks do not need a graph. A single well-scoped agent with a good verifier is a loop, and reaching for a graph when a loop would do turns a two-hour task into a two-day framework project. This particular task earns its graph, and the section after next explains exactly why, so you can apply the same test to whatever you build next.
## Why This Task Earns a Graph
A loop is just a single-node graph with an edge back to itself. Everything you know about loop design, the discover-plan-execute-verify cycle, the stop condition, the verifier, is the inside of one node. A graph is what you get when several loops need to hand off to each other, and graph engineering is the discipline of deciding how they connect.
So the question is never "graph or loop." It is "does this work split into distinct specialties that hand off." For opportunity scanning, it does, on four counts.
The work splits into genuine specialties. Finding candidates is a breadth task: search wide, filter loosely, produce a list. Analyzing a candidate is a depth task: pull specific numbers, run a formula, produce a verdict. Verifying an analysis is a skeptical task: check the inputs, hunt for the disqualifying detail, try to kill the deal. Those are three different jobs with three different success criteria, and cramming them into one agent's loop means the agent that found a promising candidate is also the agent deciding whether it is promising.
It needs fan-out and fan-in. One scan produces a dozen candidates. Analyzing them sequentially wastes the parallelism that is available for free. Fan the analysis out across candidates, then join the results back into one ranked list.
Failure needs isolating. One candidate with broken or missing data should fail on its own and get flagged, not corrupt the whole run or poison the ranking of everything else.
Verification must be independent. This is the decisive one. An agent that produced an analysis is the worst possible judge of that analysis, because it shares every assumption it just made. The single highest-value node in almost any agent graph is a separate, read-only verifier whose only job is checking another node's work.
Four triggers, all firing. That is what justifies the structure. If your task only fires one of them, build the loop instead.
## The Architecture
The graph has four nodes, five edges, and one shared state object that travels along them.
┌─────────────────┐
schedule ─────►│ SCANNER │
│ finds candidates│
└────────┬────────┘
│
state: {criteria, candidates[]}
│
┌────┴────┐ fan-out
▼ ▼ ▼
┌─────────────────┐
│ ANALYZER │ (one per candidate,
│ scores + math │ running in parallel)
└────────┬────────┘
└────┬────┘ fan-in
│
state: {..., analyses[] with verdicts}
│
▼
┌─────────────────┐
│ VERIFIER │
│ tries to kill it│
└────────┬────────┘
│
state: {..., confirmed[], rejected[]}
│
verdict == STRONG?
│
┌───────────┴───────────┐
yes no
│ │
▼ ▼
┌─────────────┐ ┌──────────────┐
│ BRIEF │ │ ARCHIVE │
│ wakes you │ │ silent log │
└─────────────┘ └──────────────┘
Four nodes. The conditional edge at the bottom is the one that makes the system livable, because it is the difference between a report you read and a report you ignore. Everything that is not STRONG goes to an archive you can consult but never have to read.
## The Shared State
State is what turns a pile of agents into a system rather than a group chat that forgets everything. Define it explicitly before writing a single node, because state drift is the most common way graphs rot.
Two design decisions in there are worth calling out.
The assumptions field on every analysis exists so the verifier has something specific to attack. An analysis that does not state what it is assuming cannot be meaningfully checked, because the verifier has to reconstruct the reasoning before it can test it.
The errors array is what isolates failure. A candidate that breaks during analysis writes an error and drops out. It does not halt the run, and it does not silently disappear either, which is the failure mode where you never learn that a third of your candidates failed to process.
## Node 1: The Scanner
The scanner's only job is breadth. It finds candidates and applies the hard filters that disqualify something outright. It does not evaluate quality, because evaluating quality is the analyzer's job, and a scanner that starts scoring things will quietly narrow the funnel using criteria nobody wrote down.
The instruction against estimating missing numbers is the most important line in the node. A scanner that fills a gap with a plausible-looking figure hands the analyzer a number that gets multiplied through a formula into a verdict, and nothing downstream can tell that the verdict was built on a guess.
## Node 2: The Analyzer
The analyzer runs once per candidate, in parallel. It takes raw data and produces a verdict with explicit math and stated assumptions.
The verdict thresholds are numeric on purpose. STRONG, MARGINAL, and SKIP as bands with specific numeric bars mean the routing edge later is a deterministic check rather than a model judgment call, which is what keeps the system from waking you for things that merely felt promising.
## Node 3: The Verifier
This is the node that makes the whole graph trustworthy, and it is the one most people skip.
The verifier is a different agent from the analyzer, ideally running a different model, with one instruction that inverts its incentive: its job is to kill the deal, not confirm it. An agent asked to "check this analysis" tends to confirm it. An agent asked to find the reason this fails behaves completely differently.
The distinction between a concern and a finding in that last rule is what separates a verifier that adds signal from one that adds anxiety. Vague hedging on every candidate is functionally the same as approving everything, because it gives you nothing to act on.
## Node 4: The Router and the Brief
The routing edge is deterministic code, not a model decision. This matters: a prompt asking a model to "surface the good ones" reintroduces exactly the judgment the thresholds were designed to remove.
Note that UNCERTAIN routes to the brief, not the archive. Those are the candidates where the system correctly declined to decide, and they are often the most interesting ones, because they are where a human judgment call actually adds value rather than duplicating what the machine already did.
The brief itself should be short enough to read with coffee:
That last instruction prevents the most corrosive failure mode of any automated brief. A system that manufactures something interesting on quiet mornings teaches you to stop trusting it, and a brief you have learned to skim is worse than no brief.
## Stop Conditions and Cost
A graph is many loops, which means a weak verifier or a missing bound now burns tokens in parallel rather than sequentially. Cap it explicitly, in the router's logic rather than in a prompt.
Set a maximum candidates per run, so a broad scan cannot fan out into hundreds of parallel analyses. Set a maximum retries per candidate, typically one, after which the candidate writes an error and drops out rather than looping. And set a hard per-run cost ceiling that halts the batch regardless of state when hit.
Then scope before you scale. Run the graph on five candidates first, measure what it actually costs and how good the verdicts are, and only then point it at thirty. This is the single discipline that separates people who run agent graphs comfortably from people who discover the cost after the invoice arrives.
## Test It Before You Trust It
Four deliberate tests, run before you let this operate unattended.
Feed it a known bad candidate. Take an opportunity you already know does not work and confirm the verifier rejects it. If a deliberately broken candidate reaches your morning brief, the verifier is decorative.
Feed it a candidate with missing data. Confirm the scanner flags the gap rather than estimating, and the analyzer returns INSUFFICIENT_DATA rather than computing a verdict from an invented number.
Break one candidate mid-run. Confirm it writes an error, drops out, and appears in the run summary, without corrupting the ranking or halting the batch.
Run the worst case. Maximum candidates, maximum retries, longest analyses. Calculate the cost. If the number would bother you on a real invoice, your bounds are too loose.
Most systems that fail in production would have failed one of these immediately, if anyone had run it.
## Build the Loop First
The full graph is four nodes, a state object, a routing rule, and a set of bounds. Do not build it all at once.
Start with a single loop: one agent that takes one candidate, analyzes it, and produces a verdict with stated assumptions. Run it by hand on a candidate you already understand and compare its verdict to your own. Tune the formula and thresholds until they agree with your judgment.
Then add the verifier as a genuinely separate step and feed it a candidate you know is bad. If it catches it, you have the only node that makes the rest safe to automate.
Only then add the scanner for breadth, the fan-out for parallelism, the routing rule, and the schedule.
That order matters, because it lets you verify each node independently before trusting them as a system. A graph assembled all at once and never tested role by role is exactly the kind of thing that runs beautifully overnight and hands you a confident, well-formatted, completely wrong list in the morning.
The edge was never being a better analyst. It was getting through more candidates without lowering the bar on any of them.
Build the loop this week. Add the verifier next.
The graph is what you get once both of those work.
## 相关链接
- [NeilXbt](https://x.com/neil_xbt)
- [@neil_xbt](https://x.com/neil_xbt)
- [6.9K](https://x.com/neil_xbt/status/2080659214028984441/analytics)
- [Upgrade to Premium](https://x.com/i/premium_sign_up)
- [10:19 PM · Jul 24, 2026](https://x.com/neil_xbt/status/2080659214028984441)
- [6,990 Views](https://x.com/neil_xbt/status/2080659214028984441/analytics)
- [View quotes](https://x.com/neil_xbt/status/2080659214028984441/quotes)
---
*导出时间: 2026/7/25 10:53:18*
---
## 中文翻译
# 如何构建一个在你睡觉时发现商机的 Agent 图
**作者**: NeilXbt
**日期**: 2026-07-24T14:19:48.000Z
**来源**: [https://x.com/neil_xbt/status/2080659214028984441](https://x.com/neil_xbt/status/2080659214028984441)
---

大多数机会调研都死于精疲力竭。
你决定研究某样东西,一个市场、一个细分领域、或者一类交易。你在第一个候选对象上花了四个小时。你拉取数据、计算、检查约束条件,最后得出结论:这微不足道。然后你看了一眼名单上剩下的十一个候选对象,悄悄地停了下来。不是方法错了,而是因为四小时乘以十二等于一周的工作量,却只能换来寥寥几个结论,而且你还有本职工作。
那些能找到好机会的人,很少是更聪明的分析师。他们只是筛选了更多的候选对象。数量就是全部优势,而数量恰恰是手动调研流程无法产出的。
本文构建了一个能产生规模的系统。不是在一个循环中死磕的单个 Agent,而是一个由专业 Agent 组成的小型图:一个负责扫描,一个负责分析,一个负责验证,以及一个路由规则,只在候选对象值得你关注时才唤醒你。它通宵运行。早上,你读到的是一份简短的结论清单,而不是一长串你可能应该去看看的东西。
在开始构建之前有一个警告,因为它决定了下文的一切:大多数任务不需要图。一个范围界定清晰且带有良好验证器的单个 Agent 就是一个循环,当可以用循环解决问题时却伸手去搞图,会把两小时的任务变成两天的框架项目。这个特定任务配得上使用图,下一节会解释确切原因,这样你就可以把同样的测试应用到接下来构建的任何东西上。
## 为什么这个任务配得上用图
循环只是一个带有一条边指向自身的单节点图。你所知道的关于循环设计的一切——发现-计划-执行-验证周期、停止条件、验证器——都在一个节点内部。图就是当多个循环需要相互交接时产生的形态,而图工程就是决定它们如何连接的学科。
所以问题从来不是“用图还是用循环”。而是“这项工作是否拆分成了可以相互交接的独立专业领域”。对于机会扫描来说,答案是肯定的,基于四点。
工作拆分成了真正的专业领域。寻找候选对象是一个广度任务:广泛搜索、宽松过滤、产出列表。分析候选对象是一个深度任务:拉取具体数字、运行公式、产出结论。验证分析是一个怀疑论任务:检查输入、搜寻导致不合格的细节、试图扼杀这笔交易。这是三个不同的工作,有三个不同的成功标准,把它们硬塞进一个 Agent 的循环里,意味着发现了一个有前途的候选对象的 Agent,同时也是决定它是否有前途的 Agent。
它需要扇出和扇入。一次扫描产生十几个候选对象。顺序分析它们会浪费唾手可得的并行性。将分析扇出到各个候选对象,然后将结果合并回一个排名列表。
失败需要隔离。一个数据损坏或缺失的候选对象应该自行失败并被标记,而不是破坏整个运行流程,或者污染其他所有内容的排名。
验证必须是独立的。这是决定性的一点。产生了分析的 Agent 是该分析最糟糕的评判者,因为它分享它刚刚做出的每一个假设。几乎任何 Agent 图中最高价值的节点,都是一个独立的、只读的验证器,它的唯一工作就是检查另一个节点的工作。
四个触发点,全部命中。这就是证明结构合理性的依据。如果你的任务只触发其中之一,那就构建循环吧。
## 架构
该图有四个节点、五条边,以及一个沿着它们传递的共享状态对象。
┌─────────────────┐
schedule ─────►│ SCANNER │
│ finds candidates│
└────────┬────────┘
│
state: {criteria, candidates[]}
│
┌────┴────┐ fan-out
▼ ▼ ▼
┌─────────────────┐
│ ANALYZER │ (one per candidate,
│ scores + math │ running in parallel)
└────────┬────────┘
└────┬────┘ fan-in
│
state: {..., analyses[] with verdicts}
│
▼
┌─────────────────┐
│ VERIFIER │
│ tries to kill it│
└────────┬────────┘
│
state: {..., confirmed[], rejected[]}
│
verdict == STRONG?
│
┌───────────┴───────────┐
yes no
│ │
▼ ▼
┌─────────────┐ ┌──────────────┐
│ BRIEF │ │ ARCHIVE │
│ wakes you │ │ silent log │
└─────────────┘ └──────────────┘
四个节点。底部的条件边是让这个系统变得可用的关键,因为它是你会阅读的报告和你会忽略的报告之间的区别。所有不属于“强(STRONG)”的内容都会进入一个你可以查阅但永远不必阅读的归档。
## 共享状态
状态是将一堆 Agent 变成一个系统,而不是一个遗忘一切的群聊的关键。在编写任何节点之前明确定义它,因为状态漂移是图腐烂的最常见方式。
其中两个设计决定值得指出来。
每个分析上的假设字段的存在,是为了让验证器有具体的攻击目标。一个不说明其假设的分析无法被有意义地检查,因为验证器必须在能够测试之前重建推理过程。
错误数组是隔离失败的手段。在分析过程中崩溃的候选对象会写入一个错误并退出。它不会停止运行,也不会无声无息地消失——后一种失败模式会导致你永远不知道有三分之一的候选对象处理失败了。
## 节点 1:扫描器
扫描器的唯一工作是广度。它寻找候选对象并应用那些直接取消资格的硬性过滤器。它不评估质量,因为评估质量是分析器的工作,如果一个扫描器开始给事物打分,它就会使用没人写下来的标准悄悄缩小漏斗。
禁止估算缺失数字的指示是此节点中最重要的一行。一个用看似合理的数字填补空白的扫描器,会把一个数字传给分析器,这个数字会通过公式计算变成一个结论,而下游没有任何东西能判断出这个结论是建立在猜测之上的。
## 节点 2:分析器
分析器对每个候选对象运行一次,并行进行。它获取原始数据,并利用明确的数学计算和陈述的假设产出结论。
结论阈值特意设为数字。将 STRONG、MARGINAL 和 SKIP 作为带有特定数值界限的区间,意味着后面的路由边是一个确定性的检查,而不是模型的主观判断,这正是防止系统因为那些仅仅“感觉有希望”的事情而唤醒你的关键。
## 节点 3:验证器
这是让整个图变得可信的节点,也是大多数人跳过的节点。
验证器是一个与分析器不同的 Agent,理想情况下运行不同的模型,带有一条能反转其激励的指示:它的工作是扼杀这笔交易,而不是确认它。被要求“检查这个分析”的 Agent 往往会去确认它。而被要求“找出它失败的原因”的 Agent 行为则完全不同。
最后那条规则中“担忧”与“发现”之间的区别,正是区分一个增加信号的验证器和一个增加焦虑的验证器的关键。对每个候选对象都进行模糊的折衷,功能上等同于批准一切,因为它没给你提供任何可采取行动的依据。
## 节点 4:路由器和简报
路由边是确定性代码,而不是模型决策。这很重要:一个要求模型“挑出好的”的提示词,会重新引入那些阈值本来旨在消除的主观判断。
请注意,UNCERTAIN(不确定)路由到简报,而不是归档。这些是系统正确地拒绝做出决定的候选对象,它们往往是最有趣的,因为那里真正需要人工判断来增加价值,而不是重复机器已经做过的事情。
简报本身应该短到可以在喝咖啡时读完:
最后那条指示可以防止任何自动化简报最具破坏性的失败模式。一个在平静的早晨凭空制造出有趣内容的系统,会教会你不再信任它;而一份你学会略读的简报,比没有简报更糟糕。
## 停止条件与成本
一个图包含许多循环,这意味着一个薄弱的验证器或缺失的边界现在会并行而不是顺序地消耗 Token。明确地限制它,在路由器的逻辑中限制,而不是在提示词中限制。
设置每次运行的最大候选对象数,这样广泛的扫描就不会扇出到数百个并行分析中。设置每个候选对象的最大重试次数,通常是一次,之后候选对象会写入一个错误并退出,而不是循环下去。并设置一个硬性的每次运行成本上限,一旦达到无论状态如何都停止批次处理。
在扩展之前先界定范围。先在五个候选对象上运行图,测量它的实际成本以及结论的质量,只有在那时才把它指向三十个。这是区分那些能自如运行 Agent 图的人和那些在收到账单后发现成本的人的唯一准则。
## 在信任之前先测试
四个刻意的测试,在你让它无人看管运行之前进行。
输入一个已知的坏候选对象。拿一个你已经知道行不通的机会,确认验证器会拒绝它。如果一个故意破坏的候选对象出现在你的晨间简报中,那么验证器只是摆设。
输入一个缺失数据的候选对象。确认扫描器会标记缺口而不是估算,分析器会返回 INSUFFICIENT_DATA(数据不足)而不是根据虚构的数字计算结论。
在运行中途破坏一个候选对象。确认它会写入错误、退出,并出现在运行摘要中,而不会破坏排名或停止批次处理。
运行最坏情况。最大候选对象数、最大重试次数、最长的分析。计算成本。如果这个数字在真实的账单上会让你困扰,那你的边界就太松了。
大多数在生产中失败的系统,如果有人运行过这些测试,立刻就会在其中一项上失败。
## 先构建循环
完整的图包括四个节点、一个状态对象、一条路由规则和一组边界。不要一次性构建所有内容。
从单个循环开始:一个 Agent 接收一个候选对象,分析它,并产出带有陈述假设的结论。在你已经理解的一个候选对象上手动运行它,并将其结论与你自己的进行比较。调整公式和阈值,直到它们与你的判断一致。
然后添加验证器作为一个真正独立的步骤,并输入一个你知道是坏的候选对象。如果它抓住了,你就拥有了让其余部分可以安全自动化的唯一节点。
只有在那之后,再添加用于广度的扫描器、用于并行的扇出、路由规则和调度。
这个顺序很重要,因为它让你在信任它们作为一个系统之前,能够独立验证每个节点。一个一次性组装且从未逐个角色测试过的图,恰恰就是那种运行得很完美,却在第二天早上交给你一份自信、格式完美、但完全错误的清单的东西。
优势从来不是做一个更好的分析师。而是筛选更多的候选对象,同时不降低对任何一个的标准。
本周构建循环。下周添加验证器。
当这两者都工作时,图自然就出现了。
## 相关链接
- [NeilXbt](https://x.com/neil_xbt)
- [@neil_xbt](https://x.com/neil_xbt)
- [6.9K](https://x.com/neil_xbt/status/2080659214028984441/analytics)
- [升级到 Premium](https://x.com/i/premium_sign_up)
- [10:19 PM · Jul 24, 2026](https://x.com/neil_xbt/status/2080659214028984441)
- [6,990 Views](https://x.com/neil_xbt/status/2080659214028984441/analytics)
- [查看引用](https://x.com/neil_xbt/status/2080659214028984441/quotes)
---
*导出时间: 2026/7/25 10:53:18*