Harness 工程 全部章节

第13章 系统集成与持续演进

组件能够分别工作,不表示它们接在一起之后仍遵守原来的约定。模型返回的调用可能被新工具解释成另一种动作,旧运行可能被新版本错误接手,平台凭据也可能把局部许可扩大成下游账户的全部权限。集成要解决的不是“接口都调通了”,而是边界相接时责任有没有改变。

本章以一套已经能够完成任务的小系统为起点。先把组合固定成可核对的版本,再检查迁移与发布,按收益决定保留哪些层。只有组织使用改变身份、授权或凭证责任时,才进入可选的平台扩展。最终得到的系统不必拥有目录中的全部能力,但要明确自己采用什么、验证到哪里,以及哪些任务还不能承接。

13.1集成契约与运行清单

系统集成是把组件的输入、输出、权力、状态与版本关系接成能够执行任务的整体。它不是将几个 SDK 的返回值串起来。最小形态是一条完整任务路径:输入依据什么许可进入模型,调用依据哪个契约进入执行器,实际对象怎样被验收,未知又在哪里停止。

边界契约说明跨过组件边界时双方必须满足的条件。它不是只有函数名和参数类型。最小契约还要指出缺失值的含义、调用与结果的关联、实际效果范围、提交与失败语义、使用的身份、记录责任以及适用版本。字段相同而意义不同,仍然是契约变化。

例如,新工具返回 ok=true,可能只表示任务进入队列,不表示对象已经创建。若宿主仍按“创建完成”推进,即使 API 名字未变,集成也已经破坏了原先验收条件。反过来,接口名称不同,但提交、核对、许可与版本语义能够保持,也可以通过适配完成迁移。名字不是兼容性的判据。

先画出任务实际经过的边界,未启用的模块不承担这次运行责任。已有框架可以落实这些契约,不需要为了称它为 harness 再包一层新的控制系统。

边界画清之后,要把这次运行依赖的版本写下来。运行清单(manifest)是描述一组可执行组件及其适用版本的结构化记录。它不是供应商产品目录,也不是把所有配置和凭证原文保存下来。最小清单要足以解释一个请求将怎样被处理,并让运行记录能够指向当时采用的组合。

至少记录以下边界。模型项包含接口、调用名、模式与关键配置;工具项包含 schema 与实际实现映射;方法项包含采用的 Skill 或固定方法版本;上下文项包含组装与发送策略;执行项包含效果范围及所依赖的执行器;记录项包含事件和摘要格式;验收项包含对象、判据与版本。没有使用 Skill 或其他可选能力时明确写未采用,不为填满清单创建空模块。

清单不必发展成通用配置语言。第3章的小系统可以直接固定 Chat Completions、显式关闭 thinking、两个工具映射、串行执行与当前记录格式。若一个标记不能帮助判断请求合法性、执行范围或验收依据,就不必先增加它。需要的是可解释的组合,而不是配置字段数量。

清单身份与组件版本还应能分别查询。只写一个“系统第二版”,很难判断哪项行为变化;只散落各组件版本,又难以确认运行采用的组合。可以为整份清单提供版本或内容摘要,并保留其中的边界项。内容摘要帮助关联清单字节,不证明清单来自可信发布者,也不应包含密钥。

运行要绑定实际采用的清单,而不是只在启动日志打印它。book/v2/harness.py 的 Harness.loop 将请求绑定到当时的工具映射、schema 和许可修订号,这是局部绑定;完整系统增加清单后仍须让响应解释和执行遵守同一绑定。仅记录旧版本、实际却调用全局最新实现,不算固定了契约。

验收版本同样属于组合。升级检查器后,旧回执仍只证明旧判据与原对象上的检查。若要依据新判据交付,重新核对适用对象并保存新结果,不能修改版本标签便把旧验收变成新验收。

13.2兼容性与旧运行迁移

兼容性是在声明条件下,某一版本能够正确消费另一版本的请求、记录或结果。它不是“没有抛异常”。最小兼容说明应给出生产方、消费方、方向、适用格式以及保留不了的语义。不同边界可以有不同结论,不能只写一个全系统兼容布尔值。

本文将后向兼容限定为新消费者能够处理旧生产者的数据,前向兼容限定为旧消费者能够处理新生产者的数据。团队采用其他命名也可以,但必须写清方向。模型响应、工具参数和持久记录分别判断;新程序能读旧账本,不表示它可以依据旧动作重做效果。

边界要核对的变化兼容成立所需条件
模型接口与模式返回结构、接续字段、工具调用结束语义原消息与调用关系仍可合法解释
工具参数schema、缺失、null、默认值原请求不被扩展或改成另一动作
执行与并发受理、重复提交、迟到结果原动作事实和许可范围仍可核对
记录与恢复格式、状态、对象引用能识别未知,不把读记录当作重执行
验收与价格判据、计量字段、计费条件新旧判断与费用口径分别可解释

矩阵应由实际变化填入“支持”“拒绝”或“待验证”,而不是默认全绿。旧程序遇到未知新字段时能否忽略,要看字段是否改变权力或语义。新增发送范围、提交身份或恢复状态不能作为无关字段静默丢弃。无法理解关键条件时停止,比强行读完更符合契约。

缺失、空值和默认值尤其不能靠重命名转换。旧接口缺少覆盖参数表示不覆盖,新接口缺少参数却默认覆盖,就需要显式保持原语义,或拒绝迁移。null 若表示清空字段,也不能与缺失混为一谈。模型模式的接续项、并发提交的重复处理和恢复状态,都有类似问题:字段能映射,不代表责任能保持。

价格变化也不是重命名。新的缓存计量或时段规则会改变费用解释,应保留实际 usage 与原日期基线,另按调用时价格核算。不能为了继续画一条成本曲线,就把新单价覆盖进旧运行并仍称原账单。接口、方法、恢复与价格分别核对,才能知道迁移改变了什么。

兼容方向确定后,迁移还要处理在途的旧运行。旧请求默认不得交给新实现解释,因为它是在旧 schema、方法、许可与输入表示下产生的。新实现可能扩大字段含义、改变默认动作或无法识别旧状态;这些变化发生时,模型当时并没有在新条件下提出请求。保留相同工具名,不能补回这一前提。

升级的最小过程分为旧运行处理、新组合验证、分批发布和停止条件。先列出旧运行处于等待、已提交、未知还是已结束。默认让旧运行按原来的组合走完,或停止新增动作后核对;没有旧版本执行条件、无法确认旧效果时,不把它直接转交给新包。确需迁移在途运行,必须另有明确的兼容与接手规则。

发布包是能够再次取得同一清单和对应实现的交付组合,不是代码仓库中一个会继续变化的分支名。它不要求把外部模型版本永远冻结,却要保留所能固定的实现、配置与依赖,并把不可固定项列出。只有版本标签而找不回原实现,旧运行就没有可用的固定执行依据。

新包验证先覆盖变化的契约,再执行原任务回归。增加异步、恢复或宽工具,不只检查正常路径,还要验证迟到结果、未知提交、失效许可和实际效果范围。人工结果核对与自动检查共同进入准入,业务负责人确认任务边界,没有发生真实联调的部分仍标为未验证。

分批发布应能识别每项任务实际采用的包,并预先写明停止扩大使用的条件。旧任务不因全局切换自动换包,新任务才按发布选择进入新组合。发现约束违反或未知激增时,停止新接入和新动作,保留已发生的事实,再决定如何核对。不能通过隐藏失败运行制造一次平滑升级。

回退是将后续适用请求切回已验证组合,不是让环境回到从未执行。新包产生的文件、远端对象、发送结果和费用不会随版本切换消失。旧包能否读取新记录,也取决于兼容矩阵。若旧包不认识新恢复状态,回退可以只影响新任务;在途运行继续核对或停下,不能为了恢复服务直接重做效果。

13.3层与组件的删减依据

固定版本与发布过程不是不断加层的理由。组件收益是它在相同任务条件下改善了什么,以及为此新增多少成本和责任。它不是“框架支持了这个模块”。最小判断同时看任务效果、约束、请求与工具消耗、延迟、重取及人工介入,并保留比较条件。

长期记忆若没有跨任务复用收益,却引入错误事实与纠正负担,可以不建。委派若未减少上下文干扰或等待,却增加消息关联与结果接收责任,可以回到同一 agent 单线推进。自动恢复若使用频率低、核对契约不完整,可以保持未知即停、人工接手。稳定 workflow 没有明确步骤收益,也不必为每项任务写一层流程。

删除这些可选层,不表示删除基础责任。没有恢复仍需留下提交意图与未知;没有记忆仍需保存当前任务事实;没有委派仍需控制版本与动作权限。简化应删掉未带来收益的组织方式,不删掉使结果可解释的条件。现有框架已经完成某项责任时,也不再并排建设另一套账本或调度器。

比较可以采用已验证的小系统作为基线,每次只增加准备评价的能力。收益不足便停用扩展,并检查它是否留下依赖或在途状态。退出不要求抹掉历史证据,也不能把尚未结束的动作遗忘。小系统是可长期工作的选择,不是必须升级成完整平台的过渡形态。

13.4组织使用中的授权与凭证

组织平台是可选扩展,但一旦采用,就改变了执行边界。本项目把两种接入责任称为 Provider 与 Connector:Provider 使用平台凭据访问下游;Connector 使用用户在目标平台绑定的凭据。这里的 Provider 不是模型供应商,这两个名称也不是行业统一分类。最小区分是每次操作明确谁提供凭据、谁决定可用范围、谁在实际执行处承担约束。

先解决身份,再谈授权。身份认证确认入口用户是谁,不授予资源权限。入口应取得可靠用户身份,并把它绑定到任务与工具边界;认证方式可以复用已有服务。授权决定这个主体对哪些资源、在什么范围内可以做什么;它不能由模型自报用户名或当前页面名称生成。

Provider 的平台凭据可能具有比当前用户更宽的下游权限,因此平台必须承担用户授权。RBAC 在这里指通过角色授予已定义的动作、资源与范围;它不是“有一个角色名称就能执行”。最小规则应能说出某角色在哪个工作区可以创建哪类对象。ABAC 指依据属性评价请求是否满足授权条件;它不是信任模型提交的任意标签。用户属性、资源归属、请求条件和当前状态应从可信来源取得,并说明更新时点。

GBAC 的具体语义需由采用它的团队先明确,不能据名称展开缩写或推定授权规则。本书不为未定义的名称补造机制;采用任何附加规则前,都须明确主体、关系、动作、范围及撤销语义,再说明它怎样与已有规则组合。

组合规则必须明确,但不存在本文能够代替团队决定的普世组合方式。某个平台可以规定显式拒绝优先,并要求用户授权范围、任务许可范围与执行能力上界取交集;也可以允许符合条件的独立授予产生许可。关键是把规则、冲突顺序与有效范围写清楚,不能临时从多个工作区取最宽权限,也不能遇到一个允许结果就跳过其余限制。

工作区在这里是服务端授权与资源归属的边界,不是浏览器当前标签。最小绑定包含入口用户、任务工作区、目标资源、动作、授予范围和策略修订号。工具真正执行时还要对应实际对象;任务写的是一个工作区,执行器却在另一个工作区创建,授权链仍然失效。

用户 a 在 g2 有创建权限,不代表在 g1 也有权限。不能用 g2 的授权检查放行,再把对象写入 g1。创建尚不存在的资源时,检查的是目标容器的归属、容器上的创建动作及约束;创建后再核对实际资源工作区与成员归属。不能要求先查不存在的新资源,也不能只验证请求里一个可由调用者修改的工作区字段。

下面是原则流程,不是当前随书代码已有的生产授权实现:

入口核验用户 → 固定任务工作区与许可版本
解析目标 → 从服务端查实际归属;创建则查目标容器
读取当前可信授权 → 按明示组合规则计算动作与范围
绑定执行请求 → 用户、任务工作区、目标、授予与策略修订
执行器复核并落实有效范围 → 不借平台宽凭据扩大操作
核对实际结果 → 资源归属、成员关系与允许发送范围
后台或恢复继续 → 保留原绑定,重验当前许可

生产实现还要说明授权检查与实际执行之间的变化如何处理。记录一个策略修订号不保证权限永远有效;撤权之后启动新动作,须依据当前许可。若下游支持按请求限制令牌范围,可以使用相应范围;否则由可信宿主执行通道落实请求级限权。持有宽 token 不等于可以把其全部能力暴露给模型,提示词和界面检查都不能代替执行处的限制。

读取与发送也沿同一绑定。允许读取一个对象,不等于可以把结果发给所有成员或外部模型;授权结果还需限制返回字段与接收者。后台任务和恢复不得改用操作者当前打开的标签。显式跨工作区操作可以存在,但要说明源与目标各自需要的动作、许可和发送条件,不无条件禁止全部跨区,也不无条件合并权限。

Connector 的重点不同。账户绑定是把本地用户与目标账户及连接使用权对应起来,不是发现一份可用 token 就拿来执行。最小连接记录包含使用归属、目标账户、环境、凭证引用、有效状态及明确操作限制。连接已建立,只说明认证路径可用,不表示目标资源已经全部获准。

目标平台承担资源授权的主责任,宿主不复制一套完整下游访问模型。但宿主仍须核验连接属于谁、当前任务是否允许使用,以及请求是否在宿主声明范围内。目标账户能够删除资源,当前任务只允许读取时,不能把账户能力当作任务许可。也不能让模型自己选择另一用户的连接,或在恢复时因原凭据失效换成平台宽账户。

凭证引用可以指向受控凭证存储,但不是秘密本身。刷新要沿原账户绑定,核对过期、撤销与环境;测试账户和生产账户不因用户名相似混用。撤销后停止新调用或要求重新授权,不静默换凭证。已有在途效果另行核对,凭证失效不能证明旧操作没有发生。

秘密不写入模型上下文、trace、命令参数或模型可控制的标准输入。外部工具显式构造所需环境,不继承宿主全部凭据;连接管理只把适用秘密交给对应可信执行通道。这里建设的是归属与使用边界,不是自建密钥管理服务。Provider 与 Connector 都要经过实际执行边界,但授权责任不能因使用同一工具接口就混成一套。

随书 book/v2/practices.py 的 provider_check 只比较给定用户、请求工作区、目标工作区、动作与 ProviderGrant;connector_check 只比较使用者、连接归属及绑定账户。test_practices.py 用纯函数用例检查 scope/account 不匹配时拒绝,没有连接平台、读取服务端授权、管理凭据或在下游执行限权。它们可检验局部关系,不是 Provider 或 Connector 平台实施,也没有定义 GBAC;实际授权与执行责任仍须由采用的系统落实。

13.5集成验证与形态选择

组件测试通过之后,还需要 集成验证:检查跨组件关系在真实执行路径中是否成立。它不是重复统计单元测试数量。最小验证选择一项许可明确、验收具体的任务,从入口绑定一直核对到实际对象与停止摘要,并记录采用的清单和未覆盖条件。

验证重点放在连接处。模型返回的缺失字段是否仍按原契约解释;上下文退出的材料是否确实可以按同版本展开;工具受理结果是否被误当成完成;验收对象是否属于本次动作;旧请求是否在新包上线后被错误分派。无需为每层再造演示程序,应沿实际工具和协调入口检查,而不是测试一个旁路展示函数。

采用组织扩展时,再核对实际资源归属和账户使用。构造用户在一个工作区获准、在另一个工作区未获准的请求,检查授权与实际创建没有串区;构造原连接撤销,检查恢复没有换用其他账户。明确观察的是宿主拒绝、下游拒绝还是禁止效果确实未发生。未采用这些模式的系统,不把这组测试当作运行前强制模块。

真实联调和受控模拟分别报告。模拟可以检查错误分支与调用关系,却不能证明下游的实际权限和计量行为。付费模型请求、目标平台操作及新增持久效果必须在明确许可下执行。已有第3章的本地测试与脚本生成的产物只支撑原小系统的检查,不自动成为新接口、新执行器或组织平台的实测证据。

若实际路径尚缺某项检查,就缩小可用范围。例如无法确认下游后台结束,只能声明已受理或未知,不交付最终完成;无法落实请求级范围,就不开放该宽凭据通道。缺口应改变系统承接任务的边界,而不只是报告里的备注。

经过验证,还要决定系统对使用者提供什么。工作系统在这里指能够重复承接声明任务、产生实际结果并如实处理停止的组合。它不是功能齐全的演示平台。最小交付说明任务入口、有效清单、允许效果、验收范围、预算和未知处理;读者据此知道何时能用,何时必须换方法或人工核对。

以固定摘录任务为边界,可以保留同一 agent、两个工具、可信串行执行、写前记录和独立验收。它不需要长期记忆、异步委派或自动恢复。任务改为跨次复用资料、远端后台创建或组织协作时,才增加对应能力与验证,并形成新的适用组合。不能只把目标文字改宽,而仍沿用旧任务的完成承诺。

能力声明要能逐项约束入口。仅支持新建对象,就拒绝隐式覆盖;不支持旧运行恢复,就停止自动接手;只验收原文与版本,就不声称内容可信。预算和价格基线也保持可解释,不拿小任务费用推断任意任务支出。用户看见的“完成”应对应当前有效验收,而不是模型最后一句自然语言。

扩展退出同样是工作形态的一部分。停用记忆后,新的任务不再读取它,但旧记录按保留规则处理;停用恢复后,在途未知由明确责任人核对;替换连接后,新任务使用新绑定,旧任务不自动迁移。可选能力不是随时切开关而没有状态后果。

最小系统与扩展系统可以各按准入范围长期并存。每次演进说明新增的可用任务、责任与证据,不要求简单任务经过所有层。

13.6本章判据

集成的出口不是架构图中每个框都存在,而是每条启用路径都有明确契约,变化能够被识别、验证和停止。可以用以下判据检查交付:

  • ☐集成说明输入、效果、权力和版本怎样跨边界,不以 API 名字相同判断兼容。
  • ☐最小清单绑定模型接口与模式、工具映射、方法、上下文、执行、记录和验收版本,未采用的扩展没有被强行创建。
  • ☐兼容矩阵写明消费方向及条件,schema、缺失、null、并发、恢复与价格变化分别核对。
  • ☐旧请求默认沿原组合结束;迁移在途运行另有规则,发布包能够取得固定实现。
  • ☐新包验证、分批采用和停止条件有证据;回退不声称撤回已经发生的环境效果。
  • ☐组件取舍依据效果与总成本,删去没有收益的层,但不删掉基本许可、记录与验收责任。
  • ☐若采用组织扩展,Provider 的平台授权与请求级限权、Connector 的账户归属与凭证使用责任分别落实。
  • ☐工作区由服务端绑定到实际对象,创建、读取、发送、后台和恢复不借当前标签或其他账户扩大范围。
  • ☐实际路径的验证与模拟证据分开,任务入口与完成声明没有越过已检查范围。

本章没有回答什么

本章没有给出所有框架、供应商和平台之间的通用迁移器,也没有冻结外部模型与服务行为。清单保留可固定部分,兼容矩阵指出需要核对的边界;未知接口、无法落实的执行范围和未验证的迁移仍需停止或限制使用。

本章没有定义团队未说明的 GBAC 语义,没有建设认证产品大全、下游完整权限副本或密钥管理服务,也没有承诺跨工作区与所有凭据场景普遍安全。组织扩展需要按实际授权规则和目标平台契约实施、验证。未采用它的读者,可以保持适合任务的小系统;采用之后,新增责任必须进入执行与验收,不能仅写在架构说明中。