大多数公司都表示自己想要“采用人工智能”。但实际上,这通常意味着在网站上添加一个聊天机器人而已。

而那些使用人工智能编码工具的工程师们则遇到了完全相反的问题。人工智能编写代码的速度很快,但没有人能够完全信任它的输出结果,因此每个人都需要仔细检查每一行代码,这样一来,编码效率就大大降低了。

这两个问题其实根源相同:人工智能缺乏必要的框架结构。它没有必须遵守的检查标准,也无法访问你的公司实际使用的数据。构建这样的框架结构是一门被称为“治理工程”的学科,而这篇文章正是要教你如何去做这件事。

我是一名全栈工程师,专门负责开发贷款系统。我们之前的文档编写工作与代码本身越来越脱节,于是我决定用Claude Code来解决这个问题。最终让这个方案得以成功实施的,并不是什么更先进的模型,而是合理的结构与完善的管控机制。

在30天的时间里,我构建了一个内部文档平台的第一版版本。其中大部分代码都是由人工智能生成的,而这些代码还受到一系列自动检查机制的保障。后来,我又为这个平台添加了Model Context Protocol服务器,这样一来,人工智能就能以与人类操作者相同的权限来阅读和编写公司的文档了。

经过多轮改进和调整,在第50天的时候,公司正式采纳了这个方案。从需求收集、开发工作到文档管理,所有流程都通过这个平台进行,它已经成为新项目开发过程中唯一的权威信息来源。

这篇文章并不是一份产品使用指南,而是旨在帮助你理解背后的思维方式以及如何将这些理念应用到实际工作中去。

以下内容您将会学到:

  • 什么是治理工程?用简单的语言来解释

  • 哪四项机制能够让人工智能完成大部分生产系统的开发工作

  • 什么是MCP服务器?为什么它比聊天机器人更重要

  • “只有追踪到的事物才能得到改进”这一原则,为何是构建以人工智能为核心的公司的重要基础

  • 如何在自己所在的公司中开始实施这些方法

目录

什么是治理工程

人们通常使用人工智能编码工具的方式是这样的:你提出需求,它生成一些代码,然后你需要仔细检查每一行代码,因为你不信任它的输出结果,之后你再修改错误之处,重复这个过程。虽然人工智能的速度很快,但人工审核却成了瓶颈,因此整体效率并没有得到提升。

“框架工程”彻底改变了工作方式。与其逐行审查代码,不如为智能体构建一个适合其运行的环境。

这个概念源自OpenAI。在一篇名为《框架工程》的文章中,他们的团队描述了一项为期五个月的实验:在实验过程中,Codex智能体编写了大约一百万行的生产环境所需代码,而没有任何一行代码是人工编写的。

他们将“框架”定义为“包括各种支撑结构、约束条件以及反馈机制在内的完整环境”,这种环境能够让智能体稳定地运行。在他们设定的环境中,这些要素包括代码仓库的结构、持续集成配置、格式规范、项目说明以及各类工具的集成。工程师的工作重点也从编写代码转变为设计这样的环境。

这种理念在我们这里也是这样应用的。OpenAI是与一个工程师团队合作,在百万行代码的规模上实施了这一方法;而我则是独自在一个内部工具上使用这种方法,设置了四项自动检查机制,让智能体在每次运行前都会读取规则文件,同时我也养成了通过运行应用程序来验证每项更改是否正确的习惯。虽然使用的工具和配置较为简单,但效果依然不错。

你不再信任人工智能本身,而是开始信任为它构建的环境。

这彻底改变了你的工作内容——你需要花时间设计各种检查机制、编写规则,并从更高层面审查系统的运行结果;而智能体则会在你搭建好的环境中执行任务。

正因为如此,某个工程师的作用就变得极为重要了。如果没有人信任智能体产生的结果,那么它的运行速度再快也无济于事;而良好的框架才能将这种速度转化为可信赖的结果。只要构建了一个完善的框架,一个人就能完成原本需要一个团队才能完成的工作。

所有这些措施都不需要获得公司的批准。我使用的框架所包含的要素,都是每个工程师都已经熟悉的工具:类型检查器、测试运行工具、代码覆盖率分析工具,以及一份记录规则的文本文件而已。

针对现实问题而设计

我所指出的这个问题,是每家公司都会遇到的。首先会制定出技术规范或需求文档,开发人员再根据这些文档进行编码。但在代码审查、测试以及生产环境维护的过程中,代码又会发生变化。由于种种原因,没有人会回去更新那些规范文件,结果六个月后,这些文档描述的系统就已经与实际情况不符了。

大多数公司对此都习以为常,但在某些受监管的行业里,这种情况是不可接受的。你必须清楚当前的实际状况,有时还需要能够证明哪些内容发生了变化、变化发生在什么时间、又是谁进行了修改。如果一份文件已经不再反映现实情况,那它就会成为一种业务风险。

因此,我们的案例研究是围绕一个内部文档平台展开的,其设计目标就是让文档能够在失效之前自动提醒人们注意。

每份文档都会明确说明其所涵盖的代码路径。持续集成系统中有一个小脚本会自动将代码变更信息报告给该平台,因此任何在最后一次编辑后代码内容发生变化的文档都会被标记为“已过期”。我们还添加了审批流程:如果文档在获得批准后又被修改,相应的审批状态会变为琥珀色;同时还会为每份文档生成健康状况评估报告,并提供汇总信息,帮助负责人了解哪些地方需要关注。

五十天,300多次代码提交,而这些代码的大部分都是由Claude Code在自动化测试框架中编写完成的。这个计划本来就是我的主意。我们之前已经使用常规的wiki系统工作了好几年,所以我非常清楚哪些功能还缺失,需要开发什么。实际上,是自动化脚本在编写这些代码;而这些代码提交本身并不是这篇文章的重点——它们只是证明这种方法确实有效的证据罢了。

四道关卡

自动化脚本所做的每一处修改,在最终被应用之前都必须通过四道关卡的审核。这些关卡并没有什么特别复杂的地方。

第一道关卡:类型检查器

我们需要对整个代码库执行`tsc –noEmit`命令;任何存在类型错误的修改都无法通过这一关卡的审核。这道关卡的成本最低,但却能捕捉到许多自动化脚本所犯的错误。

第二道关卡:100%的逻辑测试覆盖率

核心业务逻辑中的每一行代码、每一个分支以及每一个函数都必须有对应的测试用例,否则构建过程就会失败。对于人类团队来说,这样的要求确实显得过于严格;但对于自动化脚本而言,这却是完美的要求。首先,这些规则都是明确的、非可协商的——如果没有相应的测试用例,那就意味着这个功能还没有被实现。其次,自动化脚本没有自我意识,它从不会认为某个测试是多余的;它会把测试覆盖率报告当作待办事项清单来执行。

第三道关卡:端到端测试

“Playwright”测试套件会以用户实际使用应用程序的方式来进行测试。单元测试主要是用来检查单个功能模块的逻辑是否正确;而端到端测试则用于验证用户实际操作时会遇到的各种情况。

我之前曾经写过关于使用通俗易懂的断言语句进行测试的内容,这里的原理也是如此。端到端测试会验证用户实际看到的结果,而不是代码本身预期的行为。

第四道关卡:通过运行来验证

每次有修改发生之后,自动化脚本都会启动应用程序,并观察其行为是否真的发生了变化。这个步骤听起来似乎很显然,但实际上在很多地方都被忽视了。只有当所有的测试都通过,且修改的效果确实得到了验证,才能自信地将这些变更发布出去。测试可以确认代码的逻辑是否正确,而实际运行应用程序则可以验证这些修改是否真正产生了预期的效果。

这套自动化测试框架还包括两个文本文件。其中一个位于代码仓库中,它包含了整个系统的架构结构、每个功能模块的开发步骤,以及一些我之前已经拒绝采用的方案及其原因。每次新的自动化脚本会话开始时,都会先读取这个文件,这样就能确保它的行为保持一致性,避免重复提出那些不合理的方案。

另一个文本文件则是用来记录每个功能的使用说明的。这些说明是由自动化脚本自己编写的,用于展示该功能的具体使用方法。让自动化脚本编写使用说明,实际上是在迫使它真正去使用自己所开发的代码——这是我见过最简单、最有效的集成测试方式了。

需要注意的是,这套自动化测试框架并不包括代码格式检查工具。对于由自动化脚本编写的代码来说,风格问题并不会导致任何错误;真正需要关注的是那些看似正常但实际上从未被测试过的分支。把测试资源花在验证代码的实际行为上,而不是格式问题上,才是正确的做法。

这套框架失效的地方

我想坦诚地谈谈这些局限性,因为正是这部分内容被大多数关于人工智能的文章所忽略。

项目中最严重的错误竟然通过了所有的检测环节,而我是通过亲自使用该平台才发现了这个问题的。当我修改了一个文档的名称后,文档的路径信息发生了损坏,导致页面无法正常加载。

进一步深入研究修改名称的相关代码后,我发现更严重的问题:系统会根据部分数据重新生成记录,而那些在数据中缺失的字段会被自动重置为默认值。其中有一个字段用于控制哪些人能够查看该文档,因此这次修改导致原本受限制的文档被所有人看到了。这种设计在类型安全性和覆盖范围上看起来都是正确的,但实际上却存在严重问题,因为所有的测试都只检查了数据中包含的字段,而完全没有检测那些被遗漏掉的字段。

正是因为我使用了自己的产品,才发现了这个错误,而不是通过任何检测环节。这就是软件工程中的现实情况:某些检测机制只能捕捉到那些你认为需要被检测的错误类型,而只有通过实际使用产品并审查其输出结果,才能发现其他问题。两者都是必不可少的。软件框架并不会取代你的判断力,而是会将你的判断力用在真正关键的地方,而不是每一行代码上。

什么是MCP服务器以及为什么你应该关注它

到目前为止,我们所讨论的内容都是关于如何利用人工智能来开发软件。而故事的后半部分则探讨的是你的企业应该如何运用人工智能技术,而这时MCP服务器就派上了用场。

MCP(模型上下文协议)是一种标准机制,可以让人工智能代理访问各种系统。你可以把它想象成企业工具之间的一个“USB接口”:任何支持这种协议的代理都可以连接到任何提供相应功能的系统中,从而读取数据、执行操作或完成相关工作。

我为这个文档平台配置了一台MCP服务器,上面集成了50多种工具。用户可以通过它搜索文档、阅读页面内容、编写新内容、发表评论,或者检查系统中的异常情况等等。公司里的任何工程师都可以将自己的人工智能代理连接到这台服务器上,这样他们的代理就能直接与企业的知识库进行交互了。

第一次设计这个安全机制时我犯了一个错误,但这个错误值得分享,因为其他人也可能会犯同样的错。最初的版本让代理可以直接且无限制地访问数据库。虽然使用起来很方便,但却存在三个严重问题:首先,所有代理的操作都是匿名的;其次,代理可以读取用户本无权限查看的文档;最后,也没有任何办法来撤销代理的访问权限。
为了解决这些问题,我修改了MCP服务器的设计方案:现在这台服务器本身不保存任何用户的认证信息。每个用户都会在自己的个人账户中生成一个专属的访问令牌,而代理的所有操作都是以该用户的身份进行的,并且会严格遵循该用户的权限设置。例如,初级员工的代理只能阅读和发表评论,而编辑员的代理则可以编写新内容。所有操作都会以真实用户的名义被记录在审计日志中,一旦撤销了用户的令牌,代理就会立即失去访问权限。
我最喜欢的一点是,这种机制与基于角色的访问控制机制相结合后效果非常好。令牌本身并不包含任何权限信息,它只用来标识用户身份。服务器会在每次请求时根据用户当前的角色来检查其权限。因此,当用户的角色发生变化,或者某个团队的访问权限被调整时,根本不需要去逐一查找并撤销现有的令牌。代理的列表中可能仍然会显示那些可用的工具,但一旦用户的角色不再允许其使用这些工具,服务器就会立即阻止相应的操作。

以下是这种机制在实践中的具体表现。这是我从服务器中提取的一个工具的简化版本,它使用了官方的TypeScript SDK。整个服务器其实就是将这一模式重复50次而已。

import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
import { z } from "zod";

const API = process.env.WIKI_API_URL; // 你的HTTP API地址
const TOKEN = process.env.WIKI_TOKEN; // 用户的个人访问令牌

const server = new McpServer({ name: "docs-wiki", version: "1.0.0" });

server.registerTool(
"read_doc",
{
description: "根据文档的slug来读取该文档的内容",
inputSchema: { slug: z.string() },
},
async ({ slug }) => {
// MCP服务器本身并不保存任何用户的凭证信息。它只会将用户的访问令牌转发给API,而API会在每次请求时检查用户当前的权限。
const res = await fetch(`${API}/docs/${slug}`, {
headers: { Authorization: `Bearer ${TOKEN}` },
});

if (res.status === 403) {
// 当请求被拒绝时,系统会返回一个明确的错误信息,而不会导致程序崩溃,也不会隐藏失败的结果。
return {
content: [{ type: "text", text: "错误:禁止访问。" }],
isError: true,
};
}
if (res.status === 404) {
// 如果用户无权查看某份文档,系统也会返回相同的错误信息,因此这份文档的存在不会被泄露。
return {
content: [{ type: "text", text: `没有找到该文档:${slug}` }],
isError: true,
};
}

return { content: [{ type: "text", text: await res.text() }] };
}
);

await server.connect(new StdioServerTransport());

在这个简单的代码示例中,有三点因素决定了其安全性:首先,服务器本身没有访问数据库的权限,因此根本没有什么可以被窃取的数据;其次,用户的访问令牌会随每个请求一起被发送,这样API就能根据用户的真实权限来执行操作,同时也能生成准确的审计记录;最后,对于各种错误情况,系统都会给出明确的错误信息——例如,当用户无权访问某份文档时,系统会显示“禁止访问”的错误消息,而当文档确实不存在时,也会显示出相应的错误信息。

背后的原则很简单:要让AI使用你的权限模型,而不是为它提供隐藏的后门。正是这个设计决策,使得公司能够信任由AI生成的文档。AI所做的任何事情,其实都在人类能力范围之内。

一旦AI能够安全地生成文档,情况就发生了变化。文档编写不再只是开发环节后的附加任务,而成为了开发过程不可或缺的一部分。当AI完成某个功能的开发后,它会使用相同的工具来编写文档,并会在那些不确定的内容旁边加上[!VERIFY]标记;而对于那些涉及费率或合规性要求的内容,则会加上[!SME]标记,这样在获得专家确认之前,这些内容就无法被批准通过。AI提高了效率,而人类则依然掌握着最终的决策权。

只有跟踪了什么,才能改进它

以下就是推动这一切发展的核心理念:只有那些被记录下来的内容,才有可能得到改善。

我们的文档之所以会过时,并不是因为人们疏于管理,而是因为根本没有任何机制来检测这些文档是否已经过时。一旦我们将“文档内容的变更次数”这类数据纳入跟踪范围——比如“自从上次修改后,这份文档的代码已经更改了3次”——那么让文档保持最新状态就变成了一项有明确目标、能够被有效执行的任务,而不再是一个模糊不清的愿望。

当我开始留意这些现象时,发现它们其实无处不在:

  • AI助手那些无法回答的问题都会被记录下来。一个懂得“何时该不回答问题”的助手,会将自己所不了解的内容转化为数据。这份清单实际上就是按照实际需求排序的、接下来需要编写内容的优先列表。

  • 每份文档的健康状况数据能够显示哪位负责人工作负担过重,以及知识库中的哪个部分需要重点关注。

  • 审计日志会详细记录每一项操作的历史信息。当我们需要证明某项内容在何时、由谁进行了修改时,只需进行一次查询即可获得所需信息,而无需花费大量时间进行繁琐的调查。MCP也能利用这些日志来对比不同版本的文档。

实现这一切并不需要高级的人工智能技术,只需要将数据以结构化的方式保存下来,而不是让它们散落在聊天记录和收件箱里。

这就是我对“真正以人工智能为核心的公司”的定义:这样的公司并不是指那些配备了聊天机器人的企业,而是那些其业务流程能够产生可被追踪的数据、并且其工具也能通过像MCP这样的系统被工作人员有效利用的公司。

一旦这两个条件得到满足,人工智能就能发挥它真正的优势——它能处理比任何人类都能承受的更多数据,并帮助我们发现各种规律:哪些工作堆积了大量未完成的任务,哪一步是大家等待的关键环节,哪些内容正在逐渐过时。这样,我们就不再需要猜测瓶颈所在了,而是能够直接获取这些信息。

你们的公司每天都在产生这些数据,问题在于这些数据是否被保存在工作人员可以方便查阅的地方。

如何在自己创办的公司中实施这些措施

你并不需要上级的授权或命令,我当初也没有这样的支持。以下是我会遵循的步骤:

  1. **选择一个让所有人都很烦恼的问题入手。** 比如文档过时、工单需要人工分类处理、没有人编写发布说明等等。从小处着手总比从宏观战略层面开始更容易取得成效。

  2. **确保这些数据可以被追踪记录。** 数据必须结构化、带有时间戳,并且要明确指定负责人。虽然这个步骤可能比较繁琐,但却至关重要。使用电子表格也是一个不错的起点。

  3. **在开发具体功能之前,先建立相应的数据收集机制。** 确定某项变更必须满足哪些检查条件,编写相应的规则文件,然后让工作人员在这个框架内快速开展相关工作。

  4. **通过MCP以适当的权限公开这些数据。** 使用个人令牌来确保操作的合法性,所有操作都要归因于具体的人员,并且这些权限是可以被撤销的。绝对不能使用共享的后门通道。

  5. **让工作人员查看这些数据并分析结果。** 当数据积累到一定程度后,询问他们发现了哪些瓶颈、哪些内容正在过时、有哪些问题被提出却一直没有得到解答。这才是真正能带来成效的关键步骤。

从低风险的项目开始入手。内部使用的工具是理想的第一个试点对象,因为你的同事们对这些工具的使用较为宽容,而且相关数据也只会留在企业内部。

在规模较大的公司中,你无法绕过审批流程,因此应该针对这些流程来进行设计,而不是试图规避它们。重新利用安全团队已经认可的那套权限管理模型,确保所有操作都能追溯到具体的个人,并且这些权限是可以被撤销的;同时,在某个特定团队内部开展试点项目。具备这三个特点,就能解决审查委员会在开始审核之前可能会提出的大部分问题。

然后让收集到的数据为自己论点提供支持。一个能够用数字清楚地展示其检测结果的成功试点项目,比任何演示文稿都更有说服力,更有利于获得后续的审批。

真正的变革

仅仅用了50天,再加上一位工程师的努力,整个公司处理知识管理的方式就发生了改变。但这种变革并非由某个模型或某个人单独推动的——实际上,是那些被充分利用的工具发挥了关键作用:它们建立了信任机制,实现了各系统之间的连接,并通过收集到的数据证明了这一方法的有效性。

真正值得借鉴的变革并不在于“利用人工智能来更快地编写代码”,而是以下三种习惯:

  • 建立相应的检查机制,这样对于那些不是你自己编写的代码,你也可以在一定程度上信任它们。

  • 为执行这些操作的代理程序赋予与操作者相同的权限,但绝不要给予其完全的访问权限。

  • 记录你的流程实际完成了哪些工作,因为只有那些被记录下来的内容,才能成为改进的方向。

先选择那个让所有人都很困扰的流程,然后从那里开始构建第一个“控制关卡”吧。

Comments are closed.