Why Software Automation Needs a Layer Between Intent and Execution
TL;DR · AI 摘要
软件自动化应在意图与执行间增加中间层,以明确操作意图,提升系统灵活性与可维护性。当前工具常将意图与执行融合,导致变更执行机制时意图可能被改变,而分离层可解决此问题。
核心要点
- 自动化工具常将意图与执行融合,导致变更执行机制时意图可能被改变
- 可执行的操作规范(executable operational specification)可明确操作意图,提升系统灵活性
- 分离意图与执行步骤,有助于AI代理和复杂系统的管理
结构提纲
按章节快速跳转。
思维导图
用一张图看清主题之间的关系。
查看大纲文本(无障碍 / 无 JS 友好)
- 意图与执行的分离
- 核心机制
- 可执行操作规范
- 实践价值
- 提升灵活性
- AI代理支持
- 挑战
- 未解决的复杂性
金句 / Highlights
值得收藏与分享的关键句。
当意图与执行融合时,变更执行机制可能改变操作的含义
可执行的操作规范是机器可读的描述,明确操作目标和评估方式
分离意图与执行步骤,有助于AI代理和复杂系统的管理
为什么软件自动化需要在意图和执行之间增加一层
2026年9月29日
/
#software architecture
软件自动化擅长将指令转化为行动。
一个流水线可以部署发布版本,Terraform可以配置基础设施,操作手册可以重启服务,代理可以检查遥测数据并选择修复步骤。
但所有这些系统都有一个共同的弱点:它们通常更擅长执行指令,而不是表达这些指令背后的意图。
当自动化简单时,这个差距很容易被忽视。如果一个脚本只运行一个命令,脚本本身可能就足以解释应该发生什么。
但随着系统变得越来越分布化、越来越以策略驱动、越来越自主,执行逻辑开始承担它从未被设计用来承担的责任。
一个部署工作流现在可能需要编码:
应该部署什么
可以在哪里运行
必须满足哪些约束
必须检查哪些证据
谁可以批准更改
何时需要回滚
哪些失败是可以接受的在这一点上,自动化不再仅仅是执行。它也成为了定义操作意图的地方。
而这正是一个问题。
因为当意图和执行融合在一起时,更改执行者也可能改变操作的含义。
在我之前的 文章 中,我介绍了可执行操作规范的概念:一种机器可读的描述,说明操作应该实现什么,以及如何评估其结果。
在本文中,我想更深入一层。
核心问题是:
在人类意图和执行它的系统之间,应该存在什么?
我将探讨:
- 为什么自动化工具常常成为意外的规范
- 为什么意图和执行以不同的速度演变
- 当意图嵌入在流水线和脚本中时会丢失什么
- 为什么期望状态是有用的但仍然不完整
- 如何引入一个显式的操作意图层
- 预条件、约束、证据和恢复规则如何融入这一层
- 执行计划与操作规范有何不同
- 这种结构如何帮助AI代理
- 以及这种分离仍然无法解决的问题
目标不是为了抽象而添加另一个抽象层。目标是让操作决策更容易理解、评估和更改,而无需每次执行机制改变时都重新定义操作的含义。
先决条件
你应该熟悉:
- 关键的软件架构概念
- CI/CD
- 基础设施自动化
- 可观测性
- 分布式系统
- 基本的策略概念
- TypeScript或类似语言
你不需要特定的编排工具或云平台。示例特意设计得小巧且与工具无关。
目录
- 先决条件
- 自动化工具常常成为意外的规范
- 意图和执行以不同速度演变
- 当意图嵌入在执行者中时会丢失什么
- 期望状态有帮助,但不是完整的意图
- 缺失的层
- 一个小型部署示例
- 将预条件与执行步骤分离
- 将约束与机制分离
- 明确证据要求
- 在执行开始前定义恢复措施
- 操作规范与执行计划
- 为什么这对AI代理很重要
- 一个最小的TypeScript模型
- 一个实际的工作流程
- 这种分离仍然无法解决的问题
- 从自动化逻辑到操作合同
- 结论
自动化工具往往无意中成为规范
考虑一个部署工作流。它可能最初很简单:
steps:
- build
- test
- deploy然后生产需求出现。
你添加了:
approval
region validation
health checks
canary percentage
rollback logic
error-rate thresholds
latency thresholds
artifact verification最终,该流水线成为唯一完整描述操作的地方。
这会无意中形成一种架构:
操作意图
↓
流水线配置
↓
执行现在流水线承担了两项职责:它既描述了操作的含义,又定义了操作的执行方式。
这些职责相关但不相同。
假设该工作流声明:
deploy:
image: orders:v42
verify:
errorRateBelow: 0.01
rollback:
whenVerificationFails: true这可能完美运行。但现在想象将部署迁移到另一个平台。
如果操作规则仅存在于该流水线中,迁移执行器时必须重新发现并重新实现这些规则。
真正的迁移变成:
迁移执行机制
+
重建操作意图这比仅仅更换工具要危险得多。
意图与执行的演变速度不同
操作意图通常相对稳定。
例如:
部署已批准的版本。
保持可用性。
不要超过错误率阈值。
保持回滚可能性。
不要在批准区域外部署。这些期望可能保持有效多年。但执行机制的演变频率要高得多。
团队可能经历:
shell脚本
Jenkins
GitHub Actions
Argo CD
Kubernetes操作符
云原生部署服务
AI代理如果意图与这些机制紧密耦合,每次工具变更都可能引发操作重设计。
这会带来不必要的变更。
你希望:
稳定意图
↓
可替换执行而不是:
新执行器
↓
重新发现操作的含义随着自动化变得更复杂,这种分离变得越来越重要。
执行器包含的智能越多,意图越容易隐藏在实现细节中。
当意图嵌入执行器时会丢失什么
当操作意图直接嵌入脚本和流水线中时,以下问题会变得更困难。
1. 审查
审查者可能看到:
if: error_rate < 0.01但不知道该阈值是:
业务需求
SRE策略
临时发布规则
历史变通方案该值是可执行的。但其含义并不明确。
2. 可审计性
六个月后,有人问:
为什么允许这次部署?
回答可能需要重建:
流水线版本
功能标志
运行时变量
仪表板
审批
操作员决策3. 可移植性
更换工具意味着需要重新实现规则。
4. 测试
你可以测试流水线是否正常工作。但测试操作意图本身是否完整要困难得多。
5. 治理
授权规则可能被埋在工作流代码中。
生产变更需要审批可能被实现为平台特定的分支保护规则,而不是作为操作的一部分进行表述。
6. AI执行
AI 代理可能会在违反未明示的操作约束的情况下生成有效的命令序列。
问题不在于执行器能力不足,而在于意图没有独立表示。
期望状态有帮助,但并非完整意图
许多现代系统已经使用期望状态模型。
replicas: 3
image: orders:v42这很有用。
系统可以比较:
期望状态
vs.
观察状态并协调差异。
但操作意图通常包含的不仅是最终配置。
假设期望状态是:
orders:v42
replicas: 3该操作还可能要求:
不可将可用性降低至99.9%以下
支付依赖降级时不可部署
保持错误率低于1%
生产部署需要审批
延迟超过400毫秒时需回滚这些不仅仅是目标状态属性。
其中一些属于:
前提条件
运行时约束
证据要求
治理规则
恢复规则期望状态是操作意图的一部分,但并非总是完整的操作意图。
缺失的层级
更明确的架构如下所示:
人类/组织意图
↓
操作规范
↓
执行计划/绑定
↓
执行器
↓
操作
↓
证据
↓
评估操作规范是缺失的层级。
它的职责不是执行命令,而是独立于执行机制来保持操作的含义。
该层级可以包含:
目标
范围
前提条件
约束
所需证据
授权规则
恢复条件执行器则回答不同的问题:
我如何利用可用工具满足这个规范?
这是更清晰的分离。
一个小型部署示例
假设我们要部署订单服务的v42版本。
操作目标是:
将订单v42部署到生产环境。但这还不够。
我们还知道:
支付依赖必须健康
至少要有3个副本保持可用
错误率必须保持在1%以下
p95延迟必须保持在400毫秒以下
生产部署需要审批
必须保留回滚的可能性我们可以将这些关注点单独表示:
type DeploymentIntent = {
service: string;
version: string;
environment: string;
preconditions: {
paymentDependencyHealthy: boolean;
approved: boolean;
};
constraints: {
minAvailableReplicas: number;
maxErrorRate: number;
maxP95LatencyMs: number;
};
recovery: {
rollbackOnViolation: boolean;
};
};然后:
const intent: DeploymentIntent = {
service: "orders",
version: "v42",
environment: "production",
preconditions: {
paymentDependencyHealthy: true,
approved: true,
},
constraints: {
minAvailableReplicas: 3,
maxErrorRate: 0.01,
maxP95LatencyMs: 400,
},
recovery: {
rollbackOnViolation: true,
},
};注意缺失的部分。没有出现:
kubectl
Terraform
GitHub Actions
Argo
云API意图目前还不关心部署如何发生。
这是有意为之。
将前提条件与执行步骤分离
前提条件回答的问题是:
此操作是否允许开始?
这不同于:
应该首先执行哪一步?
支付依赖必须健康
生产审批必须存在
制品必须已签名
维护窗口必须开启这些不是执行指令,而是执行开始前应满足的条件。
一个简单的评估器可能如下所示:
type Preconditions = {
paymentDependencyHealthy: boolean;
approved: boolean;
};
function canStart(
preconditions: Preconditions
): boolean {
return (
preconditions.paymentDependencyHealthy &&
preconditions.approved
);
}如果:
canStart({
paymentDependencyHealthy: false,
approved: true,
});返回:
false则操作不应开始。
该决策不应取决于执行者是 Kubernetes、脚本还是 AI 代理。前置条件属于操作意图的一部分。
将约束与机制分离
约束回答在操作运行期间或之后必须保持为真的内容。
示例:
副本数 >= 3
错误率 <= 1%
延迟 <= 400 毫秒
成本增加 <= 20%
区域必须保持为 us-east-1执行者可能使用许多不同的策略来满足这些约束。
例如,为了保持 3 个副本:
Kubernetes 可能使用滚动部署
另一个平台可能使用蓝/绿部署
代理可能在切换流量前临时扩展容量机制可能不同,但约束本身不变。
这正是为什么约束应独立于执行者存在。
明确证据要求
只有在可以评估的情况下,约束才有用。
假设你定义:
错误率 <= 1%那么你需要一个证据来源。
Prometheus
Datadog
CloudWatch
OpenTelemetry
自定义应用指标规范不一定要硬编码某个供应商,但应说明需要证据。
type EvidenceRequirement = {
name: string;
metric: string;
};
const evidenceRequirements:
EvidenceRequirement[] = [
{
name: "可用性",
metric: "availableReplicas",
},
{
name: "错误",
metric: "errorRate",
},
{
name: "延迟",
metric: "p95LatencyMs",
},
];执行者或证据收集器可以决定这些值的来源。规范定义了必须知道的内容。这种区分非常重要。
在执行开始前定义恢复策略
许多操作工作流仅在出现问题后定义回滚。但这样做为时已晚。恢复是操作意图的一部分。
如果错误率超过 1%,停止发布。
如果 p95 延迟超过 400 毫秒,恢复到上一版本。
如果证据不可用,需要人工审核。这些不仅仅是实现细节,它们表达了可接受的操作行为。
一个简单的表示方式可能是:
type RecoveryPolicy = {
rollbackOnConstraintViolation: boolean;
requireHumanReviewWhenEvidenceMissing:
boolean;
};执行者可以以不同方式实现回滚。该策略仍然属于操作的一部分。
操作规范与执行计划
这种区分非常重要。
操作规范回答:
应该发生什么?
必须保持为真?
需要哪些证据?
如果约束失败会发生什么?执行计划回答:
我们将执行哪些操作?
顺序如何?
使用哪些工具?规范
部署订单 v42。
保持至少 3 个副本可用。
错误率 <= 1%。
如果约束被违反,执行回滚。执行计划
1. 将订单扩展到6个副本。
2. 将v42部署到1个副本。
3. 路由10%的流量。
4. 等待5分钟。
5. 检查指标。
6. 增加流量。
7. 移除旧副本。该计划是满足规范的一种可能方式。
另一个执行器可能会生成不同的计划。这很有用。这意味着相同的操作意图可以适应工具和执行策略的变化。
对AI代理的重要性
当执行器是AI代理时,这种分离变得尤为重要。
传统脚本通常有可预测的执行路径,而代理可能会动态决策。
对于同一事件,它可能会选择:
重启
扩展
重新路由
禁用功能
更改配置如果正确性被定义为遵循一个确切的顺序,动态执行将难以验证。
但如果正确性被定义为操作规范,代理将拥有灵活性。
目标:
恢复结账可用性
前提条件:
支付数据库可访问
约束条件:
认证功能保持启用
无支付重复
错误率 <= 1%
成本增加 <= 20%
证据:
结账成功率
重复支付次数
错误率
成本变化
恢复:
如果无法满足约束条件则升级处理代理可以选择不同操作,但其行为仍然受到约束。
这为我们提供了:
意图
↓
规范
↓
代理生成的计划
↓
执行
↓
证据
↓
评估代理可以自由决定如何执行。但它不能重新定义成功的含义。
随着自主系统获得更多操作权限,这种区分将变得越来越重要。
一个最小的TypeScript模型
我们可以将这些概念整合成一个小型通用模型。
type OperationalSpec<TContext, TEvidence> = {
name: string;
canStart(
context: TContext
): boolean;
evaluate(
evidence: TEvidence
): EvaluationResult;
recovery: RecoveryPolicy;
};
type EvaluationResult = {
conformant: boolean;
failures: string[];
};
type RecoveryPolicy = {
rollbackOnConstraintViolation: boolean;
};对于部署:
type DeploymentContext = {
paymentDependencyHealthy: boolean;
approved: boolean;
};
type DeploymentEvidence = {
version: string;
replicas: number;
errorRate: number;
p95LatencyMs: number;
};const deploymentSpec:
OperationalSpec<
DeploymentContext,
DeploymentEvidence
> = {
name: "deploy-orders-v42",
canStart: (context) =>
context.paymentDependencyHealthy &&
context.approved,
evaluate: (evidence) => {
const failures: string[] = [];
if (evidence.version !== "v42") {
failures.push(
"wrong-version"
);
}
if (evidence.replicas < 3) {
failures.push(
"insufficient-replicas"
);
}
if (evidence.errorRate > 0.01) {
failures.push(
"error-rate-too-high"
);
}
if (
evidence.p95LatencyMs > 400
) {
failures.push(
"latency-too-high"
);
}
return {
conformant:
failures.length === 0,
failures,
};
},
recovery: {
rollbackOnConstraintViolation:
true,
},
};现在执行可以在其他地方处理。
interface DeploymentExecutor {
execute(
spec: typeof deploymentSpec
): Promise<DeploymentEvidence>;
}该执行器可以由:
Kubernetes
云平台
测试框架
本地模拟器
AI 代理规范始终是参考标准。
实践工作流程
如果你想将这种分离引入现有自动化系统,从一个操作开始。
1. 选择一个重复的操作
部署服务
轮换证书
扩展工作池
恢复备份2. 提取目标
写下该操作试图实现的目标。避免使用命令。
3. 提取前提条件
提问:
在此操作开始之前,必须已经成立的条件是什么?
4. 提取约束条件
提问:
在执行过程中或执行后必须保持成立的条件是什么?
5. 定义证据
针对每个约束条件,识别用于评估该条件的观测信息。
6. 定义恢复机制
决定当证据显示约束条件被违反时应采取的措施。
7. 保持执行独立
让当前的自动化工具继续作为执行者。不要一次性重写所有内容。
8. 评估现有执行者
判断当前脚本、流水线或代理是否满足提取出的规范。
这种分离可以逐步引入,因此不需要立即构建新的操作平台。
这种分离无法解决的问题
将意图与执行分离并不会自动使操作正确。
你仍然可能遇到:
错误的目标
不合理的阈值
缺失的证据
误导性的指标
冲突的约束
不安全的执行者
安全漏洞
错误的恢复策略规范本身可能有错误。这很重要。
形式化表示不会使假设成立,它只是让假设更容易被检查和评估。
这也会带来成本。更明确的操作意图意味着需要维护更多工件。
如果规范未进行版本控制和审查,它们可能会过时。如果证据定义薄弱,符合性结果可能变得误导。某些操作决策仍然难以形式化。
人类判断不会消失。其价值在于让更多的判断变得明确。
从自动化逻辑到操作契约
还有另一种思考这种分离的方式。
成熟的操作规范开始表现出类似契约的特性。
它声明:
在这些条件下,该操作可以开始。
必须保持这些约束。
必须产生这些证据。
其结果将根据这些规则进行评估。
如果失败,将适用这些恢复条件。这比以下内容强大得多:
运行此工作流工作流是实现。操作契约描述了该实现需要负责实现的目标。
这为我们提供了如下结构:
意图
↓
操作契约
↓
执行计划
↓
执行者
↓
证据
↓
评估这种分离为以下内容创造了空间:
针对相同操作意图的多种执行策略一旦实现这一点,另一个问题浮现:
两个不同的执行者能否满足相同的操作规范?
这是我想接下来探讨的问题。
结论
自动化使软件操作变得更加快速和可重复。
但执行只是操作的一部分。我们仍然需要知道:
为什么允许执行该操作
预期的成果是什么
必须满足哪些约束
需要哪些证据
当约束失败时会发生什么
当所有这些逻辑都封装在流水线、脚本或代理中时,执行器会无意间成为操作语义的拥有者。
这种耦合使得系统更难被审查、迁移、审计和验证。
更合理的分层方式如下:
意图 ↓ 操作规范 ↓ 执行计划 ↓ 执行器 ↓ 证据 ↓ 评估
规范描述了成功的定义,执行器决定如何实现目标。
随着执行机制变得越来越动态,尤其是当执行器是AI代理时,这种区分变得越来越有价值。
因为当我们给予系统更多决定如何完成工作的自由时,就越需要明确工作应该实现的目标。
合作伙伴推荐课程
(在新标签页中打开)
广告
- Udemy Apache Airflow:实践指南 Marc Lamberti 4.6(满分5星)(5,751人评价) 10小时54分钟 初学者 证书 查看课程 (在新标签页中打开)
- Coursera 高级Linux故障排除与系统恢复 Packt - 课程讲师 3周,每周4小时 高级 证书 查看课程 (在新标签页中打开)
- Coursera 编写自动化脚本 业内人士 2周,每周1小时 中级 证书 查看课程 (在新标签页中打开)
- Coursera 搜索与展示广告 Chris J. Vargo 和 Harsha Gangadharbatla 4.5(满分5星)(99人评价) 5周,每周2小时 初学者 证书 查看课程 (在新标签页中打开)
更多Selenium WebDriver课程请访问Class Central
→
技术与产品负责人,拥有25年以上经验,曾主导构建和扩展拉丁美洲的B2B平台、运营系统、云架构和技术团队。我撰写关于软件架构、技术债务、遗留系统现代化、AI、工程领导力和技术决策的内容——尤其是团队投入时间、金钱和代码之前就应该做出的决策。OrkestCloud和Collabai创始人。兼职CTO和技术顾问。我的核心原则:构建成本低廉;糟糕决策代价高昂。
如果你读到这里,请感谢作者以表达你的支持。说声谢谢
免费学习编程。freeCodeCamp的开源课程已帮助超过40,000人成为开发者。立即开始