← 返回目录

第 1 卷

第 1 / 4 卷日期:

01|时之可逆:Context、插件与可撤销的 Effect

张嘉熙 · DeepSeek Harness 前沿工程实践

图 1-1
图 1-1

你好,我是张嘉熙。欢迎来到《DeepSeek Harness 前沿工程实践》的第一讲。这一讲我们来聊聊 Cordis。

Cordis 的定位是「时空可组合性的元框架」。乍一听不好理解,不过你别被这些词吓住,你可以把普通框架想象成一份乐高积木的拼装说明书,而元框架就是积木凹凸点之间的拼接规范:它不关心你能拼成什么,只管任何积木块之间都能“咔哒”扣上、也能随时拆开。

图 1-2
图 1-2

「时空可组合性」则来自一篇论文《A Programming Paradigm for Spatiotemporal Composability》,它把“组件拆装”这件事,抽象成两个正交的维度:

时间维度:一个组件被移除时,它对环境所做的修改,能不能被干净地逆转?

空间维度:多个组件存在依赖关系时,被依赖的一方一旦发生变化,依赖方能不能自动地跟着激活或停用?

课程前两讲会分别沿着这两个维度展开。这一讲,我们先重点关注时间维度,也就是标题里的「时之可逆」。其实它的精髓可以浓缩成一句话:

每一个产生副作用(Effect)的行为,在 Cordis 中都能成对地定义好“副作用”和“怎么撤销它”;框架保证,只要你返回了正确的清理函数,当这个行为被取消时,“怎么撤销它”一定会被兑现。

Cordis 当然不能真的让时间倒流,却可以提供一套机制,让副作用能彻底、可靠地撤销,回到副作用发生之前的状态。

Context 和插件

我们先来了解 Cordis 的一些基本概念,这是官方教程里的 hello.ts,我给代码补上了中文注释:

// 来自官方 cordis-tutorial 第一章的 hello.ts
import type { Context } from '@deepseek-ai/cordis'

// 插件的显示名,用于诊断信息(可选)
export const name = 'hello'

// apply 是插件的入口,框架会调用它
export function apply(ctx: Context) {
  console.log('hello from my first plugin')
}

这个例子极简,但它已经暴露了 Cordis 世界里最核心的两个词:

Context(上下文,简称 ctx):就是传给 apply 的那个参数。它是“共享环境”的化身 ——插件要往环境里装东西、从环境里拿东西,全都通过它。

插件(Plugin):就是一个可独立装卸的功能单元。它对外只有一个入口 apply(ctx) ——框架在加载时调用它一次,把 ctx 递进来,插件可以在这个 ctx 上声明自己要什么、提供什么。

在 Cordis 中,插件可以有三种形态:

import { Service, type Context } from '@deepseek-ai/cordis'

// 1. 函数形态(最常用):直接导出 apply 函数
export function apply(ctx: Context) {}

// 2. 对象形态:一个带 apply 方法的对象
export const objectPlugin = {
  name: 'object-plugin',
  apply(ctx: Context) {},
}

// 3. 类形态:Service 子类(第二章的主角,这里先混个脸熟)
export class MyService extends Service {
  constructor(ctx: Context) {
    super(ctx, 'myTutorialService')
  }
}

现在我们只需要知道有这样三种写法,如果你不需要公开服务,直接使用第一种函数形态即可。

可撤销的 Effect

刚刚我们已经了解了一些基本概念,现在来看看这个例子:

全站分卷索引 · 4 卷
  1. 1第 1 卷
  2. 2第 2 卷
  3. 3第 3 卷
  4. 4第 4 卷