How do you build a company harness? We've built internal agents at LangChain across marketing, sales, and engineering, and they have completely changed how those teams work. They weren't easy to get right. We spent a lot of time solving the problems that come with a multiplayer harness, and every team landed on the same core primitives: It lives where people already work (for us that's Slack). It knows who's asking and acts OBO that person for some services and with its own identity for others. It has memory, scoped globally and/or at the user level. Code runs in a sandbox and can make requests to services which require auth. A large % of its runs are scheduled rather than explicitly invoked by someone (ambient agents!!).
怎么建一个公司 harness?我们在 LangChain 内部跨营销、销售、工程建了 agent,它们彻底改变了这些团队的工作方式。做对并不容易——我们在「多人 harness」的问题上花了大量时间,而每个团队最后都落在同一套核心原语上:**住在人们已在工作的地方**(对我们是 Slack);**知道是谁在问**,对某些服务代表这个人行事(OBO,on-behalf-of)、对另一些用自身身份;**有记忆**,按全局和/或用户级划作用域;**代码跑在沙箱里**、能请求需要认证的服务;**大比例的运行是定时的**而非某人显式发起(ambient agents,环境化 agent!)。
LangChain Internal Agents · LangChain 的内部 Agent
To ground this discussion, a brief overview of the three main agents we have at LangChain. GTM Agent: a proactive, always-on agent that assists with GTM activities. Monitors and responds to emails, to new qualified leads, sends daily briefs, can answer questions about accounts, can run outbound motions. OpenSWE: our engineering agent, can work on and draft PRs, but also runs code review over all PRs. Content Studio: our marketing agent, can draft assets (blogs, images, PowerPoints, videos) in our style and with knowledge of our positioning.
把讨论落到实处,先看我们的三个主力 agent。**GTM Agent**:主动型、全天候的上市(go-to-market)助手——监控并回复邮件与新合格线索、发每日简报、答账户问题、跑外联动作。**OpenSWE**:工程 agent——能上手写 PR 草稿,也对全部 PR 跑代码审查。**Content Studio**:营销 agent——按我们的风格、带着定位知识产资产(博客、图像、PowerPoint、视频)。
All of these agents are built in the same way. We think this is a general recipe for building company harnesses.
这三个 agent 全部用同样的方式构建。我们认为这是建公司 harness 的通用配方。
Problem: User Experience · 问题:用户体验
All our agents live where people already work, which for us is Slack. They each have their own Slack apps, and can be DM'd or tagged in a channel. One benefit of working with these agents in channels is that others can see how people use it.
我们全部 agent 都住在人们已在工作的地方——对我们是 Slack。各有自己的 Slack app,可以私信也可以在频道里@。在频道里与这些 agent 协作有个额外红利:**别人能看到别人怎么用它**。
One nice thing we added was the concept of "breaking" out a conversation in Slack. Oftentimes, a great conversation would be happening and you'd want to add in your agent to get their opinion or get them to do something. But if they ran in that thread it would pollute the human conversation and distract. So we added an easy way for agents to "breakout" into their own thread in the channel.
我们加的一个好东西是 Slack 里的「分场」(breakout)概念:常常一场好对话进行中,你想拉 agent 进来听它的意见或让它干点什么——但若它直接跑在那个线程里,会污染人类对话、造成干扰。所以我们让 agent 能一键「分场」到频道里自己的线程去跑。
There are some user experiences that are best NOT done in Slack. For example, when reviewing emails GTM Agent wants me to send, it's fine to do that in a one-off way in Slack, but if there is a big backlog it's not a fun experience at all to track those from Slack messages. For experiences like that, we did end up building a custom UI.
也有些体验**不该**在 Slack 里做。比如审查 GTM Agent 想让我发的邮件:偶发一条在 Slack 里处理没问题,但积压一大堆时,靠 Slack 消息跟踪它们毫无体验可言——这类场景我们最终自建了定制 UI。
Problem: Identity · 问题:身份
The thorniest and trickiest problem we tackled was identity, specifically: when these agents take actions, who do they take actions on behalf of? There are two main ways this is handled in the industry: On-behalf-of — the agent acts on behalf of the user invoking the agent. Fixed credentials — there is a fixed set of credentials that the agent uses no matter who is invoking it (eg a service account).
我们处理过的最棘手问题是身份,具体说:这些 agent 采取行动时,**代表谁**行动?行业里有两条主路:**OBO(on-behalf-of)**——agent 代表调用它的用户行事;**固定凭证**——无论谁调用,agent 都用一组固定凭证(比如服务账号)。
This is how we handled it for each agent. When you message it, it acts on behalf of you (eg will open up PRs with your GitHub handle). When it runs in background (for example, as a code review agent) it acts with its own identity (GitHub app). It has some tools (eg Salesforce access) where it uses a fixed identity, so not everyone has to log in. It has some tools (eg email) where it acts on behalf of the user invoking the agent. These tools are ONLY available in DMs. In shared channels, they are not available. It has some tools (eg Notion) where it acts on behalf of the user invoking the agent. It has some tools (eg Twitter) where it uses a fixed set of credentials, in this case for our company Twitter account. Only a whitelisted set of users can invoke certain operations here though. Eg not everyone can post to Twitter (they may only be able to read/draft).
我们对每个 agent 是这样处理的:你私信它时,它代表你行事(比如 PR 开在你的 GitHub handle 下);它在后台运行时(比如作为代码审查 agent),用自身身份行事(GitHub app)。有些工具(如 Salesforce 访问)用固定身份——不必人人都去登录。有些工具(如 email)代表调用者行事——**且只在私聊(DM)里可用,共享频道里禁用**。有些工具(如 Notion)代表调用者行事。有些工具(如 Twitter)用一组固定凭证(我们的公司 Twitter 账号)——但只有白名单用户能执行部分操作:不是人人都能发推(多数人只能读/起草)。
Problem: Memory · 问题:记忆
All agents have two tiers of memory: Global memory — memory that applies to all users. User memory — memory that only applies to the specific user. Agents decide which facts they want to remember to which level of memory. This is probably the least explored area so far — we have a lot of work we want to do here!
全部 agent 都有两级记忆:**全局记忆**——对全部用户生效;**用户记忆**——只对特定用户生效。agent 自己决定把哪些事实记进哪一级。这大概是迄今探索最浅的区域——我们还有一堆想做的!
Problem: Code Execution · 问题:代码执行
All three of our agents can write and execute code, and often need to in order to accomplish tasks. They all follow the pattern of running outside the sandbox, but connecting to it and executing code in there. They all have slightly different base images with different dependencies. OpenSWE (the most coding related agent) is intelligent about which base image it spins up (differs based on channel/user). They all take advantage of the secret proxy on LangSmith Sandboxes to let the agent connect to services in a safe and secure way from inside the sandbox itself.
三个 agent 全都能写代码并执行,且经常需要这样才能完成任务。它们都遵循同一模式:跑在沙箱之外、连接沙箱并在其中执行代码。各有稍有不同的基础镜像与依赖;OpenSWE(编码最重的 agent)会智能选择起哪个镜像(按频道/用户而不同)。它们都用 LangSmith Sandboxes 的 secret proxy,让 agent 从沙箱内部安全地连接服务。
Problem: Scheduled Runs · 问题:定时运行
A large percent of runs are scheduled or triggered in the background by events, rather than being directly kicked off by a user. Some of these are set up by the developer of the agent. For example: OpenSWE listens for PRs and when a new one is created it reviews it. Others of these are set up by the user asking the agent to do so. For example: I asked GTM agent to send me a daily brief, and it created its own cron to do so.
大比例的运行是定时或事件在后台触发的,而非用户直接发起。一部分由 agent 的开发者设置:比如 OpenSWE 监听 PR,新 PR 一建就审查。另一部分由用户叫 agent 自己设置:比如我让 GTM agent 每天给我发简报——它给自己建了个 cron。
All built on Managed Deep Agents · 全部建在 Managed Deep Agents 上
All of these agents are built on Managed Deep Agents, which sits on top of the open source Deep Agents harness. It provides infrastructure to solve all these problems (channels, crons, sandboxes, memory, identity) while providing enough flexibility to customize agent behavior as needed. Try it out today with the quickstart!
这些 agent 全部建在 Managed Deep Agents 上——它位于开源 Deep Agents harness 之上,把上述问题的基建(渠道、cron、沙箱、记忆、身份)全部供给,同时留足按需定制 agent 行为的灵活性。今天就能用 quickstart 上手试!