Skip to content

Why NASDK? ​

一个长时任务中,多个应用之间经常需要的不只是一次远程函数调用。

一个任务可能持续数分钟,执行期间不断产生结果;调用方可能需要观察进度、发送补充信息,或者暂停、恢复和终止任务;多个任务还可能竞争同一块 GPU、同一个模型或其他有限资源。

TIP

是的孩子们,我就是在讲AgentRuntime经常遇到的问题。

这些需求可以分别用 RPC、消息队列、事件总线和任务调度器解决,但应用必须自行维护它们之间的身份、生命周期和状态关系。

并且,如果应用关注这些限制过多,会导致应用职责变得模糊。例如,如果LLMProvider过度去关注GPU的占用,则Provider很有可能会进一步长出队列和调度器,这就是经典的职责越界。

Not Only Req-Res ​

传统 RPC 擅长表达「调用一个函数,然后取得一个结果」。

当一次调用包含过程输出和运行时控制时,通常还需要额外建立流式接口、回调通道或控制接口。

NASDK 保留 Request-Response,同时增加三种与请求相关的消息:

  • notify 推送零到多个过程消息。
  • signal 向仍在运行的 Event 发送信息或控制指令。
  • ack 确认可靠消息已经到达。

这些消息由NASDK自行内部匹配,不需要业务方单独记录id匹配。

可编排的任务与流水线 ​

复杂任务通常无法由一个函数一次完成。

它可能需要根据上一步结果选择下一步操作,在本地计算与远程调用之间切换,等待异步结果,派生子任务,并在任意步骤失败时收束整个执行过程。

NASDK 将这类工作组织为三个层次:

  • Event 表示一次完整任务,承载从进入队列到成功或失败的生命周期。
  • Pipeline 描述任务如何逐步推进,并根据上一步结果决定下一步执行什么。
  • Task 是实际执行工作的最小单元,可以进行本地计算、调用模型或等待远程结果。

Pipeline 不需要把整个流程写成一条难以观察的异步调用链。每一步 Task 都有明确的输入、输出和状态,步骤之间可以保存上下文,也可以通过内建任务结束流水线或派生新的 Event。

这种编排方式适合多阶段 AI 推理、Agent 工作流、数据处理流水线和其他需要长时间运行、动态分支或子任务协作的工作。

传输协议与队列消息 ​

长时任务对网络波动更加敏感,并且传输的内容可能包含大型二进制。

一次几秒钟的调用可以在断线后直接重试,但一个已经运行数分钟、产生大量过程状态的任务,不应该因为连接短暂中断就从头开始。

NASDK 将应用消息与底层连接分开处理。NApp 面向目标 App ID 发送消息,NACT 负责通过 TCP、WebSocket 或 Unix Socket 承载数据,NACP 则负责请求、响应、订阅、通知、信号和确认之间的关系。业务逻辑不需要根据传输方式分别实现调用协议。

对于需要可靠送达的消息,NASDK 使用 ACK 确认消息已经到达。未收到 ACK 的消息会保留在待确认队列中;连接中断后,它们会进入待发送队列,在目标 NApp 于宽限期内重新连接时按原有顺序继续发送。

不同消息也不必承担相同成本:

  • Request、Response、Signal 和协议控制消息需要可靠送达。
  • Notify 用于过程状态和事件推送,不等待 ACK,避免高频过程消息阻塞关键控制消息。
  • 重复到达的可靠消息会再次获得 ACK,但不会被重复交给业务处理。
  • 队列具有数量和容量限制,避免失联节点无限消耗发送方内存。

这套机制让应用能够把注意力放在任务本身,而不是在每个调用点重复实现消息编号、确认等待、断线缓存、重发和去重。

此外,NASDK还具有能够直接传输大型二进制的功能,允许用户直接将Buffer存储在JSON内通过NASDK发送到另一端,一定程度上承担消息队列能力。

有限资源和调度 ​

在 AI Infra 中,GPU、模型上下文和部分外部服务都不是可以无限并发的资源。

如果每个业务模块都自行判断 GPU 是否空闲,那么锁、等待队列、超时和任务优先级会逐渐进入 LLMProvider。Provider 原本只需要负责执行模型调用,最后却同时承担资源管理和任务调度。

NASDK 将资源竞争放在 Task 调度层处理。Task 可以声明执行时需要占用的资源;运行时根据当前占用情况决定何时放行。

等待网络、数据库或远程响应的异步 Task 不占用这些资源,仍然可以并发推进。

如此,我们可以实现:

  • Provider 只负责完成一次具体执行。
  • Pipeline 只负责决定下一步做什么。
  • Task 调度器负责决定这一步什么时候可以运行。
  • 业务代码不需要重复实现锁和等待队列。

资源约束从业务实现中被抽离出来,但仍然和任务生命周期保持关联。任务暂停、失败或结束后,运行时可以统一处理资源释放和后续任务放行。

观测,并介入 ​

NASDK 会暴露连接、消息和执行过程中的 Event。应用可以用它们记录日志、统计耗时、展示实时进度,或者追踪一个 Event 当前位于 Pipeline 的哪一步、正在运行哪个 Task。

过程结果也不必等到任务完成后一次性返回。Task 可以持续上报处理结果,调用方通过 Event 请求附带的过程流实时消费这些数据。

此外,观察只能回答任务正在做什么,有些场景还需要改变它接下来怎么运行。

调用方可以向仍在运行的 Event 发送 Signal。普通 Signal 可以携带补充信息,控制 Signal 可以请求暂停、恢复或终止任务。

NACEB 还提供生命周期 Hook,让运行时内部能够在明确的状态转移点执行逻辑。其中,Veto Hook 甚至可以阻止部分状态转移,使运行时在下一刻重新检查条件。

Released under the MIT License.