
设计会上已经确定了其中的一件事情。
用户的密码被更改之后,其他的设备都需要退出。当前设备是否保留登录状态取决于产品的策略。
会议结束后,后端就把这条规则写入到了SessionService里面。
移动端也是根据这样的逻辑来完成交互的。
过了三个星期之后,团队就给另外一个Coding Agent增加了账号安全的功能。
Agent读取需求信息。
可以同时登录多个设备。允许用户更改自己的密码。支持会话取消的功能。
经过重新整理之后,它觉得更改密码属于凭证变更,最安全的方法就是全部退出会话。
很快就可以做到。
测试已经通过了。
于是目前的设备也跟着被踢出了。
Agent并没有出现明显的错误。
它并没有看到三个星期前的设计会议中所作的全部决定。
重要的规定在会议记录中也有,在一些开发者脑海里也有。
但是没有形成一个稳定的,可以用来设计的上下文。
这就是AI Coding在进行多人,多Agent合作的时候所面临的新问题。
大家的意见都一致了。
但是共识并没有转化为可以实施的工作方案。
因此每次新的任务开始的时候,Agent都可能会对需求进行新的解读。
因此,在人工智能的时代里,设计文档就不再仅仅是一个给人们看的说明文档了。
它是业务意图和代码生成之间的一个控制接口。
告诉Agent什么地方可以自由地实现。
已经做出的选择是什么。
不能逾越的界限是什么样的呢?
哪些结果要经过测试才能得到证实。
【企业架构研究会在每个月都会发布智能架构和本体论研究的研究报告,并且构建不同的社群,如有希望获取的,希望进群一起研讨的,请留言:“进群并获取资料”,同时添加文章最下方的联系人,我们恭候各位到来,希望与各位有识之士一同研讨中国的企业IT产业和技术发展的方向,有需要进群或者联系我们一起学习的,请联系money_god1984】
一、设计文档应该由对系统进行描述转为对系统做限定
传统的设计文档主要分为三部分来使用。
审阅。
移交工作。
说明系统的构成组件和接口。
这些用途依然很关键,但是对Coding Agent而言,仅仅进行解释是不够的。
Agent要了解自己可以修改的地方。
不可以更改任何内容。
什么样的才算完成了呢?
什么是越界?
因此一份能够被纳入到AI Coding链条中的设计作品必须能够回答出六个方面的问题。

图1 可执行设计工件必须回答六类问题
1. 范围
这次修改的内容有哪些?
可以修改哪些部分。
哪些模块是固定的。
在确定了范围之后,Agent不应该因为自己的方便而重新构造整个权限模块。
范围并不是项目的说明。
它是指写出权限界限。
2. 对象模型
系统中的主要对象是什么?
二者之间是什么样的关系呢?
谁拥有谁。
谁依赖谁。
这张图很清晰。但是它直接决定了数据库结构,领域服务以及接口参数。如果Session是和设备绑定的话,那么单个设备退出就很容易了。如果Session只属于用户的话,那么设备级隔离就变成了另外一种逻辑。对象不明确的时候,Agent就会按照现有的代码来选择。对象确定之后,就可以按照相同的领域模型来完成了。
3. 状态机
对象的状态是什么样的。
情况如何变化。
能够被谁触发。
失败之后停留在什么地方。

图2 对象模型和状态机共同限定实现空间
状态机能来避免代码中产生更多的临时变量。
is_active。
is_expired。
is_revoked。
is_blocked。
这些布尔值多了之后就会产生相互矛盾的情况。
设计把状态空间缩小。
代码才能保持一致。
4. 接口契约
接口输入的内容是什么?
输出的内容是什么?
将会怎样改变?
怎样对失败进行分类。
可以进行重试吗?
调用方如何处理呢?
以Refresh Token接口为例,仅仅写出POST /token/refresh是远远不够的。
还应该做到:
Refresh Token只能用一次。
成功之后会生成新的Token Family版本。
旧Token再次出现的时候会进行重放检测。
当出现网络超时时,客户端可以再试一次。
重试的时候一定要带上相同的幂等键。
检测到重放之后,不再返回普通的401错误,而是返回一个安全事件代码。
接口契约并不是API文档的装饰。
它就是模块之间的责任划分。
5. 关键决策
为什么要用设备级别的Session?
为什么Access Token只能使用五分钟?
普通接口为什么允许短时间的权限缓存?
这些原因需要被保留下来。
否则几个月之后,另一个Agent发现五分钟太短,可能直接把它改成三十分钟。
从编程角度看,这只是一个配置变化。
从安全角度看,它会增加越权的机会。
因此,设计工件不能只记录已经完成的工作。
还要把原因记录下来。
6. 验收条件
什么样的设计方案才算是正确的呢?
要把它变成可以用来进行测试的行为。
【Given 用户在设备A上登录之后
When 用户在设备B上退出了当前会话
Then 设备A上的Refresh Session就会失效
And 设备B还可以刷新Token】
没有验收条件的情况下,设计就只能依靠人的解释来完成。
有了验收的标准之后,测试,CI以及Agent都可以参与到评价当中来。
到了这个时候,设计才由说明书变为工程限制。
二、设计隔离的关键就是确定哪一方掌握着状态
多Agent并发开发速度很快。
也很危险。
一个Agent管理Token。
一个Agent来管理Session。
另外一个Agent来管理权限。
如果没有把组件的责任写明白的话,那么各个Agent就会为了完成自己分配的任务而直接去改动其他的模块数据了。
开始的时候很管用。
之后就会越来越糟。
以移动端认证为例,可以先把这四个部分分别定义出来:
Identity Provider用来验证用户的个人信息,Session Service用于管理设备会话以及会话的生命周期,Token Service负责对Tokens进行签名,更新以及防止重放攻击,Permission Service则用来做权限计算和权限版本控制。
组件的名字没有关系。
主要是看所处的状态属于哪一种。
有状态的是谁。
谁能够修改呢?
其他的模块只能用什么样的方式去调用呢?

图3 状态所有权限制组件和Agent的修改边界
·该表格会对实施的方法进行限制。
·Token Service可以向Session Service报告重放发生的情况。
但是它不能直接更改Session表。
·Permission Service能够进行权限版本的更新。
·但是它不能够取消设备。
·Session Service能够取消会话。
·但是它不能够自动地去修改用户的权限。
这就是隔离的设计。
并不是说模块越多就越好。
而是让每一个状态都只由一个明确的主体所拥有。
如果有好几个模块都能够直接修改同一个状态的话,那么系统迟早会出问题。
人类工程师会越界。
Agent也会。
因此,组件边界的编写不能仅仅做到低耦合,高内聚。
要把是谁有数据,谁有权更改写进去。
这就是可以用来控制代码生成的设计方法。
三、验收条件为设计进入工程系统入口
很多文档写完了之后,也只能依靠人工来阅读。
原因很简单。
内容不能够被证实。
如:
系统的安全性很重要。
登录的过程要很顺畅。
权限要尽快生效。
这些有方向性的表述。
但是没有执行的意义。
对于Agent而言,它们基本上没有受到任何限制。
设计要继续往下压。
系统的安全性可以分成几个部分来考虑:
Refresh Token要定期更换。
旧Token在再次使用的时候一定要引起重视并产生安全事件。
·账号被冻结之后,在五秒钟之内就会拒绝掉之前的老Token。
·Token不可以跨租户复用。
·登录体验要好,可以把它分成以下几部分来讲解:
·Access Token过期之后可以进行静默刷新。
·刷新失败的时候只提示一次重新登录。
单一设备退出不会影响到其他的设备。
当出现网络超时时不能再次创建Session。
把要求转化为测试场景之后,设计就具有了可实施性。
【Given 用户权限版本为12
And 当前Access Token中权限版本也为12
When 管理员撤回了用户的高风险权限
Then 用户的权限版本就变成了13
And 在使用过期的Token去访问高风险接口的时候会被拒绝】
这样的验收条件的作用主要有三点。
第一点就是让团队找出设计方案有没有缺少的地方。
如果不能写出测试用例,则表示对对象,条件或者结果还不是很清楚。
第二步就是让Coding Agent去实现目标了。
Agent不再仅仅依靠一个描述来推断什么是完成了。
第三,它也可以加入到CI里面去。
代码提交之后,系统会进行验证,看是否违反了设计的要求。
这就是由软约束转向硬约束的设计过程。
先把内容写到文档里。
再写到测试里去。
然后就到了流水线上。
此时的设计已经不是建议了。
它会决定代码是否可以被合并。

图4 验收条件把设计转化为测试和CI门槛
四、设计工件要进入AI Coding的完整链路
一份设计文档如果仅仅放在项目的目录下,那么很快就会没有用途了。
Agent并不一定需要主动去读取。
文档也会和代码渐渐分离。
因此,在设计工件的时候要把它放到AI Coding的运行链条上。

图5 设计工件进入AI Coding完整运行链路
有一些具体的机制要加以说明。任务开始之前就加载好相关的图纸。Agent接收到需要修改Session的任务之后,系统会自动加载:
Session对象模型。
状态机。
接口协议。
相关的ADR。
验收的标准。
并不是把整个项目的文档都放进去。按任务加载。信息不足的时候,Agent可以自己补充完整。信息量大,重要的限制很容易被忽略。实施计划要引用设计节点。任务不能只是写出刷新接口的功能。要说明它所对应的那条设计决策是什么。
于是设计,任务以及测试就联系在了一起。代码修改之后要查看有没有越界的地方。Agent对不在范围内的模块进行了修改。增加了以前没有的设计状态。修改了接口返回值的方式。这些都应该被检查到。
不一定是每一次都不答应。
但是应该告诉大家,代码已经跑偏了。
编写完代码之后再回来修改设计。
在实施的过程中如果发现原来的设计是不可行的,则不应该仅仅修改代码。设计也得一起改变。不然的话,文档就会继续讲以前的系统了。下一个Agent读取之后就会再次出错。
因此,设计agent并不是一次性的产品。它和代码一样要进行版本控制。
【写在最后】
这五篇论文探讨的是人工智能如何参与到真实软件工程当中去,并非是它能写出更多的代码。Explore使系统被看清楚,Grilling使得方案可以经受住质疑,Brainstorming将共识凝聚到设计之中,工程控制面又把设计变成权限,范围,以及验证的方式。
人工智能编程真正的成熟标志,并不在于产生结果的速度快慢,在于能够理解问题,做出可靠的方案,以及保证这些方案可以被检验出来。
![]() | 侯君璠,AI架构陪跑师,清华大学工程管理硕士(MEM),企业架构研究会发起人,国内大型央企单位技术总监、解决方案专家。20余年工作经验,曾任美国某大型科技公司-M中国区首席架构师,国内某大型险资技术总监、某大型科技咨询公司副总裁。深耕于企业架构、人工智能研究与落地方案,以及先进工程项目管理和企业数字化转型等领域。 |
声明:本文核心文字内容由本人亲自撰写,图片由模型生成
夜雨聆风