第二代 pSEO 系统上线后,执行成功率从 60% 提升到了 95%,平均执行时间从 40 分钟缩短到 20 分钟,单篇文章成本也从约 30 美元降到了 5 美元以下。
从工程结果看,这次重构已经成功了。但当我们把 pSEO 当成长期运行的内容基础设施,而不是一次技术演示时,5 美元一篇仍然太贵。
Workflow + Agent 还有优化空间。通过缩短上下文、减少工具、调整模型和压缩 Prompt,成本大概可以继续降到 3 美元。但我们当时设定的目标是 0.5 美元一篇。继续优化 Agent,只是在降低一个本身就不适合这类任务的成本上限,很难改变它的成本结构。
因此,我们进行了第三次重构:取消 Agent 运行时,改成纯代码 Workflow + LLM 节点。
新方案中,生成 Workflow 直接调用 Ahrefs、抓取页面、执行校验、插入内链并保存文章草稿。发布则由独立 API 在人工选择 BOE 或 Live 后触发。文本 LLM 只保留在三个确实需要语义能力的位置:写作、主观审核和定向返修。每次调用都是无会话、无工具、无历史消息的单轮请求。
这次重构的目标不再只是提升稳定性,而是消除 Agent 架构中无法避免的固定成本。实际运行后,单篇文章的平均模型成本约为 0.3 美元,完整流程平均在 3 分钟内完成。
1. 三代 pSEO 架构解决了三个不同问题
我们的 pSEO 系统先后经历了三种架构。
| 架构 | 主要控制方式 | 单篇成本 | 成功率 | 平均耗时 | 主要问题 |
|---|---|---|---|---|---|
| OpenClaw 多 Agent | Workflow Agent 通过上下文调度 Specialist | 约 30 美元 | 约 60% | 约 40 分钟 | 上下文持续增长,任务越跑越慢,失败率随时间升高 |
| Workflow + OpenCode Agent | 代码管理 DAG,节点调用 Agent | 低于 5 美元 | 约 95% | 约 20 分钟 | Agent system prompt、工具调用和多轮对话仍然昂贵 |
| 纯 Workflow + LLM 节点 | 代码执行完整流程,必要节点单次调用模型 | 约 0.3 美元 | 持续统计中 | 3 分钟以内 | 需要继续控制返修长尾与完善成本对账 |
第一代主要验证“多 Agent 能不能完成 pSEO”。第二代解决“如何让它稳定执行”。第三代要解决的是另一个问题:
当流程已经固定之后,我们为什么还需要 Agent?
这个问题决定了系统的成本下限。
2. Workflow + Agent 为什么很难降到 0.5 美元
Agent 的成本不只来自最终生成的文章,还来自维持 Agent 工作方式所需的上下文。
一次典型的节点 Agent 调用,通常包含以下内容:
- Agent 身份、职责和行为边界等 system prompt。
- 可用 Skill、工具说明和参数 schema。
- 工作目录、路径规则和产物协议。
- 当前任务输入和上游产物。
- 工具调用请求与工具返回结果。
- 多轮对话历史和错误信息。
- 自检、修正和最终汇报。
即使 Agent 最后只写一篇文章,它也需要先理解“自己是谁、能做什么、应该怎么使用工具、完成后怎样汇报”。这些 token 不会直接进入文章,却会在每轮调用中重复付费。
更关键的是,Agent 很少只调用模型一次。它可能先读取文件,再调用抓取工具,接着分析结果,然后写入产物,最后重新读取文件完成检查。每一步都有新的对话消息、工具调用和返回结果。上下文越长,后续每一轮的输入成本越高。
假设一个节点经历四轮对话,成本并不是简单的“一份 Prompt × 4”。后面的调用会继续携带前面的消息和工具结果:
第 1 轮:system + task
第 2 轮:system + task + tool call + tool result
第 3 轮:前两轮全部内容 + 新的分析与工具结果
第 4 轮:前三轮全部内容 + 最终生成
这就是 Agent 成本容易随轮次快速增长的原因。缩短 Prompt、裁剪工具和更换模型都能降低单次价格,却无法彻底消除 system prompt、工具协议和多轮历史。
对于开放式任务,这些成本可能是合理的。Agent 需要自己探索代码、选择工具和决定下一步。但 pSEO 不是开放式任务,它是一条输入、步骤和输出都很明确的生产流程。
3. pSEO 天然适合 Workflow + LLM
pSEO 的核心步骤长期保持稳定:
- 读取关键词。
- 获取 Ahrefs 与 SERP 数据。
- 抓取并清洗竞品页面。
- 生成文章。
- 检查客观规则和内容质量。
- 必要时定向返修。
- 插入内链。
- 生成封面图。
- 计算阅读时长并保存文章。
- 人工选择环境发布。
这里大部分工作并不需要模型主观判断。
Ahrefs 请求参数是固定的,竞品页面可以按规则抓取,meta title 长度可以直接计算,关键词出现次数可以用代码统计,内链可以从白名单中匹配,阅读时长可以根据字数计算,文章数据也有固定 schema。
真正需要文本模型的地方只有两类:
- 内容生产:根据关键词和竞品资料生成文章,或根据反馈修订文章。
- 主观检查:判断文章是否完整、自然、可信,是否真正满足搜索意图。
此外,封面图由独立图片模型生成,不进入文本 LLM 的上下文和审核回路。
因此,第三代架构的原则很直接:
能用代码表达的规则全部进入 Workflow,只有无法确定性编码的语义任务才调用 LLM。
这不是把 Agent 换一个名字,而是取消 Agent 的自主执行能力。模型不再决定下一步,也不再使用工具。Workflow 准备好输入,向模型发送一次请求,解析结果,然后继续执行代码。
4. 第三代架构:模型成为函数,而不是执行者
新实现位于 service/pseo,主流程是一条由 TypeScript 明确编排、包含有限审核回路的固定 Workflow:
Workflow 不再向 Agent 发送“请完成写作阶段”这样的任务,而是直接调用一个明确的方法:
const result = await llmService.call({
taskName: 'write',
round: 1,
messageText: prompt,
});
模型接收到的请求只有一条 user message:
{
"messages": [
{
"role": "user",
"content": "已经渲染完成的写作 Prompt"
}
]
}
当前请求体中没有显式 system message,没有工具声明,没有 tool call,没有 tool result,没有 session ID,也没有之前的聊天记录。模型只完成一个输入到输出的映射。
从 Workflow 的接口看,LLM 被封装成具有显式输入输出的无状态节点:
writingInput -> writingOutput
reviewInput -> reviewOutput
repairInput -> repairOutput
这种调用方式牺牲了 Agent 的自主性,但换来了更小的上下文、更稳定的调用次数和更容易计算的成本。对固定流程而言,这正是我们需要的取舍。
5. 哪些节点使用 LLM,哪些已经完全代码化
第三代系统不再按“以前这里有一个 Agent,所以现在也要有一个模型节点”进行迁移。每个节点都重新判断是否真的需要语义能力。
| 节点 | 执行方式 | LLM 输入 | 为什么这样设计 |
|---|---|---|---|
| 批次创建与关键词拆分 | TypeScript + MQ | 无 | 任务拆分、状态和队列都是确定性操作 |
| Ahrefs 数据采集 | 代码调用 API | 无 | 参数、缓存、重试和过滤规则固定 |
| 竞品页面抓取与清洗 | Axios + Readability + 清洗脚本 | 无 | 下载、正文提取、去链接和长度限制可程序化 |
| SEO 写作 | 文本 LLM | 关键词、意图、竞品内容和写作 Prompt | 需要生成结构完整的自然语言内容 |
| 客观质量检查 | TypeScript | 无 | 标题长度、关键词、字数、章节和禁用词均可计算 |
| 主观质量检查 | 文本 LLM | 当前文章、关键词和 metadata | 需要判断表达、完整性和事实风险 |
| 定向返修 | 文本 LLM | 当前文章和标准化审核反馈 | 需要理解问题并重写相关内容 |
| 内链插入 | TypeScript + 静态链接库 | 无 | 锚文本、URL 去重、标题排除和数量限制规则明确 |
| 封面图 | 图片生成模型 | 关键词、meta title 和 description | 属于视觉内容生成,但与文本会话完全隔离 |
| 阅读时长 | TypeScript | 无 | 按中英文字符和单词数直接计算 |
| 存储与发布 | TypeScript + DB/TOS | 无 | schema、目标路径和环境均可确定 |
文本 LLM 最终只承担 write、review 和 repair。封面图由独立图片模型生成,不共享文章写作上下文。
内链是一个典型变化。第二代仍让 Agent 理解文章、选择 URL 并插入链接;第三代直接读取静态内链库,在非标题、非已有链接区域匹配锚文本,并对 URL 去重。对于标题严格为 Introduction 的 H2 区域,已有链接和新增链接合计最多两条;脚本必须成功新增至少五条内链。整个过程不产生任何 token。
6. 从多轮 Agent 对话变成单轮 LLM 请求
纯 Workflow + LLM 最直接的成本变化,是每个模型节点都成为无状态单轮调用。
Write 节点一次性接收关键词、搜索意图、竞品页面和固定写作要求,返回:
{
"meta_title": "...",
"meta_description": "...",
"title": "...",
"article_content": "Markdown content"
}
Review 节点不继承 Write 的会话。Workflow 重新构造最小输入,只传当前文章、主关键词、次关键词、meta title、meta description 和文章标题,要求模型返回:
{
"passed": true,
"feedback": []
}
如果审核不通过,Repair 节点同样启动一次新的独立请求,读取关键词、当前 metadata、标题、正文和标准化反馈。修订完成后,Workflow 再进入下一轮客观检查与主观审核。
从业务上看,write、review 和 repair 仍然组成一个迭代回路;从模型 API 的角度看,每次调用都是独立的单轮请求,不存在不断膨胀的会话历史。
当前流程最多进行三轮审核和两轮返修。正常一次通过时,完整流程包含 1 次 write、1 次 review 和 1 次图片调用。不含格式修复时,最差路径包含 6 次文本调用,也就是 1 次 write、3 次 review 和 2 次 repair,外加 1 次图片调用。
Write、Review 和 Repair 在返回格式无法解析时,各自最多增加 1 次格式修复调用,因此理论上最多出现 12 次文本调用。每次逻辑调用最多尝试 3 次 HTTP 请求,也就是初次请求加 2 次重试。业务节点次数、格式修复次数和网络请求次数被分别限制,不会由模型自行决定是否继续对话。
7. 上下文不再按流程累积,而是按节点切片
第三代架构并不是把完整任务数据复制给每个 LLM 节点,而是让不同节点只看到完成当前任务所需的信息。
Write 读取竞品内容
只有写作阶段需要了解竞品覆盖范围。Workflow 最多收集六个有效页面,清理图片和链接,并限制单页内容长度,然后把结构化竞品数据放入 Write Prompt。
Review 不读取竞品页面
审核阶段只关心当前文章是否符合内容与 SEO 要求,因此不再重复携带 Ahrefs 原始数据和竞品全文。输入只包括文章、关键词和 metadata。
Repair 不再读取竞品内容
返修阶段不需要重新理解完整研究过程。它接收主关键词、次关键词、当前 metadata、标题、正文和合并后的审核反馈,输出更新后的 metadata、标题和正文。
Image 只读取主题信息
封面图节点只使用关键词、meta title 和 meta description,不读取文章全文,也不共享任何文本模型历史。
这种切片方式使上下文大小由节点输入决定,而不是由任务已经运行了多久决定。第一个关键词和第一百个关键词使用相同的调用结构,成本不会因为共享会话历史增长而自然上升;实际金额仍取决于竞品与文章长度、输出长度和返修次数。
8. 客观规则先由代码计算,再减少无效的主观审核
如果一条规则能被代码准确判断,就不应该消耗一次 LLM 调用。
当前客观审核已经覆盖:
- Meta title 是否超过 60 个字符。
- Meta description 是否超过 160 个字符。
- 关键词是否出现在 metadata 和标题中。
- 正文是否达到 1500 个英文单词。
- Introduction 是否满足要求。
- 正文中的关键词出现次数。
- Conclusion 和 FAQ 的顺序。
- 是否存在非 FAQ 的 H3。
- 是否包含禁用表达。
通过代码执行这些检查有两个好处。第一,结果可重复,不会因为模型状态不同而改变。第二,反馈可以直接结构化后交给 Repair 节点,不需要让 Review LLM 再花 token 数标题长度或搜索关键词。
主观 Review 只处理代码难以可靠判断的部分,例如内容是否真正回答搜索意图、章节是否重复、建议是否自然、事实表达是否存在风险。
这条边界还可以继续推进。当前实现即使客观审核已经失败,仍会继续调用主观 Review。后续可以先处理确定性问题,修复后再进入主观审核,避免为注定需要返修的版本支付一次完整 Review 成本。
9. 结构化输出决定了是否需要额外调用
Write、Review 和 Repair 都要求模型返回 JSON。Workflow 会解析并验证必填字段;如果格式错误,再发起一次独立的格式修复请求,要求模型只转换格式,不添加新内容。
这比让 Agent 自行检查稳定,但仍然存在额外成本。一次内容质量完全合格、只是 JSON 少了引号的返回,也会增加一次模型调用。
为了减少 0.3 美元平均成本中的无效波动,结构化输出还可以进一步下沉到模型接口层:
- 使用原生 JSON mode 或 response schema。
- 在请求阶段限制字段类型和必填项。
- 继续增强现有本地容错解析,处理更多轻微格式问题,减少进入格式修复 LLM 的情况。
- 只有内容字段真实缺失时才重新调用模型。
这类优化看起来不如换模型显眼,却能直接减少调用次数。对于大规模 pSEO,减少一次请求通常比把每个 Prompt 再缩短 10% 更有效。
10. 成本从“估算整条任务”变成“记录每次调用”
新实现会为每次成功返回内容的模型调用生成成本记录;如果响应缺少 usage,token 和估算成本会退化为零:
- 任务类型:write、review、repair 或 cover image。
- 审核轮次。
- Provider 和模型。
- 输入、输出、缓存与 reasoning token。
- ModelHub log ID。
- 调用开始和结束时间。
- 按模型价格估算的美元成本。
调用成本先累计在当前关键词的内存上下文中,任务结束时再批量写入独立记录。运行时结果汇总为 totalLlmCostUsd,成功文章持久化为 extra.totalLlmCostMicroUsd。对于成功持久化的调用,我们可以按任务类型、轮次和模型分析:一篇文章贵在写作、审核、返修,还是图片?未通过审核的文章多花了几轮成本?
这套记录仍有边界:没有成功返回 usage 的异常请求无法准确计费,进程在任务结束前异常退出时,内存中尚未批量写入的成本也可能丢失。要建立严格的预算系统,后续还需要把成本从“任务结束时持久化”改为“调用完成后立即持久化”。
成本可观测是把单篇成本从 5 美元降到约 0.3 美元的前提。没有节点级记录,只能知道“这批任务很贵”;有了调用级数据,才能针对真正昂贵的输入和失败路径优化。
11. 0.3 美元的成本是怎么实现的
从 5 美元降到约 0.3 美元,不是依靠某一个更便宜的模型,而是同时减少模型需要参与的步骤、每次调用携带的上下文和一次任务产生的对话轮次。
11.1 删除 Agent 固定上下文
第三代不再加载 Agent 身份、Skill、工具 schema、路径规则和历史消息。文本模型请求只有一条已经准备好的 user message。模型不需要先理解自己该做什么,也不需要通过工具寻找输入。
这部分内容在 Agent 架构中每轮都会重复出现,删除后直接降低了所有 write、review 和 repair 调用的 input token。
11.2 把七类工作移出模型
Ahrefs 数据采集、竞品抓取、页面清洗、客观审核、内链插入、阅读时长计算和文章存储全部由 TypeScript 完成。这些节点不再产生 system prompt、工具调用和模型输出。
LLM 只处理代码无法可靠完成的语言任务。正常一次通过的文章只需要 1 次 write、1 次 review 和 1 次图片调用。
11.3 每个节点只读取最小输入
Write 读取关键词和竞品内容;Review 只读取当前文章、关键词与 metadata;Repair 不再读取竞品页面;图片模型只读取关键词和 metadata。不同节点不共享会话,也不会携带之前的工具结果。
因此,成本取决于当前节点的真实输入,而不是 Workflow 已经运行了多久。
11.4 限制模型的思考与循环次数
文本调用默认关闭 thinking token,最大输出长度固定。审核最多执行三轮,返修最多执行两轮,格式修复也只有一次机会。每条高成本路径都有明确上限,不会因为模型自行反思或继续规划而增加未知轮次。
11.5 用代码完成后处理与验收
模型返回结果后,代码负责解析 JSON、移除正文链接和多余 H1、修复产品名大小写、统一 FAQ 标题并检查必填字段。轻微格式问题不需要重新启动一个 Agent 处理,只有结果确实无法解析时才调用格式修复模型。
11.6 逐次记录模型成本
write、review、repair 和 cover image 的 token 与美元成本分别记录,再汇总到文章。我们能够看到一次返修增加了多少成本,也能区分正文生成与图片生成的消耗。
最终,纯 Workflow + LLM 将单篇文章平均成本降到约 0.3 美元,完整执行时间控制在 3 分钟以内。这个结果来自一组可复用的工程约束:减少模型职责、缩小节点输入、限制调用轮次,并让所有确定性工作回到代码。
12. 固定 Workflow 不是所有 AI 任务的答案
纯 Workflow + LLM 的代价是灵活性下降。增加一个节点需要修改代码和部署;遇到流程外情况,模型不会像 Agent 一样自行寻找工具和替代方案。
但这不是 pSEO 的缺点。
pSEO 追求的是批量、一致、可审核和成本可控。关键词来源明确,输出 schema 固定,审核标准可以拆分,大部分异常也能够提前枚举。相比“面对未知问题自主规划”,它更需要“把同一件事稳定地执行一千次”。
适合 Agent 的任务通常具有以下特点:
- 目标明确,但路径未知。
- 需要动态选择工具。
- 输入结构变化很大。
- 需要根据外部结果持续规划。
适合 Workflow + LLM 的任务则相反:
- 路径稳定,节点和依赖明确。
- 大部分规则可以程序化。
- LLM 只在少量节点提供语义能力。
- 需要严格控制吞吐、失败率和单次成本。
选型的关键不是“Agent 是否更先进”,而是任务究竟需要自主性,还是只需要智能能力。
13. 总结
三代架构对应了三个阶段的答案:第一代证明 AI 可以完成 pSEO;第二代用代码 Workflow 把执行成功率从约 60% 提升到 95%;第三代进一步取消 Agent 运行时,将单篇成本从约 5 美元降到 0.3 美元,平均执行时间从 20 分钟缩短到 3 分钟以内。
最终方案并没有减少对模型能力的要求,而是缩小了模型的职责范围:Write 生产内容,Review 完成主观判断,Repair 根据反馈修改文章,封面图由独立图片模型生成。数据采集、抓取、校验、内链、状态、存储和发布全部由代码负责。
当流程已经确定,LLM 最合适的位置不是工作流的驾驶员,而是一个拥有明确输入输出的计算节点。
pSEO 的路径固定、规则明确,需要主观判断的环节很少。它需要的不是一个能够自主规划的 Agent,而是一条稳定的 Workflow,在少数关键节点调用模型。
这次重构最终同时改善了三个指标:流程更短,平均 3 分钟内完成;成本更低,单篇约 0.3 美元;执行规模扩大时,不会因为共享会话历史增长而持续变慢。对于需要批量生产的 AI 系统,这种可预测性比增加更多 Agent 能力更有价值。