我最近遇到一个看似简单、实际很容易走偏的问题:面对一个陌生软件,怎样才算“熟悉”了它?是把源码读完,是把文档看完,还是把页面上的按钮都找出来?如果任务只是问“它有什么功能”,这些工作大概已经够用。但如果下一步是让一个智能体稳定完成任务,答案就完全不同了。
当时我们在整理一批软件的能力资料,目标不是做一份漂亮的介绍,而是让系统以后能够接到真实任务,自己找到合适的动作,完成后再交回证据。讨论很快从“要调用一个入口还是多个工具”变成了另一个问题:我们究竟是在收集知识,还是在建立执行能力?
这件事让我重新意识到,软件熟悉不是一次阅读,而是一条逐级收紧的验收链。只有当发现、理解、执行和复核都接上,软件才算从“被看见”走到了“可自主使用”。
看见过,不等于会完成
最开始,人很容易把发现结果当成能力结果。代码里有某个函数,文档里写着某项功能,页面上能看到一个按钮,或者一次试跑没有报错,这些都能证明软件“有东西可找”。但它们证明不了任务能不能做完。
比如,一个按钮可能依赖特定登录状态,一个接口可能需要先准备上下文,一项看起来普通的操作可能会修改数据。只把这些内容记进知识库,下一次真正执行时,智能体仍然要临场猜顺序、猜参数、猜风险。它偶尔会成功,却很难解释为什么成功,更无法保证换一个输入仍然成功。
代码、文档、控件可见性和一次试跑,只能证明发现过,不能证明任务已经被稳定完成。
如果不处理这个差距,后面会出现一种很熟悉的假象:资料越来越多,实际工作却每次都从页面搜索开始。系统看起来“懂得很多”,但一遇到具体任务,就重新点按钮、重新试参数、重新判断结果。知识没有沉淀成能力,反而把不确定性藏进了临场操作里。
第 1 层:先建立发现层
我现在更愿意把熟悉陌生软件的第 1 步叫作建立发现层。它负责回答:软件有哪些页面、模块、动作、数据对象和可能的入口?源码、文档、界面结构、控件信息和历史记录,都可以放在这一层。
这一层的价值很大,因为没有发现就没有后续判断。但它的边界也必须写清楚。发现层不是能力承诺,不应该直接把“存在”标成“可用”。一个页面被扫描到,只代表页面存在;一个控件被识别到,只代表它曾经被看见;一段代码被建立索引,只代表静态关系已经留下。
当时的一个关键判断,就是不把所有复杂能力都暴露给外部。统一入口负责建立资料、盘点能力、分配角色、运行真实任务和生成评分;需要源码分析或界面分析时,再由内部路由按需调用相应能力。这样做是因为使用者真正关心的是“这件事能不能完成”,而不是每次都先决定应该找哪个底层工具。
表面上这是入口设计,实际上是在给知识划边界。发现工具可以很多,外部承诺应该尽量少。入口越稳定,内部越可以替换分析方式,任务方也越不需要知道软件内部有多少层复杂性。
第 2 层:从能力清单走向角色
发现资料之后,下一步不是立刻执行,而是盘点能力。这里要把“软件有什么”改写成“它能为哪类任务提供什么结果”。同一个软件可能同时包含浏览、编辑、生成、导出、管理等能力;如果只按页面罗列,执行者仍然不知道该从哪一条开始。
所以我会给能力补上几个维度:输入是什么,输出是什么,前置条件是什么,是否会改变数据,失败时留下什么信号,以及它适合哪个工作角色。角色不是给软件贴一个漂亮标签,而是减少任务分配时的歧义。一个偏生成的能力和一个偏审核的能力,虽然都在同一个软件里,却不应该被同样调用。
这里最容易误判的是,把资料完整当成能力完整。资料可以有很多页,能力仍然可能缺少输入约束、结果判断和失败处理。能力盘点的目的不是让清单变长,而是让下一次任务知道该选哪条路、交回什么结果。
我选择先做能力和角色盘点,是因为它能把后面的真实任务变成可比较的测试。如果连“这项能力解决什么问题”都说不清,直接跑任务只会得到一堆零散回执,无法判断到底是入口不稳,还是任务本身选错了能力。
第 3 层:把复杂度收进稳定正门
真正的跃迁发生在第 3 层:把界面操作和逆向分析的复杂度收进一条稳定的非界面正门。这里的“非界面”不是说软件本身没有界面,而是外部调用不再依赖临场点击。外部只提交结构化输入,正门负责准备上下文、调用内部能力、处理错误,并返回可以继续核对的数据。
这一步很重要,因为前台操作天然容易受窗口位置、登录状态、弹窗、焦点和页面变化影响。界面可以作为内部实现的一部分,但不应该成为每次任务都要重新依赖的记忆。自主执行的关键,不是把智能体训练成更熟练的点按者,而是把点按背后的判断收进稳定的正门。
我没有选择“以后让智能体自己看着页面点”这条错误捷径,是因为那只会把复杂度转移给每一次任务。今天能点通,不代表明天换一个页面仍能点通;一次成功也不能说明失败时知道如何恢复。更稳的做法是,界面探查、源码分析和控件发现作为内部手段,外部始终面对同一套输入、输出和错误语义。
当然,正门也不能靠名字显得稳定。它要有明确的参数边界,知道哪些动作需要确认,哪些结果必须落证据,哪些失败应该停止而不是继续猜。否则只是把多个不稳定工具包了一层,入口看起来统一,内部仍然没有真正收敛。
第 4 层:用真实任务证明能干活
有了正门,才进入真正的验收。这里不能只做模拟调用,也不能只看返回码。必须拿真实输入跑一项真实任务,得到真实产出,并留下别人可以复核的证据。
当时的讨论里,一个很有价值的区分是:试跑可以验证“路径能不能被触发”,真实任务才能验证“目标是否完成”。前者适合发现入口和暴露错误,后者才涉及输入是否被正确理解、输出是否符合要求、数据是否真的写入,以及结果能不能被再次找到。
证据也不能只是一句“执行成功”。它至少要能回答:用了什么输入,调用了哪类能力,产生了什么结果,结果在哪里,哪些部分经过人工或程序复核。如果任务涉及修改或发布,还要留下更谨慎的边界记录,说明哪些动作实际发生了,哪些只是演练。
如果不留证据,后面会把“执行过”误认成“验证过”。换一个人接手时,他只能重新跑一遍;换一个版本时,也无法判断变化来自软件、输入还是执行路径。真正的完成不是返回成功,而是产出可核对、可复现、可解释的结果。
第 5 层:用可重复评分确认成熟度
最后一层是成熟度评分。评分不是为了给软件贴一个漂亮的分数,而是为了把“偶然成功”和“稳定可用”分开。一个能力跑通一次,只能算有了证据样本;要称为成熟,还要看同类任务能否重复,输入变化后是否仍然成立,失败是否有明确边界,源码或页面变化后能否发现影响。
我会把评分至少拆成两条线:一条看知识覆盖,另一条看能否真正干活。知识覆盖可以反映文档、代码和控件是否已经进入发现层;能干活则必须依赖真实回执、结果验证和风险门。前者很高、后者很低,是完全可能的状态,不能用一个总数把它们混在一起。
这也解释了为什么成熟度不能靠一次成功来判断。一次成功可能只是输入刚好、页面刚好、状态刚好。可重复的评分会迫使我们继续问:如果重跑,结果是否一致?如果更换输入,正门是否仍然理解?如果软件更新,哪些能力需要重新验证?
源码变化后,也不应该每次全量重建所有资料。更合理的做法是按变化指纹增量刷新,只重新检查受影响的模块和证据。这样既节省成本,也保留了上一轮已经验证过的部分;但如果指纹无法确认影响范围,就应该降级为更大范围的复核,而不是假装没有变化。
下次我会怎么做
下次再熟悉一个陌生软件,我会先把目标从“把它研究明白”改成“让一类真实任务稳定完成”。然后按 5 个门槛推进:先建立发现层,再盘点能力与角色;接着封装稳定的非界面正门;随后用真实输入完成真实任务并留下证据;最后用可重复的 readiness 评分确认成熟度。
我会特别记录每一层的停止条件。发现资料足够定位入口时,就不继续无边界扫描;能力已经能对应任务时,就开始做真实验收;真实结果还不能复核时,就不把它标成已验证。这样做不是降低要求,而是让每一步都对下一步负责。
这件事让我重新意识到,工具真正改变的不是我们能收集多少信息,而是我们是否愿意把判断过程留下来。一个流程成熟的标志,不是它能在顺利时跑通一次,而是下次遇到类似任务时,不必再从零猜测。熟悉软件的终点,从来不是知道它有什么,而是能够在边界清楚、证据完整的情况下,放心把事情交给它完成。