LangChain 详解如何构建其付费媒体 Agent 并开源
How We Built LangChain’s Paid Media Agent
LangChain 发布长文,复盘自建付费媒体 Agent 的构建过程并已开源。该 Agent 运行在 Slack 中,半年内将付费渠道贡献从 0 提升至营销管线的 20%,合格线索成本(CPL)从 6 月到 8 月下降 30%。
LangChain 亲述自建付费投放 Agent 的架构与实测数据,五层上下文和单一运行时等经验可直接迁移到其他 Agent 工程。
在 LangChain 的头三年,我们的销售管道主要靠自然增长,由开源、内容、YouTube、社区和聚会驱动。今年一月,我们想启动付费广告计划,开始触达自然增长无法覆盖的潜在客户,比如新地区和企业的决策者。
我们希望在短短六个月内,从主要依赖自然增长的引擎扩展到五个付费渠道。这给我们小型的营销团队带来了新的挑战。我们必须跟踪跨渠道启动的新广告活动、不同的创意和定向实验,以及不断增长、需要理解和采取行动的绩效数据。
为了扩展和优化,我们有一些技术障碍需要克服。每个广告平台都有自己的数据模式,使得跨渠道的绩效难以统一。广告活动参数也无法清晰地映射到我们最终关心的结果,比如销售线索、注册或内容下载。随着公司产品发布节奏加快、广告活动数量增长,手动跟踪哪些在运行、哪些有效、下一步该尝试什么变得越来越困难。
我们着手构建一个能帮助管理这种复杂性的智能体。它会跟踪新产品发布、起草广告活动、添加关键词、测试变体,并向团队提交建议的实验以供批准。随着时间推移,它将作为一个持续学习的循环运行:分析绩效、做出改变、观察结果、记录所学,并将这些洞察应用于未来的广告活动。我们的目标是让营销团队更高效,同时持续提升广告活动绩效。
在这篇文章中,你将了解我们的付费媒体智能体如何工作、如何支持营销团队,以及我们在构建它时对智能体工程学到了什么。
我们已开源了我们的付费媒体智能体,你可以将其作为自己项目的起点。你也可以参加GTM Engineering Live:我们如何构建付费媒体智能体,时间是太平洋时间9月23日上午11点。在本次网络研讨会中,我们将演示该智能体,讲解代码和设计决策,并回答关于将这些模式应用到你自己智能体的问题。
关键成果
- 付费媒体在六个月内从贡献0%增长到我们营销管道的20%。
- 从六月到八月,合格线索成本(CPL)下降了30%,而月度支出增长了约60%。在LinkedIn——我们最大的社交渠道上,CPL比一月份低了40%。
- 通过将分析和报告内部化,而不是依赖代理机构,我们每月节省了约5000美元。
- 我们还通过将计算移入代码并移除不必要的模型调用,优化了智能体本身,使早期报告工作流成本降低约40倍、速度提升13倍,运行时间从18分钟降至85秒。
我们构建了什么
付费媒体智能体是一个长期运行的智能体,驻留在Slack中。每周一,它会将广告平台数据与来自我们数据仓库的线索和管道数据结合起来。它会为每个平台发布一份摘要和品牌化的PDF,解释发生了什么变化、为什么变化,以及团队下一步该做什么。
团队可以在话题中@它,询问关于广告活动、成本或管道的后续问题。它还可以根据我们的行动手册和编码的判断,提出新的关键词、定向调整、广告文案或新的搜索广告活动。

我们如何构建它
我们围绕一个简单的原则构建了这个智能体:编程智能体就是知识工作者。
知识工作通常涉及读取文件、转换信息、运行分析和记录内容。编程智能体也通过文件和 shell 完成这些任务。
我们把这个智能体当作一名新入职的付费媒体分析师。我们给它配备了一台电脑、完成工作所需的软件、对我们数据的访问权限,以及关于我们业务运作方式的文档。

操作系统
我们使用 LangChain Deep Agents 作为智能体框架,这样就不必从零开始构建核心智能体基础设施。就像操作系统一样,Deep Agents 管理对文件、代码执行和工作记忆的访问。它为模型提供工具来规划工作、将任务委派给子智能体,并在任务变得更复杂时管理上下文。这个基础就是智能体框架。我们在其上叠加付费媒体工具、技能和业务知识。
计算机
每次运行都默认有一个 LangSmith Sandbox 可用。它是一个隔离的 microVM,拥有 32 GB 磁盘和一个用于运行命令的 shell。沙箱为智能体提供了一个安全、隔离的环境来执行代码和处理文件,而不会影响其他运行或底层系统。
我们为它配备了 pandas 和 DuckDB 用于分析,openpyxl 用于电子表格,以及 WeasyPrint 和 Jinja2 用于生成报告。除了这些软件之外,还有它的工作数据和业务知识,以 Markdown 格式存储在六项技能和一个十九页的 wiki 中。
为了保持快速启动,我们将软件和业务 wiki 烘焙进一个快照,即沙箱启动时所用的已保存镜像。这将平均启动时间缩短了 10 秒。
💡 不同的智能体需要不同的计算机。我们的内容生成智能体的沙箱更像一个视频编辑工作站,配有 headless 浏览器、ffmpeg、媒体工具和品牌手册。财务智能体可能需要 openpyxl 处理电子表格,以及 DuckDB 进行更重的数据处理。工作性质决定了你如何设计这台计算机。
提供正确的上下文
一旦智能体有了计算机,下一个挑战就是给它正确的上下文。人类分析师需要理解自己的角色、使用的方法、所服务的公司、当前正在发生的事情,以及需要遵循的规则。
最朴素的做法是把所有这些都放进系统提示词中。然而,这会导致提示词过长、每次运行都携带成本高昂,而且很可能过时。
更好的思考方式是:上下文窗口往往才是瓶颈,而不是模型。许多看似推理失败的情况实际上是上下文失败。要么模型缺少正确的信息,要么太多无关信息在争夺它的注意力。
我们不把提示词当作知识存放的地方,而是把它当作一张地图。知识存放在位置可预测的结构化文件中,智能体只加载当前任务所需的上下文。

💡 设计智能体工作空间的方式,值得你像对待所给工具一样认真思考。我们发现,智能体能够通过组合桌面上已有的内容,回答我们从未构建过明确工作流的问题。它有指导调查的 playbook、可供使用的营销活动数据,以及用于分析这些数据的库。设计这个工作空间,成为了设计智能体本身的一部分。
我们将上下文分为五层,下面逐一描述(按每层变化的速度排序):
- 系统提示词:定义智能体的角色和导航方式。我们的提示词以一句话描述智能体角色开头,随后是三个简短部分:如何操作、数字从何而来、如何呈现结果。其余内容都是给智能体的指引,例如操作手册在这里、wiki 在那里、先读索引。提示词告诉智能体去哪里找到它需要的东西。
- 技能:六个指令文件夹,在运行时逐步披露。智能体最初只能看到每个文件夹的标题和描述。
- Wiki:十九个页面,解释我们的漏斗如何运作、每个营销活动旨在达成什么目标、哪个数据源拥有哪个数字,以及团队做出了哪些决策及其原因。
- 实时工具:支出、设置和管道每天都会变化,因此智能体在请求时获取它们。我们有 218 个此类调用。关于如何避免其膨胀上下文,详见下文。
- 确定性代码:任何应当保持一致且可复现的内容,我们都用代码实现,包括计算、日期窗口、账户匹配和硬性保障措施。例如,有一条规则防止智能体在一次糟糕的一周后就砍掉一个顶级管道驱动因素,这条规则在代码中强制执行,因此模型无法覆盖它。最难划清的界限是技能与 wiki 之间。技能解释如何完成工作:读取数据、运行数字、撰写报告、准备变更,并应用解读付费媒体表现的操作手册。它不包含任何我们营销活动特有的内容。

wiki 则是 LangChain 特有的一切:哪个营销活动用于品牌认知、哪个应该驱动演示请求、我们在七月决定了什么,以及为什么。
💡 技能应该能‘在另一家公司也适用’,而 wiki 则不应如此。换句话说,技能捕捉的是可复用的工作方式,而 wiki 包含的是这些技能运作所需的公司特定上下文。
这遵循了 Karpathy 的 LLM wiki 笔记以及我们自己的 Wiki Memory 中的模式。
统一智能体架构
我们最初构建了两个智能体图,因为用户体验看起来不同:
- 周报智能体是定时运行的,且产出物繁重。它使用 Deep Agent、沙箱、大模型和 PDF 生成。
- Slack 需要在几秒内给出答案,因此它在更便宜的模型上使用轻量级循环,配有 Google Ads 和仓库工具,没有沙箱,且为只读访问。
这种拆分只持续了五周。每项新能力都必须实现两次。功能到达 Slack 和报告的时间不同。Slack 无法处理附件,因为它没有沙箱,也无法回答关于周一报告的后续问题,因为这些 PDF 来自另一个图。
错误在于把它们当成了两个产品。它们是同一分析的两个入口,背后是同一个 wiki、技能、工具和来源规则。我们改为为每个请求隔离状态和能力。每个线程都有自己的沙箱和检查点,每次运行只看到它需要的工具。
现在只有一个图,每个请求都全新实例化:
- Slack 提及和周一定时任务以不同的运行模式进入。
- 定时运行只看到一个工具 task(),它按平台委托给一个子智能体。
- Slack 获得更广泛的读取、仓库和营销活动操作工具。

它是同一个运行时,只是能力配置不同,托管在 LangSmith Deployment 上,由后者负责托管、扩缩容和定时运行。而且由于 Slack 现在共享同一套沙箱架构,智能体还能打开报告 PDF,并在生成该报告的会话线程中回答后续问题。
💡 要点:为每个入口点使用同一个运行时并配置相应的能力档案。同一个工厂可以为不同用户提供不同的技能和权限。

关键技术经验
让智能体投入实际工作,让我们在把数字算对、回答我们未曾预料的问题,以及把分析转化为行动方面学到了五条经验。
1. 让模型负责判断,而非计算
我们第一版的周度分析让模型包办一切。我们把每一条广告系列记录、关键词、销售管道记录和落地页检查都加载进上下文,然后让它计算花费、周环比变化、对广告系列表现进行分类,并撰写报告。
它能用,但效率低下。在我们的冻结测试集上,单份报告处理了约 390 万个输入 token,因为模型必须读取所有原始数据并反复自行完成计算。这让每次运行都更慢、更贵,耗时 1,112 秒,成本略高于 3 美元。这也让结果更难被信任,因为模型每次都要负责重新计算底层数字。
我们发现代码更适合做确定性的工作。现在由 Python 获取数据、对齐日期窗口、计算总计和对比、应用固定规则,并把一组紧凑的结果写入沙箱。模型则专注于需要判断的工作:串联证据、解释可能的原因、对照目标评估广告系列,并建议下一步该做什么。
2. 为每个指标定义唯一可信来源
我们有六个平台,它们的 ID、转化定义、归因窗口和广告系列层级各不相同。试图把所有内容归一化成一个完美的 schema,只会增加复杂性,却未必能让数据更可信。
于是,我们定义了每类指标应该信任哪个系统。广告平台是媒体活动(如花费、展示次数和点击量)的可信来源。一旦有人完成转化,我们就依赖数据仓库来获取下游结果,如线索、商机和销售管道。
当一些 Google 视频广告系列无法干净地映射到我们的数据仓库时,我们明白了这一点为何重要。我们的数据仓库使用关键词来关联广告系列数据,但视频广告系列并不总是有可用的关键词。结果,尽管 Google 本身拥有正确的花费数据,我们数据仓库中仍缺失了约 10% 的 Google 花费。Meta 则有相反的局限:它能告诉我们某条广告产生了转化,但我们的数据仓库更擅长告诉我们那次转化究竟是什么,比如是“联系销售”请求还是“注册”。这些例子进一步印证了,我们不应指望单一系统对每个指标都给出最佳答案。
我们把这些可信来源规则编码进了智能体。它们存放在 wiki 中,并且我们会移除那些会让智能体针对给定指标查询错误系统的工具。有了来源边界、转化映射和广告系列层级的定义,智能体就能跨平台工作,而无需一个完美归一化的 schema。
当数据无法可靠地关联时,智能体不会试图填补这些空白。它会保留这些限制,并在回答中附上相关来源、日期窗口和归因模型,以便团队理解每个数字是如何得出的。
💡 要点:你不需要先有一个完美的数据模型,智能体才能跨系统工作。更重要的是定义每个指标以哪个来源为准、把这些规则明确化,并在底层数据无法干净地对账时保留不确定性。
3. 让智能体自行发现工具,而不是预先加载所有内容
回答诸如“我们的广告支出带来了哪些销售管道?”这样的问题需要访问两个系统。广告平台提供支出和点击数据,而我们的 BigQuery 数据仓库将广告活动与网站转化关联到合格线索、Salesforce 商机和销售管道。
我们希望智能体能够同时跨这两个系统工作,而无需加载数百个工具定义,也无需为每个问题编写新工具。
Pipeboard 的 MCP 暴露了 200 多个广告平台工具。早在 6 月,即使是我们较小的只读目录,也需要 38,000 个 token 才能加载可用的工具名称、描述和参数,而这还是在智能体读取用户问题之前。这些上下文大部分与任何单个请求都无关。
我们的数据仓库也有类似的问题。我们为诸如按广告活动查看销售管道或按广告组查看转化等重复性问题构建了固定查询。但每一种新的数据分组方式,例如按单个销售商机查看销售管道,都需要另一个专用工具。
我们通过给智能体一个小型接口来查找所需内容,从而解决了这两个问题。
Pipeboard 的目录由三个工具支撑:
- 搜索:根据问题找到最多八个工具。
- 读取:仅为选定的工具加载完整 schema。
- 运行:通过我们的服务器执行该工具。广告活动写入使用单独的需审批路径。

对于数据仓库,我们添加了两个灵活的工具:
- 描述可用的表和字段。
- 运行分析查询。
智能体可以检查 schema 并组合问题所需的查询,而不必依赖为每种可能的分组预先构建的工具。
该目录将第一轮对话降至约 12,000 个 token。在我们的对比中,它比加载所有 schema 便宜 4 倍,同时保持了相同的评判质量。此后目录规模几乎增长了两倍,而其上下文成本大致保持稳定。
我们在 60 次实际运行中测试了固定数据仓库工具、查询接口以及两者结合使用。固定工具对常规问题效果良好,但会正确地将更深层的问题报告为不受支持。带有查询接口的两个版本都回答了所有分析性问题。
我们保留了这两种方法。固定工具为常见问题提供快速路径,而查询接口则处理我们未曾预料到的问题。
💡 要点:给智能体一种按需查找和查询能力的方法,而不是预先将所有工具都放入上下文中。
4. 明确设计隔离
在迁移到共享运行时后,我们面临另一个挑战:智能体如何在不将每个平台的数据都放入同一个上下文窗口的情况下分析五个平台?
我们在实际数据上测试了三种架构:
- 每个平台一次隔离运行。
- 一个智能体处理所有平台。
- 一个父智能体委托给每个平台一个子智能体。
分离式运行是最简单的架构,但在实际工作流中表现最差。每次运行只能看到一个平台,因此系统会生成多条 Slack 消息,并且难以跨渠道综合表现数据。
两种整合式方案都产出了带有跨平台综合的单一输出。我们最终选择了父代理加子代理的架构,因为它让父代理的上下文保持精简,同时为每个平台提供各自的上下文窗口,以容纳平台特定的数据和注意事项。
但独立的上下文窗口并不会自动带来完全隔离。我们仍然必须自行设计隔离机制。
例如:
- 一个平台可能会意外抑制另一个平台。两个子代理向同一位置写入报告,并共享同一个“完成”标志。一旦第一个完成,第二个就可能误以为该状态属于自己,从而在没有生成报告的情况下停止。我们通过为每个平台分配各自的报告位置和完成状态解决了这个问题。
- 子代理可能会陷入验证自身工作的困境。当某个子代理无法确定其 PDF 是否已渲染时,它会不断检查文件,消耗大量 token,最终试图从头构建 PDF。现在子代理只获得三个工具:读取上下文、计算和渲染。如果渲染成功,任务即告完成。
子代理为你提供了一个独立的上下文窗口。隔离模型的其余部分由你决定。你仍然需要定义它可以使用哪些工具、可以访问哪些文件和状态、必须返回什么,以及如何处理失败。
5. 为代理提供一条从分析到行动的路径
一个只会分析表现的代理,最终不过是一个更好的仪表盘。我们希望代理能帮助团队根据其发现采取行动。
它可以直接在 Slack 中提出更改建议,例如添加关键词、更新地理定向或创建新的搜索广告系列。
赋予代理采取行动的能力也带来了一个新要求:权限。
付费媒体之外的团队可以使用该代理询问广告系列表现和销售管道相关的问题,但只有指定的团队成员才能编辑或批准广告系列更改。服务器在接受任一操作前会检查 Slack 用户 ID。来自其他任何人的请求都会被阻止,提案将保持待处理状态。
每个提议的更改都会出现在一个使用 Block Kit 构建的 Slack 审批卡片中。获得授权的审核者可以比较当前值和提议值、进行编辑并批准最终方案。随后代码会应用已批准的更改,并检查广告平台以确认操作成功。

这为我们带来了有用的职责分离。代理可以分析表现并推荐行动,但由人类控制该行动是否真正被执行。
💡 要点:闭环需要的不仅仅是写入权限。为代理提供一条清晰的操作路径,并内置权限、审批和验证机制。
6. 让界面与工作相匹配
Slack 作为第一个界面效果很好,因为审批卡片可以与促成它的分析和讨论处于同一线程中。跨团队的人可以提问并发表意见,而广告系列负责人仍然控制着实际应用哪些更改。
这种方法最适合相对聚焦的决策。随着代理开始处理更复杂的工作,例如包含许多广告组和创意的广告系列、批量编辑,或需要多轮修订的方案,Slack 作为主要工作空间就变得越来越难用。
我们正在把这些更复杂的工作流迁移到一个围绕 agent 构建的专用界面中,同时保留 Slack 作为一个轻量级的场所,用于提问、查看建议和批准变更。更多内容将在后续文章中介绍。
下一次构建时我们会采纳什么
我们希望有一个 agent 能够处理我们未曾预料到的问题,产出我们可以核实的数字,并对其发现采取行动。以下是我们会带入另一个 agent 的设计原则:
- 像对待新员工一样装备 agent。 给它一个沙箱、有用的库、对正确数据的访问权限,以及清晰的文档。一个设计良好的工作空间能让 agent 无需为每个问题都配备专门的工作流,就能调查新问题。
- 将可复用的指令与公司知识分开。 Skills 说明如何完成工作,wiki 说明业务,实时工具提供当前信息。保持这些层次分离,可以让每一层都更容易更新,而不会让系统提示词不断膨胀。
- 对应当可复现的工作使用代码。 计算、比较和硬性规则应当用代码实现。这样模型就可以专注于解读结果并判断其含义。
- 明确设计边界。 子 agent 仍然需要清晰的规则,规定它们可以访问哪些工具、文件和状态,应当返回什么,以及如何处理失败。独立的上下文窗口只是隔离的一部分。
- 以 agent 能否完成工作为优化目标。 减少 token、成本和延迟很重要,但如果这会让 agent 能力下降就不值得。我们发现,将这些指标与完成率和答案质量一起评估更有用。
- 让真实使用情况告诉你集成需要在哪里改进。 agent 反复难以回答的问题,揭示了哪些地方值得构建更清晰的连接、更好的定义或专用工具。
下一步
目前,该 agent 主要响应定时运行和团队的请求。我们希望它变得更加主动,通过持续监控广告活动表现,呈现值得关注的变更,并提出新的实验和优化建议供团队审阅。
更大的机会在于将这些经验贯穿 GTM 连接起来。广告活动的互动情况可以为销售跟进提供参考,而销售管道进展、销售对话和交易结果可以提升我们对理想客户的理解,并影响下一次广告活动。
随着时间的推移,我们希望我们的 GTM agent 能够为同一套共享知识和 playbook 做出贡献,这样组织某一部分学到的东西就能改善漏斗其余部分的定向、信息传递和实验。
基于我们学到的东西继续构建
参加 9 月 23 日太平洋时间上午 11 点的 GTM Engineering Live:我们如何构建付费媒体 agent。在本次网络研讨会中,我们将演示该 agent,讲解代码和设计决策,并回答关于如何将这些模式应用到你自己 agent 的问题。
你也可以把这个付费媒体 agent 带到你自己的团队中。我们已经将其开源,包括广告平台工具、付费媒体 skills、示例 wiki、报告和审批工作流。连接你的账户,提供你公司的上下文,并使用 Managed Deep Agents 通过一条命令将其部署到 Slack。
来源:LangChain:Blog · langchain.com