Skip to content

Latest commit

 

History

History
137 lines (80 loc) · 14.6 KB

kernel.md

File metadata and controls

137 lines (80 loc) · 14.6 KB

Aide 的 Controller Runtime

Aide 同时发展个人助手与 TypeScript controller-runtime 底座;Personal 以真实业务检验底座能力,底座不感知其 CRD。Aide 底座是 TypeScript 的 controller-runtime:插件声明资源,Controller 根据变化读取当前状态,通过能力接口执行动作,再保存结果与下一次唤醒条件。Personal 在其上实现个人助手;单机是交付方式,资源协调模型可以由未来的 Kubernetes CRD 后端承载,当前使用本地持久化。

概念与所有权

概念 职责
ResourceDefinition 插件声明类型、Schema、校验、Printer、索引与保留策略
ResourceClient / Storage 统一身份、版本、事务、引用、容量与持久化
Controller / Reconcile 围绕一个资源实例推进领域状态
Source / Watch 发现资源,将变化映射为协调请求
ApplicationRuntime 装配插件实例、调度、Connector 与可选执行能力
Harness 承接模型和工具执行,拥有原生历史与可恢复会话
Plugin 拥有领域模型、完成条件、恢复策略与对外行为

业务资源属于插件实例与 namespace,身份不依附执行 Session。底座不预注册 Input、Output 或 Topic;一个插件可以只观察和协调资源,另一个插件可以通过 Harness 请求判断。应用负责装配通信入口和投递能力。

底座能力的演进依据

资源更新、并发、条件写入与协调机制优先对齐 Kubernetes API / controller-runtime 的成熟语义。遇到业务层冲突、重试或协作需求,先检查 ResourceClient、协议、Storage 和 Controller 的公共能力是否准确,再决定是否需要领域特例;底座能力缺口由底座解决,插件保留字段所有权和业务判断。已有机制可复用时不新增上层补丁或独立版本体系。

Resource 是更新语义、Kubernetes 对应关系、当前实现缺口及验收边界的主说明;公共接口位于 packages/plugin。差异需明确记录:本地多资源事务是 Aide 的能力,不假定 Kubernetes 后端天然支持。实现状态与设计目标分别标明,不能把参考模型写成已交付能力。

一次协调如何推进

  1. Source、API 或工具通过 ResourceClient 创建或更新资源。
  2. 存储在事务中完成校验、版本、索引和容量检查,提交后发布变化。
  3. 主资源变化或显式 Watch 映射为去重队列中的资源身份。
  4. Reconcile 读取最新状态,决定直接请求外部能力、调用 Harness,或等待。
  5. 业务组件保存进展和回执,必要时返回下次唤醒时间。

同一 Controller 对同一资源串行,不同资源可以并行。多个具名 Controller 可以观察同一种资源,有各自的队列和定时记录,当前共享写入使用资源版本 CAS;局部 Patch 的演进见 Resource 更新契约。纯 status 更新不自动唤醒主 Controller,协作方按需声明 Watch。事件用于唤醒,持久资源承载事实。Host 按插件实例与精确资源类型维护 Watch 订阅表,先过滤后分发到 Controller / Runner;namespace 和事件谓词继续在对应边界检查,注册、卸载同步维护订阅。

动态 deadline 使用带位置索引的最小堆,新增、提前、延后和取消为 O(log n),每个活跃 key 只有一个堆项;到期只弹出到期项,不扫描所有定时资源。scope 卸载仍遍历该进程的定时项。定时器不承载持久事实,重启从 control 恢复。

Reconciler 与 Agent 的分工

Reconciler 是模块的入口:接收 CRD 变化,直接完成确定性工作,并决定何时触发 Agent;Agent 带着上下文负责语义判断与具体行动。 Reconciler 根据持久状态安排优先级、执行接纳、重试与等待。例如 Route 先由 Reconciler 按明确规则直接分派,需要语义判断时才触发 Agent。具体业务规则属于插件,通用运行时提供队列、并发和执行能力。

角色 负责的判断 交付给协作方的内容
Reconciler 直接执行确定性规则,安排优先级,决定调用 Agent 或等待 确定性处理结果,或交给 Agent 的任务、触发原因与约束
Agent 如何理解材料、采取哪些动作、是否需要调整 工具动作、业务结果、判断依据及需要等待的条件
工具与资源事务 动作是否满足资源范围、版本、执行归属等硬约束 可核对的状态变化、回执或明确失败

任务交接需要说明“为什么现在做、希望检查什么”,具体操作由 Agent 根据上下文选择。数量阈值可以触发整理检查,但不直接证明哪些对象相关,也不强制 Agent 修改组织结构;决定保持现状时同样留下判断依据。执行结束和业务完成分别依据执行事实与业务回执判断。

Personal 用 aide:review / aide:triage / aide:organize Input 承载 Chief 的回顾、分理和组织请求,并由对应 Reconciler 调用各角色;这种交接形式属于 Personal,通用底座不要求插件使用 Input。业务场景见 Topic 的分层整理与收敛。

Host 与 Runner

Host 持有资源存储、Connector、Harness Adapter 和原生权限审批;Runner 运行插件回调、Source、Watch、队列、重试和 Reconcile。每个启用插件实例有自己的 Runner,数量不随 Topic 增加;进程内插件使用相同契约。

双方通过 src/protocol 协作,不互相导入实现。公共契约位于 packages/plugin。资源定义在恢复和 Controller 启动前加载,校验、打印与容量规则不依赖 Runner 存活。插件私有目录按 package global 与 instance 组织。

执行后端的边界

ApplicationRuntime 始终提供资源协调,按需装配 ExecutionService。Manager 通过 HarnessExecution 能力请求执行,不读取原生历史。Operator 经 harness verb 操作 Harness interface,传入配置名与可选原生 sessionId;接口契约见 Harness。

运行时用插件实例、资源 UID 与 Controller 定位调用范围,删除后同名重建获得新的范围。Operator 自己保存恢复参数,例如 Personal 的 status.agent;Harness verb 不访问资源,也不约定 status 结构。持久会话、压缩与恢复由 Harness 负责,服务重启不会回放 Aide 的调用栈。

HarnessActivity 提供有界进程内执行投影;诊断日志用于排查,不参与恢复。执行结束只说明调用收口,目标达成、输入确认与通知送达由业务组件分别判断。取消或超时不能证明外部副作用没有发生。

能力与事务

Plugin / Operator 通过 ResourceClient 操作 CRD,通过 Verb 发起非 CRD 操作。运行时管理调用关联、期限、取消和诊断;业务元数据以不透明 attributes 传递,只有所属插件解释其含义。

资源事务可组合业务状态与回执,不能覆盖外部请求。外部动作与结果落盘之间中断时,插件应核对已有副作用。Connector 自持调用记录,未完成调用在重启后记为 interrupted,不重放外部请求。

资源所有者声明能否释放,Host 执行容量限制与合格对象的淘汰排序。未完成的工作不能仅因 LRU 而被删除。事务、引用和容量的具体契约见 Resource。

Controller 局部并发和 Runner 全局并发共同限制新 Reconcile 的启动。全局默认 8,由 reconcile.maxTotalConcurrency 配置;局部阈值由 Controller 声明。等待 verb 时释放两层容量,返回后恢复计数并直接继续,不重新排队。恢复允许暂时超限;达到或超过阈值时停止启动新执行,已有执行继续推进。同一 Controller 对同一资源的串行约束贯穿等待与恢复。

该阈值不限制所有尚未结束的外部调用,也不保证超限幅度或持续时间;Connector 与 Harness 各自控制下游预算。Controller watchdog 在等待 Host verb 时暂停,返回后继续计时,不存在恢复容量的排队等待。插件根据持久事实恢复,不能依赖进程内队列或异步调用栈跨重启存在。

助理定位与身份边界

Aide 是服务于用户的独立助理。它从自身视角观察信息、形成判断、提出建议,并在授权范围内执行工作。用户是 Aide 服务和理解的对象;Aide 不将用户的经历、表达、意愿或承诺视为自己的经历、表达、意愿或承诺。

这是 Personal 的产品契约,由 Chief、Route、Weave、Task、Routine 共同遵守;通用运行底座不解释人物身份或业务授权。各 Agent 是同一个助理的内部角色,不是不同人物。

为何不用数字分身定位

“数字分身”隐含更强的产品承诺:系统能够以用户的身份延续其判断、表达和行动。Aide 选择独立助理定位,优先建立可靠的服务关系、事实归属和授权边界,原因有三点:

  1. 掌握信息不等于掌握意愿。 用户发出、收到和观察到的信息可能包含试探、客套、引用或尚未成熟的想法。分身需要推断“如果是用户,此刻会怎么做”;助理可以明确提出自己的建议,让用户区分已表达的意愿与系统的判断。
  2. 代表用户需要更高的准确性和更细的授权。 助理的建议可以被拒绝或纠正;以用户身份表态、作出承诺,则可能被他人直接视为用户的决定。分身需要理解不同关系、场合和事情中的代理边界,仅靠了解偏好不足以承担这一责任。
  3. 独立身份便于保留分歧和纠错。 助理可以依据新证据质疑用户原有判断,也可以明确承认自己的推断有误。区分用户立场与助理判断,有助于发现偏差,避免系统生成的观点反过来被记成用户的偏好或意愿。

即使采用数字分身定位,也必须区分“用户本人说过”“系统推测用户会认可”和“系统获授权代为提出”。代理权限不能把生成内容变成用户的历史表达,用户采纳也不改变建议的原始作者。

助理定位允许 Aide 深入理解用户、主动发现机会、持续跟进,并在授权范围内自主行动。代理范围可以扩大,助理身份与事实归属仍须保持清楚;更多信息或更强能力不会自动改变这一产品定位。

身份定义

角色 定义 渠道身份示例
被服务者(Me) Aide 持续服务的用户,其目标、偏好和授权是助理开展工作的依据 李乾坤的 Lark 用户身份
助理(Aide) 具有独立表达、判断和行动归属的助手 Aide 的 Lark 机器人身份
其他人 与被服务者或助理发生交流的其他主体 同事的 Lark 用户身份

角色、主体与渠道身份分别表达不同事实。一个主体可以拥有多个渠道身份;身份通过平台、作用域和 ID 识别,姓名不能作为唯一依据。缺少身份信息时保留未知,不通过同名或聊天位置猜测身份。

访问凭证决定 Aide 能读取或操作哪些外部资源,不决定 Aide 是谁。使用被服务者的凭证读取消息,不改变消息的作者、接收者,也不使 Aide 成为被服务者。

输入关系与交流对象

sent / received / observed 始终描述 Input 与 Me 的关系:Me 发出的、Me 收到的,以及 Me 可观察到的其他交流或事件。它们不直接说明消息是否面向 Aide。

处理输入时,必须区分作者、交流对象和对助理的含义。Me 发给同事的消息属于外部交流观察;别人直接向 Aide 发消息,也不意味着发信人就是 Me。群聊中存在 Aide,不代表每条消息都在对 Aide 说话。

自动输入预览保留必要身份线索。Lark Source 的模型预览逐条标明作者、相对 Me 的关系、提及对象和回复引用;多作者讨论不能仅拼接正文。原始正文与页面标题不被身份说明替换。Channel 接纳的消息说明其直接交流入口,并保留已知机器人身份。提及对象不是完整接收人列表,未知接收者不补造;完整证据仍由 read_input 按需读取。

观察、委托与代理

外部交流提供事实和背景。Me 向同事提问不自动成为向 Aide 提问;Me 向别人承诺完成工作不自动成为对 Aide 的执行委托;其他人的要求不自动获得 Me 的授权。

Aide 可以主动关联信息、发现变化、提醒和提出建议,并在已有委托范围内推进工作。代表 Me 表达立场、作出承诺或执行外部动作,需要相应授权;已经授权的范围内无需每一步重复确认。工作交接需区分交付给 Aide 的目标、授权范围、背景事实和未确认建议,主题归并不会扩大授权。

直接回复与按输入推导目的地仅适用于 Channel 输入。Source 的观察地址不自动成为联系 Me 或其他人的路径,即使该观察被标为紧急。主动通知需使用独立已知且符合授权的目标;目标的可达性不等于授权。

认识与表达的归属

Topic、Person、工作摘要及长期记忆必须区分原始表达、助理推断、助理建议和用户确认。使用明确主体;引用“我”等第一人称原话时保留作者,避免后续读取者误认叙述主体。

Aide 提出的建议归属于 Aide。Me 采纳后记录采纳事实,保留原始提出者和确认范围,不能推导出未确认的其他意愿或委托。提出者、决策者和执行者可以不同。动作提议、授权、执行以及 Output 接纳、送达和对方确认分别依据实际证据记录。

Weave 归并与记忆压缩可以精简内容,但必须保留重要信息的归属、确认状态和不确定性。旧摘要中来源不明的“我提出”不构成 Me 表达或授权的证据;无法核实时保留未知,不补造归属。

例如:同事提出 dashboard 建议,Me 回复“我来弄下”,Aide 随后补充 doctor 方案。认识应分别保留同事的建议、Me 的承诺和 Aide 的未确认方案,不能合写为“Me 提出的方案”,也不能自动把实现任务交给 Aide。

应用方式

Personal 将 Channel / Source 的内容保存为 Input,经 Route 归入 Topic,由 Chief 研判并按需交给 Task / Routine。Input.status 保存 route / assess / handle 痕迹;Output 独立记录表达与投递;Person 保存身份和认识。

应用装配在 src/app.ts 完成。配置在启动时解析,详见 配置;运行目录、备份和诊断见 部署,真实依赖验收见 E2E。