过去一年半左右,我一直在研究公司内部“人工智能”的应用,实际上是LLM工具和智能体的应用。我认为,对于当今时代的每位工程领导者来说,这至少都是一项需要认真对待的任务。鉴于公司内部有如此多的人都在研究这个问题,我想把我学到的东西整理成一份“工作笔记”。
这并非一份关于您应该如何操作的建议,而仅仅是对我目前为止解决问题的方法以及我在持续迭代中学到的经验的总结。我希望这里的思路对您有所帮助,或者至少能验证您在部署过程中遇到的一些问题。您阅读得越深入,内容就越具体,最后甚至会涉及到一些非常基础的话题,例如如何让代理可靠地将 Slack 实体的人类可读文本表示形式转换为正确的底层实体的mrkdwn格式。
我们正在招聘:如果您有兴趣与我一起在 Imprint 内部推进智能代理和人工智能的应用,我们正在招聘创始高级软件工程师(人工智能方向) 。理想的候选人是一位产品工程师,拥有一定的智能代理实验经验,并希望在未来一两年内深入研究这一领域。
前期准备:培养我的直觉
作为技术人员,我认为我们对团队应尽的基本责任之一,就是花时间直接使用新工具,从而培养对它们如何运作以及不如何运作的直觉。人工智能的应用也不例外。
为了实现这个目标,我首先阅读了一些资料,特别是 Chip Huyen 的 《人工智能工程》 ,然后投入到一些有界项目中:使用 Claude 代码构建我自己的简易代理平台,创建一个简单的 MCP 来搜索我的博客文章,以及一个用于评论 Notion 文档的代理。
每个项目耗时两到十小时,而且都让我受益匪浅。尤其是工具的使用,在实现一个简单的工具使用代理之前,它对我来说就像魔法一样;而当我实现之后,它就变得非常容易理解和运用,不再像魔法那样神秘莫测了。
我们的人工智能应用策略
Imprint 改进人工智能应用的一般方法是策略测试:确定几个目标,选择初始方案,然后快速迭代细节,直到方案真正有效。在这个舆论压力巨大的时代,高层领导深入细节是我们为数不多的防御手段之一。

加入公司后不久,我便与高管团队合作制定了上述人工智能应用战略。经过一番讨论,我们最终确定了以下几个核心支柱:
- 为推广应用铺平道路,首先要消除推广障碍,尤其是一些必须明确申请才能使用工具的障碍。公司内部和行业对人工智能的应用都充满热情,我们应该相信我们的团队。如果他们没有采用相关工具,我们应该优先考虑如何简化流程,而不是质疑或轻视他们为采用人工智能所做的努力。
- 人工智能的应用机会无处不在,而不仅仅局限于工程、客户服务或其他部门。要想成为一家能够广泛受益于人工智能的公司,我们需要解决所有团队的人工智能应用问题。我并不是说我们应该在所有地方都采用相同的方法,而是说我们需要为每个团队制定一套适用的方案。
- 高层领导以身作则,确保我们所做的一切都是真正有用的,而不是纠结于我们衡量的指标。
正如您从这些原则和我之前的评论中所看到的,我对人工智能应用的最大担忧在于,人们可能会专注于营造一种应用人工智能的假象,而不是专注于提高生产力。表面功夫固然是任何工作的核心组成部分,但几乎所有有趣的工作都发生在表面功夫与现实交汇之处,而这些原则正是为了支撑这一点。
顺便提一下,就《工程战略制定》一书中的战略组成部分而言,这实际上就是战略的政策。此外,我们还运用战略测试来完善我们的方法,制定了一套具体的初始行动方案来付诸实施(这些方案过于具体,不便对外公开),并进行了一些初步探索,以确保我没有过度依赖之前在 Carta 的工作经验。
记录技巧和窍门
我采取的第一步是将尽可能多的内部技巧和窍门案例收集到一个 Notion 数据库中。我对案例的定义非常宽泛,因为我相信展示各种不同的工具使用案例——尤其是在不同职能部门中的案例——既实用又具有启发性。

我不断扩展这个功能,并得到了公司各部门的贡献,它已经成为人类和机器人使用人工智能工具解决问题的有用资源,可以提供建议。
集中我们的提示
我的核心理念之一是,让公司内部用户能够轻松找到提示信息至关重要。可发现性解决了四个不同的问题:
- 让用户清楚地了解提示功能的作用(以便其他人可以借鉴并在类似场景中使用它们)。例如,您可以使用我们的代理在 Notion 文档创建时对其进行评论、在 Slack 频道中高效回复、对 Jira 工单进行分类等等。
- 展示一个好的提示符示例(以便其他人可以改进他们的提示符)。例如,您可以将复杂的配置信息从难以阅读和准确修改的列表中移到表格中。
- 它提供了一个可复制的提示模块库,方便在不同提示中重复使用。例如,您可以复制我们现有的“Jira 问题分类提示”来开始对新的 Jira 项目进行分类。
- 提示信息是团队或职能部门的共同财产,而不是某个人一成不变的产物。例如,我们服务台团队的任何成员都可以改进用于响应服务台请求的提示信息,而不仅仅是某个有权访问提示信息的人。而且,它并不依赖于对 Git 或 GitHub 的熟悉程度(尽管我估计随着时间的推移,我们最终会对编辑最重要的内部代理设置更多限制)。
- 识别重复出现的提示子组件,这些组件暗示着工具缺失或难以使用。例如,我们早期版本的提示在如何指定 Slack 用户和频道方面存在很多混乱,我虽然能够找到解决方法,但其他人却不行。
我的核心理念是,所有客服人员的提示信息都存储在同一个 Notion 数据库中,公司里的每个人都可以查看。大多数提示信息都可以编辑,但有些提示信息设有编辑限制。
以下是一个示例提示,用于将客户支持部门收到的 Jira 问题路由到正确的工程团队。

以下是第二个例子,这次是响应我们基础设施工程团队请求频道中的请求。

几乎所有提示都以一条指令结尾,要求在生成的消息中包含指向该提示的链接。这样可以确保能够轻松地从平庸的回复过渡到由提示驱动的回复,从而进行修正。
采用标准平台
除了收集提示和建议之外,人工智能应用的下一个显而易见的步骤是确定公司内部使用的标准人工智能平台,例如 ChatGPT、Claude、Gemini 等等。
我们为所有用户都选择了 OpenAI。除了平台标准化之外,我们还确保账户配置在第一天就自动完成。对于任何从事 IT 行业或相关领域的人来说,这并不令人意外,许多革命性的通用人工智能应用实际上……都只是账户配置和访问控制。这些看似不起眼的细节,如果不深入研究,很容易让整个计划功亏一篑。
在工程部门,我们也同时提供 Cursor 和 Claude。不过,我们绝大多数的 Claude 使用都是通过 AWS Bedrock 实现的,我们利用 AWS Bedrock 为 Claude Code 提供支持……而且我们对 Claude Code 的使用非常频繁。
其他人工智能工具
尽管整个行业都在大力推广人工智能工具,但我发现绝大多数所谓的“人工智能工具”实际上只是在营销宣传中大谈人工智能的SaaS供应商。我们一直在继续采用这些供应商的产品,但同时也在内部帮助团队评估哪些“人工智能工具”真正有意义。
我们已经花了不少时间深入研究如何将人工智能工具集成到聊天和交互式语音应答工具中,但这完全是另一篇文章的内容了。
指标
衡量人工智能的采用情况,就像所有衡量指标一样,充满了挑战。总的来说,我发现衡量工具的采用情况非常有助于找到应该问的正确问题。为什么你没有使用 Cursor?或者 Claude Code?或者其他什么工具?这些都是值得深入探讨的问题。我尽量每月至少查看一次使用数据,尤其关注以下两个问题:
- 对于电力用户来说,他们实际在做什么?他们为什么觉得电力有用?
- 对于低采用率或非采用者而言,他们为什么不使用这些工具?我们如何才能帮助他们解决这个问题?
从根本上讲,我认为那些不采用工具的人是理性的反对者,花些时间了解这种(表面上的)抵制行为比自上而下的强制推行更有效。我认为这通常是一个很容易弥合的教育差距。或许在某个时候,我会发现一个收益递减点,届时进展停滞不前的原因在于人们拒绝使用人工智能工具——或者因为人工智能工具本身并不真正有用——但我尚未找到这个点。
构建内部代理
接下来的几节将介绍如何构建内部代理。核心实现是一个无状态的 lambda 函数,用于处理各种 HTTP 请求,类似于 Zapier。目前该函数使用 Python 编写,代码大约有 3000 行,其中很多代码用于处理一些特殊情况,例如格式化 Slack 消息等等。
需要说明的是,我最初尝试过在 Zapier 中实现这个功能,但我发现 Zapier 无法提供我认为有效实现此功能所需的精确度。此外,我认为 Zapier 对非技术用户来说也不太友好。
是什么推动了这种做法的普及(尤其是对代理商而言)?
作为一名长期从事平台工程工作的人,我仍然相信只要搭建好平台,用户自然会来。的确,我认为如果问题对用户来说足够棘手,就会有一小部分早期用户加入,就像Uber 2014 年的服务迁移那样。
然而,我们发现真正能有效推动产品普及的方法恰恰相反。真正奏效的是平台工程和传统产品工程的结合:
- (产品工程)找到一个充满挑战或潜在影响的工作流程
- (产品工程师)与领域专家紧密合作,确保第一个版本正常运行。
- (平台工程)确保所使用的解决方案能够被团队扩展。
- (两者)监测采用情况,以此作为问题解决方案是否匹配的指标
以下是一些我们在内部取得进展的项目示例:
- 编写软件时,应使用有效的
AGENTS.md文件来指导测试、类型检查和代码检查工具的使用。 - 通过聊天和交互式语音应答系统 (IVR) 解答客户的初步疑问
- 通过路由聊天机器人,引导问题以解决问题、提供答案或通知正确的响应者。
- 对收到的工单进行问题分类:添加标签,并将其分配给相应的团队
- 就日常合规和法律问题(例如经常出现且偏差很小的问题)提供实时初步反馈
- 每周根据各种资源(Git提交、Slack消息等)编写优先级更新报告
所有这些成功的项目,其成功模式都与“搭建平台,用户自然会来”截然相反。相反,它们需要与那些在构建人工智能代理和使用人工智能工具方面经验丰富的人员进行深度合作,才能取得进展。在重要或类似生产环境的工作流程中有效应用人工智能的学习曲线仍然相当陡峭。
配置代理
使用功能强大的工具的智能体会带来复杂的配置问题。首先,暴露过多的工具——尤其是提示编写者不熟悉的工具——会极大地影响可靠工作流程的构建。例如,我们有一个 ` exit_early命令,允许提前终止智能体:这在很多情况下非常有效,但也容易导致机器人崩溃。类似地,我们有一个slack_chat命令,允许跨频道发布消息,这可以支持各种有用的工作流程(例如,将一个频道中的问题“热接”到更合适的频道),但也可能导致垃圾信息泛滥。其次,随着工具功能的增强,它们可能会引入复杂的安全问题。
为了解决这两个问题,我们目前将配置存储在经过代码审查的 Git 仓库中。以下是一个 JIRA 项目示例。

以下是指定 Slack 回复机器人的另一种方法。

与 JSON 文件相比,我们可以静态地定义配置,并且易于扩展。例如,我们可能希望扩展slack_chat以限制特定机器人可以发布到哪些频道,这很容易实现。目前,大多数智能体唯一不在 Git 版本控制范围内的内容是提示本身,这些提示由 Notion 进行版本控制。但是,我们可以轻松地要求特定智能体在敏感场景下使用 Git 管理的仓库中的提示。
通过测试、代码检查和类型检查后,配置将自动部署。
解析外键
说起来有点好笑,但实际上,真正阻碍我们轻松编写有效提示的一件事是,我们很容易输入像@Will Larson这样的内容,而这些内容随后会被转换成<@U12345>或 Slack 中针对特定用户、频道或用户组的相应标识符。同样的问题也存在于 Jira 群组、Notion 页面和数据库等等。
这正是集中化提示信息的一个绝佳例子。我之前习惯于自己提取唯一标识符,但显然大多数人并不习惯。最终,我们开发了三个用于 Slack 解析的工具: slack_lookup ,它接受一个待查找的引用列表; slack_lookup_prefix ,它查找所有以给定前缀开头的 Slack 实体(例如,它可以提取所有以@oncall-开头的频道或群组,而无需在提示信息中硬编码列表);以及slack_search_name ,它使用字符串距离来查找潜在匹配项(同样,它有助于处理拼写错误)。
如果这听起来令人困惑,主要是因为 Slack 没有公开用于此类查找的相关 API。Slack 的 API 需要使用 ID 来检索用户、群组和频道,因此您必须维护自己的缓存才能执行查找。执行查找操作本身就很繁琐,尤其是对于用户而言。Slack 用户至少有三种引用方式: user.profile.display_name 、 user.name和user.real_name ,但对于任何给定用户,只会设置其中的一部分。据我所知,正确的逻辑是,首先查找与user.profile.display_name匹配的用户,如果存在则使用该用户。然后对user.name执行相同的操作,最后查找user.real_name 。如果您选择第一个与这三种方式之一匹配的用户,则在某些情况下会使用错误的用户。
除了为LLM提供名称解析工具外,我还对每个响应进行最终的强制性检查,以确保返回的引用指向真实存在的项目。如果不是,我会将无效的引用注入上下文窗口,并执行一个仅包含实体解析工具的额外代理循环。这听起来很荒谬,但只有到了这一步,一切才真正开始稳定运行。
顺便说一句,我对这些截图感到很尴尬,今天早些时候,我对 Notion 页面和数据库做了和之前对 Slack 所做的相同的更改。
格式化
与外国实体解析类似, Slack 的mrkdwn Markdown 变体和 JIRA 的Atlassian 文档格式也存在类似的问题:它们都是严格的。
现在调用这些 API 的工具对格式有严格的要求。这些要求原本包含在各个提示信息中,但现在每个提示信息中都会出现,所以我知道需要将它们整合到代理框架本身,而不是强迫每个提示信息编写者都去理解这个问题。
我猜我需要添加一个类似于我为实体解析添加的验证步骤,而且在我这样做之前,我还会继续遇到一些非常罕见但很烦人的渲染问题。说实话,我个人并不介意这些渲染问题,但这会给其他使用代理的人带来很多不确定性,所以我认为解决这些问题是必要的。
日志记录和调试
如今,所有日志,尤其是工具使用日志,都会被汇总到两个地方。首先,它们会进入 Datadog,以便全面了解日志内容。其次,对于非工程师来说,这可能更有用,因为它们会被汇总到 Slack 频道#ai-logs中,从而可以清楚地看到使用了哪些工具以及使用了哪些(可能经过截断的)参数。
从长远来看,我估计这最终会通过专门的内部网页用户体验来实现,但总的来说,我发现那些积极开发代理的人员都比较愿意容忍一些冗余功能。同样,那些不直接开发代理的人员也不太在意这些,他们希望每次都能完美运行,所以不会花时间查看日志。
最大的不足之处在于:缺乏一个通用的平台来访问用户范围的MCP服务器。
目前我看到的最大内部机遇在于,如何让非工程师也能获得与在本地运行 Claude Code 并接入他们常用的 MCP 服务器相同的体验。我一直希望 ChatGPT 或 Claude.ai 能提供这种体验,但它们都还不够完善。Claude Desktop 虽然接近目标,但配置起来略显繁琐。我们正在寻找一款能够让公司内部所有员工轻松定制并日常使用的工具。
我还在寻找合适的工具。如果有人能提供一些不错的建议,并且这些建议能够让我们比较有把握地认为两年后仍然有效,而且不需要向一家初创公司发送大量内部数据,那么我很想听听大家的意见!
接下来是什么?
好的结论应该以一个精彩的轶事开头,用全新的视角阐明你的论点。我不确定自己能否达到这个标准,但对我来说最重要的四个观点是:
- 人工智能的应用仍处于早期阶段,因此关注学习速度比其他任何因素都更有价值。
- 如果你想领导一项内部人工智能计划,你就必须使用相关工具,而且不仅仅是ChatGPT,而是要仅使用 LLM API 构建你自己的工具代理。
- 我的经验是,真正将人工智能应用于实际问题是一个复杂的过程,涉及以下几个方面:问题领域的具体情况、人工智能工具的使用经验,以及传统的IT问题。任何不以这三者为基础的内部人工智能推广计划,我都深表怀疑。对于初创公司来说,这是一个优势,因为你通常可以在一个人身上找到这三方面的特质,或者至少可以在两个人身上找到。但在规模较大的公司,你需要三个不同的部门协同工作,这本身就非常困难。
- 我认为模型选择非常重要,但任何特定时刻你只需要两到三个模型,而且任何人都能告诉你这两到三个模型是什么。例如, GPT-4.1在快速遵循规则方面表现极其出色,对于大多数对延迟敏感的智能体来说,它是一个非常棒的模型。
我很想知道其他人发现了什么!