我一直觉得,工程师的工作可以分为两类:一类是创造,另一类是重复。
重复本身最烦人的地方,其实不是“浪费时间”,而是它会将人的注意力切得粉碎。想象一下,你正专注地思考着业务的深层逻辑和因果关系,下一秒却不得不切到某个网页上寻找一个按钮,接着又得复制粘贴一段字符串,最后还得提心吊胆,反复确认自己有没有点错地方。
这种体验促使我对自己发起了一次小小的“反重复实验”。整个过程并非一蹴而就,而是经历了四个明显的阶段:从最初的网页操作,到脚本,再到 MCP,最后进化到 Skill。每一个阶段都称不上完美,但每一步都让我更靠近一个核心结论:将底层能力封装成标准接口,远比把固定流程做成孤立的工具更加重要。
我的起点:网页操作的“确定性痛苦”
一切始于一些再普通不过的内部任务:在公司的某个管理系统里,我需要周期性地创建迭代、创建需求、查询任务状态、整理摘要报告。
这些操作有几个共同点:
- 步骤固定:每次操作的流程一模一样,变化的仅仅是几个字段,比如日期、标题、描述、预估工时。
- 结果可验证:操作成功或失败,系统会给出明确的反馈。
- 高频打断:状态查询可能一天要做好多次,而迭代创建则每周都要执行。
网页操作的优势显而易见:看得见、摸得着,不需要额外解释。但它的劣势,从工程角度审视则更为突出:
- 知识只在你脑子里:整个流程依赖你的肌肉记忆和大脑缓存,没有被固化到任何文档或代码中。
- 可复用性极差:即使你操作得行云流水,也很难让另一位同事“开箱即用”,学习成本很高。
- 易错且难追溯:一旦点错,排查起来往往只能依赖模糊的回忆或零散的截图。
当一个流程足够确定时,重复执行它就不再是必要的劳动,而更像是一种亟待修复的系统设计缺陷。
第一版:脚本化——把“手工动作”变成“可重复计算”
我迈出的第一步,是用脚本将两个最确定、收益最高的动作自动化:
- 创建迭代:输入一个开始日期,脚本自动计算出结束日期与有效工作日,然后向系统发起创建请求。
- 创建需求:将原本需要在多个页面间跳转的操作,固化成一个脚本,只需执行一条命令,就能按照既定顺序分步提交。
这一步的核心价值不在于写了多少行代码,而在于完成了一次关键的“抽象”:
- 以前,你是在操作 UI 界面。
- 现在,你是在调用一个“函数”,它接收明确的参数,并返回确定的结果。
脚本带来的好处立竿见影:
- 时间大幅缩短:从几分钟的操作压缩到几十秒。
- 错误率显著降低:输入参数减少,执行流程固化。
- 过程可回放、可追溯:执行失败可以重试,所有操作都有日志可查。
但脚本的局限性也很快暴露:
- 入口不友好:你需要记住命令名称和各种参数,还得确保运行环境配置正确。
- 能力分散:一个脚本管迭代,另一个脚本管需求。未来如果增加功能,脚本会越来越多,管理起来很麻烦。
- 共享困难:你可以把脚本文件丢给同事,但“怎么用、何时用、出了错怎么办”这些问题,仍然需要大量的口头解释。
脚本阶段给了我一个深刻的启示:
自动化不应仅仅是将流程写成代码,而应致力于将能力封装成可复用的组件。
而组件的下一步,需要一个标准的“协议”来统领。
第二版:MCP 化——把脚本变成“工具”,把工具变成“可组合能力”
当封装好的能力开始增多时,真正的挑战不再是实现某个单一功能,而是解决“如何被高效、统一地调用”这个问题。
脚本相当于自定义了一套调用契约:参数格式、输出样式、错误处理都由开发者自己决定。而 MCP (Model Context Protocol) 为我指明了一个更接近“产品级接口”的方向:
- 工具列表:明确声明“我”能提供哪些能力。
- 工具调用:提供结构化的参数,“我”返回结构化的结果。
- 统一的输入/输出:一切都遵循预先定义的、可验证的规范,这使得能力天然具备了“可组合性”。
这一步最关键的变化在于思维模式的转变:
- 以前:你编写一个脚本,然后需要人去“适应”这个脚本的调用方式。
- 现在:你实现一组符合 MCP 协议的工具,之后任何支持 MCP 的客户端(如 AI Agent)都能直接“接入”并使用你的能力。
MCP 化从本质上解决了三个问题:
- 统一入口:无论是查询、创建迭代还是管理需求,都变成了同一种规范的调用方式。
- 结构化参数:每个工具都有明确的参数模式,缺少什么、格式错误,调用方一目了然。
- 可组合性:工具不再只是用于单次执行,它可以被更高层次的智能体串联起来,组合成更复杂的业务流程。
不过,MCP 的体验仍然偏向“工程师友好”:
- 你仍然需要知道具体该调用哪一个工具。
- 你仍然需要手动组织 JSON 格式的参数。
于是,我开始思考最后一层优化:能否让人直接用自然语言表达意图,然后由系统自动完成工具的选择与调用?
第三版:Skill 化——让工具“会聊天”,但不让聊天“去干活”
Skill(在诸多 Agent 框架中常见)更像是整个体系的“智能交互层”:
- 它负责意图识别:分析用户的自然语言,判断是想查询需求、创建迭代,还是进行其他操作。
- 它负责参数解析与补全:从一句话中抽取出ID、日期、标题等关键信息;如果参数不全,它会主动追问。
- 它负责结果呈现:将底层工具返回的结构化数据,整理成更易于阅读的自然语言摘要。
- 它还负责安全与体验:对结果中的敏感信息进行脱敏处理后再展示。
在这里,我刻意坚持了一个重要的设计边界:
- Skill 本身不实现任何具体的业务能力。
- Skill 只负责意图理解、流程编排与结果表达。
真正的网络请求、鉴权、错误处理等核心逻辑,仍然稳固地放在 MCP 工具层。为什么要做这样的分层?这关乎“可信计算”的核心理念:
- 你希望真正执行动作的“能力层”是可测试、可复现、可审计的,它的行为必须绝对确定。
- 你希望自然语言交互只影响“如何调用”,而绝不改变“调用具体做了什么”。
Skill 层的价值在于,它将“使用工具的成本”降到了最低:
- 你不需要记住任何工具名称。
- 你不需要了解参数的具体结构。
- 你只需要像对话一样说出需求:
- “查一下项目X的需求123现在是什么状态?”
- “从下周一(2024年10月28日)开始,创建一个为期两周的迭代。”
- “按这个标题和描述,创建一个高优先级的需求。”
至此,一个完整的自动化链路才真正形成闭环:
用户说人话 → Skill 负责理解与组织 → MCP 工具负责可靠执行 → Skill 负责将结果讲成人话。
四段进化背后的技术架构(本质上是清晰的三层分离)
如果从更工程化的视角来审视这个演进过程,其核心是一个清晰的三层架构:
- 能力层
核心任务是将外部系统(如内部管理系统)的能力,封装成一个个确定性、高内聚的函数。这一层处理所有细节:构造HTTP请求、管理认证令牌、实现重试机制、统一处理错误码等。
- 协议层
核心任务是将“能力层”的函数,通过像 MCP 这样的标准协议暴露出去。它定义工具的列表、每个工具的参数模式、以及标准化的输出格式,使得能力变得“可被发现、可被集成”。
- 体验层
核心任务是提供友好、智能的交互界面。利用 Skill 实现意图识别、上下文参数抽取、缺参时的主动追问,并将执行结果格式化成对用户友好的展示形式,同时兼顾信息安全。
这种分层架构带来了显著的好处:
- 能力高度可复用:封装好的能力既可以被原始脚本调用,也可以无缝接入 MCP 协议。
- 集成天然标准化:协议层让这些能力能够被任何兼容的客户端或平台轻松集成。
- 体验与逻辑解耦:最上层的交互体验可以持续迭代和优化,而不会波及或破坏底层核心业务逻辑的正确性。
实践带来的几点心得
-
确定性优先于智能性
自动化初期最有价值的部分,往往不是让系统变得更“聪明”,而是让整个过程变得更“确定”。消除不确定性是提升效率和可靠性的第一步。
-
接口设计优先于UI设计
当你把核心能力抽象并封装成标准的工具接口后,上层交互的UI可以随意更换,调用入口可以灵活变通,甚至整个技术平台都可以迁移,但最宝贵的能力资产始终得以保留。
-
自然语言是“编排层”,而非“执行层”
让大语言模型去做它擅长的理解、规划和编排工作,但绝不让它直接执行可能产生副作用的操作。执行必须交给可控、可审计的确定性代码。
-
安全是内置属性,而非事后补丁
认证令牌绝不能硬编码在代码中;结果展示必须考虑敏感信息脱敏;错误信息应做到对用户友好,同时不泄露系统内部细节。这些安全考量需要从设计之初就融入架构。
-
文档是产品的一部分,而非交付后的负担
一个工具能否被他人顺利使用,往往不取决于代码写得有多精妙,而取决于README是否清晰易懂。好的文档是降低复用门槛、放大工具价值的关键。
结语:把重复留给机器,把注意力还给人
回顾这四段演进之路,它们本质上并非单纯的技术升级,而是一次深刻的“心智升级”:
- 从最初只关注 “我把眼前这件事做完”,
- 进化到追求 “我要用更可靠的方式把这件事做对”,
- 再提升到思考 “如何将这件事做成一个可被他人复用的通用能力”,
- 最终实现 “让这个能力能够像日常对话一样自然地为人服务”。
自动化的终极价值,或许不在于节省了多少分钟的操作时间,而在于你终于可以免受干扰,在需要深度思考的关键时刻,不再被网页上那些机械的按钮所打断。
如果你手头也有一段每天、每周都需要重复点击的流程,不妨也尝试一下这个路径:先把它写成脚本,再把脚本封装成接口,接着让接口遵循标准协议变成工具,最后为工具赋予自然语言交互的能力。你可能会发现,属于工程师的快乐,有一半恰恰来源于——我们终于亲手终结了那些无意义的重复。如果你想了解更多关于自动化与DevOps的实践,欢迎来云栈社区一起交流探讨。