编程 Cordis 深度拆解:DeepSeek Harness 的"可逆副作用"插件内核——如何让 AI Agent 的每个模块都能安全热拔插

2026-08-17 18:14:10 +0800 CST views 16

Cordis 深度拆解:DeepSeek Harness 的"可逆副作用"插件内核——如何让 AI Agent 的每个模块都能安全热拔插

写在前面

2026年8月13日,DeepSeek 在发布 V4 Pro 正式版的同时,开源了旗下首款 Agent 产品——DeepSeek Harness(DSH)。这个框架的核心不是模型,而是插件架构:模型、工具、技能、会话、存储、主循环,全都可以替换、升级、热拔插。

但真正让我停下来多看了两眼的设计,是驱动这一切的底层内核——Cordis。它的核心设计哲学只有一句话:每个副作用都附带逆操作。这不是简单的"注册/注销"机制,而是一套用依赖注入 + 可逆副作用构建的插件图管理方案。

这篇文章,我们把 Cordis 从里到外拆一遍:它解决了什么问题、核心抽象是什么、代码怎么写、与 LangChain/AutoGen 的插件系统有什么本质区别,以及你在生产环境中怎么用它。


一、背景:为什么 AI Agent 框架需要"可逆副作用"

1.1 AI Agent 的插件困境

在传统的 AI Agent 框架里,"插件"(或叫 Tool、Extension、Skill)通常长这样:

注册一个工具 → 框架持有引用 → 卸载时只能等 GC

问题在哪?当一个 Agent 插件做了以下任何一件事,卸载它就会变成一场灾难:

  • 启动了一个后台进程(比如一个长期运行的评估任务)
  • 修改了全局状态(比如注册了一个全局 HTTP handler)
  • 打开了文件句柄或网络连接
  • 修改了环境变量
  • 写入了一个持久化存储

更复杂的是,AI Agent 的插件通常工作在嵌套调用链里:A 插件调用了 B 服务,B 服务调用了 C 工具链。当你要卸载 A,理论上应该按依赖图的逆序清理——但谁来维护这张图?框架?还是插件自己?

如果插件自己维护,那就等于每个插件都要写一整套"自己的清理逻辑",而且还得知道谁依赖了自己。这是灾难级的耦合。

1.2 现有方案的局限

来看看目前主流 AI Agent 框架是怎么处理这个问题的:

LangChain:插件(Tools)基本上是无状态的函数,注册和卸载就是加到/移除列表。状态全靠外部管理。这意味着 LangChain 的工具集基本不支持有副作用的长期任务。

AutoGen:会话管理器负责生命周期,但插件卸载时的清理逻辑由插件自己负责。没有统一的可逆性保证。

CrewAI:类似地,工具是附加到 Agent 上的,卸载 = 列表删除。没有跨插件依赖追踪。

这些方案有一个共同点:它们假设插件是无状态的或自包含的。一旦你的插件需要管理外部资源(比如沙箱环境、数据库连接),就束手无策。

1.3 Cordis 的设计起源

Cordis 的设计动机就来自于这个真实的工程痛点。DeepSeek 在构建 Harness 的过程中发现:

如果每个插件都能声明自己的副作用,同时声明"如何撤销这些副作用",那么框架就能在插件卸载时自动执行清理,而不需要插件之间相互知道对方的存在。

这个想法不是 Cordis 首创的——它本质上来自事务性编程函数式编程的副作用管理思想(类似 Monad 的 bracket、ZIO 的 acquireRelease、或 C++ 的 RAII)。但 Cordis 把这个思想落实到了 AI Agent 插件系统 这个场景,并且做得相当工程化。


二、核心抽象:Context、Service、Plugin 三层模型

Cordis 的整个架构建立在这三个核心抽象上:

Context(上下文)
  └── Plugin(插件)
        ├── Service(服务)
        ├── Event Handler(事件处理器)
        └── Dependency(依赖声明)

2.1 Context:全局插件容器

Context 是 Cordis 的顶层容器,类似于依赖注入框架中的 IoC Container。它负责:

  • 加载和卸载插件
  • 维护插件之间的依赖关系图
  • 在卸载时自动触发逆操作
  • 提供服务查询接口
# Cordis Python SDK 核心接口(参考 GitHub: deepseek-ai/deepseek-harness)
from cordis import Context, Plugin, Service

# 创建根上下文
ctx = Context()

# 向上下文注册一个服务
ctx.register("vector_store", MyVectorStore())

# 在上下文中查询服务
store = ctx.get("vector_store")

Context 的关键设计点在于:它是一个树形结构。可以创建子上下文(ctx.child()),子上下文卸载时只清理自己的插件,不影响父上下文。这对 AI Agent 场景特别重要——比如你想在一个隔离的子上下文中运行一个临时任务,任务结束后直接销毁子上下文,所有副作用自动回滚。

# 创建子上下文,运行临时任务
with ctx.child() as subctx:
    subctx.load(temporary_plugin)
    # ... 运行任务,所有资源由 subctx 管理
# 退出 with 块时,subctx 自动卸载,逆操作全部执行

2.2 Plugin:带生命周期声明的单元

一个 Cordis 插件不是简单的函数集合,而是一个带生命周期声明的包

from cordis import Plugin, hook

class SandboxPlugin(Plugin):
    name = "sandbox"
    version = "1.0.0"
    
    # 定义依赖的其他服务
    requires = ["llm_adapter", "logger"]
    
    # 提供给其他插件的服务
    provides = ["sandbox_runtime"]
    
    @hook("on_load")
    def on_load(self, ctx: Context):
        """插件加载时执行"""
        # 启动沙箱进程
        self.process = subprocess.Popen(
            ["firecracker", "--config", self.config_path],
            stdout=subprocess.PIPE,
            stderr=subprocess.PIPE
        )
        # 注册逆操作:在卸载时杀死进程
        ctx.register_reversible(
            action=lambda: self.process.terminate(),
            reversal=lambda: None,  # 进程终止不需要逆操作
            description="terminate_firecracker"
        )
        
        # 注册服务
        ctx.register("sandbox_runtime", SandboxRuntime(self.process))
    
    @hook("on_unload")
    def on_unload(self, ctx: Context):
        """插件卸载时执行——通常不需要手动写,
        Cordis 会自动执行通过 register_reversible 注册的逆操作"""
        pass

这里的关键是 ctx.register_reversible() ——这是 Cordis 的核心机制。插件不是通过"记住自己做了什么"来回滚,而是通过声明式地向 Context 注册"正操作+逆操作"对来实现可逆性。卸载时,Cordis 自动按逆序执行所有已注册的逆操作。

2.3 Service:带接口的服务对象

Service 是一个标记性抽象,代表"其他插件可以依赖的服务"。它本质上就是一个 Python 对象,但通过 Cordis 的类型系统,带上了依赖关系和生命周期语义:

from cordis import Service, implements

class LLMAdapter(Service):
    """LLM 适配器服务接口"""
    async def complete(self, prompt: str) -> str:
        raise NotImplementedError

@implements(LLMAdapter)
class DeepSeekAdapter(LLMAdapter):
    def __init__(self, api_key: str, model: str = "deepseek-chat"):
        self.api_key = api_key
        self.model = model
    
    async def complete(self, prompt: str) -> str:
        # 调用 DeepSeek API
        ...

通过接口抽象,插件之间的依赖就变成了接口依赖而不是具体类依赖。这意味着你可以:

  • 开发时用 mock 服务,上线时换真实服务
  • 同时运行多个实现(比如同时用 DeepSeek 和 OpenAI 做对比)
  • 在测试时注入桩服务

三、可逆副作用机制:从原理到实现

这是 Cordis 最核心、也是最有技术含量的部分。

3.1 为什么要"可逆"而不是"清理"

常规的资源管理思路是"清理"(Cleanup):

# 传统思路:插件自己管理自己的清理
class OldStylePlugin:
    def setup(self):
        self.file = open("/tmp/output.txt", "w")
        self.process = subprocess.Popen(["daemon"])
        os.environ["PLUGIN_ACTIVE"] = "1"
    
    def teardown(self):
        self.file.close()       # 关闭文件
        self.process.terminate() # 终止进程
        del os.environ["PLUGIN_ACTIVE"]  # 恢复环境变量

问题在于:teardown() 方法必须精确知道 setup() 做了什么,并且顺序要对。如果插件在运行过程中动态创建了额外资源(比如插件本身又调用了其他服务),那么 teardown() 需要知道这些依赖的资源链才能正确清理。

Cordis 的思路是每次做副作用操作时立即注册逆操作

class CordisStylePlugin:
    def setup(self, ctx: Context):
        # 打开文件 → 同时注册"关闭文件"作为逆操作
        ctx.register_reversible(
            action=lambda: open("/tmp/output.txt", "w"),
            reversal=lambda f: f.close(),  # 逆操作接收 action 的返回值
            description="open_output_file"
        )
        
        # 修改环境变量 → 同时注册"恢复旧值"作为逆操作
        old_val = os.environ.get("PLUGIN_ACTIVE")
        ctx.register_reversible(
            action=lambda: os.environ.__setitem__("PLUGIN_ACTIVE", "1"),
            reversal=lambda _: os.environ.__setitem__("PLUGIN_ACTIVE", old_val),
            description="set_env_PLUGIN_ACTIVE"
        )
        
        # 启动进程 → 逆操作是终止它
        ctx.register_reversible(
            action=lambda: subprocess.Popen(["daemon"]),
            reversal=lambda p: p.terminate(),
            description="spawn_daemon"
        )

这样,setup() 中的每行代码都同时记录了"如何撤销"。当 Cordis 执行卸载时,它只需要按逆序执行所有已注册的 reversal 就行了——不需要插件自己维护清理逻辑,也不需要框架知道具体操作是什么。

3.2 实现原理:撤销栈(Undo Stack)

Cordis 内部维护一个撤销栈(Undo Stack),每个 register_reversible 调用就是往栈上压一条记录:

撤销栈(后进先出)
┌─────────────────────────┐
│ reversal_4: p.terminate() │  ← 最后注册,最后执行
├─────────────────────────┤
│ reversal_3: env恢复       │
├─────────────────────────┤
│ reversal_2: f.close()     │
├─────────────────────────┤
│ reversal_1: (无逆操作)    │
└─────────────────────────┘

卸载时,从栈顶向下依次执行逆操作。如果某个逆操作本身也产生了副作用(这在实际中很常见),Cordis 会继续为这个"逆操作的副作用"注册新的撤销记录——形成嵌套撤销栈

这和数据库事务的 UNDO 日志非常像,区别在于:

  • 数据库的 UNDO 记录的是"旧数据",恢复时直接覆盖
  • Cordis 记录的是"可调用函数",恢复时执行任意清理逻辑

3.3 跨插件依赖的清理:依赖图 + 拓扑排序

现在考虑一个更复杂的场景:

┌─────────────┐     requires     ┌──────────────┐
│  Sandbox    │ ──────────────▶ │  LLM Adapter │
│  Plugin     │                  │    Plugin    │
└─────────────┘                  └──────────────┘
       │                                 ▲
       │            provides            │
       └────────────────────────────────┘

Sandbox 插件依赖 LLM Adapter 插件。如果要卸载 LLM Adapter,Cordis 需要:

  1. 检测到 Sandbox 依赖它
  2. 先卸载 Sandbox(或拒绝卸载 LLM Adapter)
  3. 再卸载 LLM Adapter

Cordis 的依赖管理基于 声明式依赖

class SandboxPlugin(Plugin):
    requires = ["llm_adapter"]  # 声明依赖
    
    @hook("on_load")
    def on_load(self, ctx: Context):
        # Cordis 保证:在 on_load 执行时,llm_adapter 已加载
        # 可以直接使用
        llm = ctx.get("llm_adapter")

在加载时,Cordis 执行拓扑排序,保证依赖的插件先加载。在卸载时,Cordis 执行逆拓扑排序——先卸载没有其他插件依赖的叶子节点,再层层向上。

# Cordis 卸载时的依赖处理伪代码
def unload_with_deps(ctx: Context, plugin_name: str):
    # 1. 构建依赖图
    dependents = ctx.get_dependents(plugin_name)
    
    if dependents and not force:
        raise PluginInUseError(
            f"Plugin '{plugin_name}' is still required by: {dependents}"
        )
    
    # 2. 递归卸载依赖它的插件(自身不算)
    for dep in dependents:
        unload_with_deps(ctx, dep)
    
    # 3. 执行本插件的撤销栈(后进先出)
    ctx.undo_plugin(plugin_name)

3.4 子上下文隔离:嵌套撤销栈

子上下文机制是 Cordis 处理"临时任务隔离"的方案:

# 主上下文:包含基础服务
main_ctx = Context()
main_ctx.load(core_plugin)   # 全局共享,不会被临时任务影响
main_ctx.load(llm_adapter)

# 临时任务:在子上下文中运行
async def run_temp_agent(task: str):
    async with main_ctx.child() as task_ctx:
        # 临时任务只在这个子上下文中加载自己的插件
        await task_ctx.load(sandbox_plugin)  # 独立沙箱
        await task_ctx.load(custom_tool_plugin)
        
        # 运行 Agent
        agent = Agent(runtime=task_ctx.get("sandbox_runtime"))
        result = await agent.run(task)
        
        return result
    # with 块结束时:
    # 1. 触发 task_ctx 的撤销栈(按逆序执行所有注册的 reversal)
    # 2. 关闭所有临时资源
    # 3. 主上下文的插件完全不受影响

这在 AI Agent 场景中非常有价值。比如你要并发运行多个 Agent 任务,每个任务需要自己的沙箱环境、自己的工具集、自己的临时存储——子上下文让这一切变得干干净净。


四、DeepSeek Harness 如何使用 Cordis

4.1 Harness 的插件体系

DeepSeek Harness 基于 Cordis 构建,官方定义的插件类型包括:

插件类型说明示例
llmLLM 模型适配器DeepSeek 适配器、OpenAI 适配器
tool工具注册表搜索工具、代码执行工具
skill技能包某个垂直领域的工具集合
session会话管理内存会话、持久化会话
sandbox隔离执行环境Firecracker microVM、Docker
storage持久化存储文件系统、向量数据库
loopAgent 主循环ReAct 循环、Plan-Execute 循环
scheduler任务调度器优先级调度、并发控制
ui用户界面CLI、Web UI

所有这些插件都遵循 Cordis 的 Plugin 接口,通过 requires/provides 声明依赖关系。

4.2 用 Harness 配置一个多模型路由 Agent

以下是 Harness 的典型配置文件(YAML 格式),展示如何用 Cordis 插件系统组合出一个具有多模型路由能力的 Agent:

# harness.yaml
name: "multi-model-router"
version: "1.0"

plugins:
  # LLM 适配器:同时接入多个模型
  - name: llm/deepseek
    package: cordis-llm-deepseek
    config:
      api_key: ${DEEPSEEK_API_KEY}
      model: deepseek-chat
      max_tokens: 8192
  
  - name: llm/openai
    package: cordis-llm-openai
    config:
      api_key: ${OPENAI_API_KEY}
      model: gpt-4.6-turbo
  
  - name: llm/claude
    package: cordis-llm-anthropic
    config:
      api_key: ${ANTHROPIC_API_KEY}
      model: claude-sonnet-4-20250514
  
  # 工具集
  - name: tools/search
    package: cordis-tools-websearch
    config:
      engine: brave
      api_key: ${BRAVE_API_KEY}
  
  - name: tools/code_exec
    package: cordis-tools-code
    requires: [sandbox/default]
    config:
      timeout_seconds: 30
      max_memory_mb: 512
  
  # 沙箱
  - name: sandbox/default
    package: cordis-sandbox-firecracker
    config:
      snapshot_path: /opt/harness/base-snapshot.bin
      network_bridge: harness-br0
  
  # Agent 主循环:多模型路由循环
  - name: loop/router
    package: cordis-loop-model-router
    requires: [llm/deepseek, llm/openai, llm/claude]
    config:
      routing_policy: "cost-quality-balance"  # 或 "fastest", "highest-quality"
      fallback_order: [deepseek, openai, claude]
      thresholds:
        coding: { model: claude, min_quality: 0.85 }
        fast_response: { model: deepseek, max_latency_ms: 2000 }
        default: { model: openai }

这份配置不需要写一行 Python 代码。Cordis 会自动:

  1. 按拓扑序加载所有插件
  2. 验证依赖完整性
  3. 启动各插件的副作用
  4. 注册所有逆操作

4.3 代码级插件开发

如果要开发自己的 Cordis 插件,完整流程如下:

# cordis_my_tool/__init__.py
from cordis import Plugin, hook, Service, contextproperty
import httpx

class MyWebSearchService(Service):
    """自定义搜索服务"""
    
    def __init__(self, api_key: str, engine: str = "brave"):
        self.client = httpx.AsyncClient(
            headers={"Authorization": f"Bearer {api_key}"},
            timeout=10.0
        )
        self.engine = engine
    
    async def search(self, query: str, top_k: int = 5) -> list[dict]:
        response = await self.client.post(
            f"https://api.search.{self.engine}.com/v1/search",
            json={"q": query, "count": top_k}
        )
        return response.json()["results"]


class MyToolPlugin(Plugin):
    name = "my-web-search"
    version = "1.0.0"
    
    # 声明插件元数据
    provides = ["web_search"]
    requires = []
    
    @hook("on_load")
    async def on_load(self, ctx, config: dict):
        # 初始化服务
        service = MyWebSearchService(
            api_key=config["api_key"],
            engine=config.get("engine", "brave")
        )
        
        # 注册服务(其他插件可以通过 ctx.get("web_search") 使用)
        ctx.register("web_search", service)
        
        # 注册可逆副作用:异步客户端需要在卸载时关闭
        ctx.register_reversible(
            action=lambda: None,  # action 是空操作,客户端已在 service.__init__ 创建
            reversal=lambda _: self._close_client(service),
            description="close_httpx_client"
        )
        
        # 注册事件处理器
        ctx.on("agent.before_tool_call", self._log_tool_call)
    
    @hook("on_unload")
    async def on_unload(self, ctx):
        # 注销事件处理器
        ctx.off("agent.before_tool_call", self._log_tool_call)
    
    async def _close_client(self, service: MyWebSearchService):
        await service.client.aclose()
    
    async def _log_tool_call(self, event):
        print(f"[MyTool] Agent calling tool: {event['tool_name']}")

五、与 LangChain/AutoGen 插件系统的本质区别

维度LangChainAutoGenCordis (Harness)
插件形态Python 函数(@tool 装饰器)ConversationGroup + Handler声明式插件包(Plugin 类)
状态管理无内置机制,靠外部有限的状态清理钩子可逆副作用 + 撤销栈
依赖声明requires/provides 声明
卸载安全性不可靠(有资源泄漏风险)部分可靠可靠(自动撤销栈执行)
子上下文不支持不支持支持(嵌套隔离)
事件系统有限(回调钩子)会话级别回调统一事件总线(ctx.on/off
插件隔离有(子上下文级别)
配置方式代码代码YAML 配置(声明式)

Cordis 的本质区别在于:它把"副作用管理"从插件的手动实现中抽离出来,变成了框架层的保证。在 LangChain 里,插件作者需要自己记得在 teardown 中清理资源;在 Cordis 里,插件作者在 on_load 中就声明了清理方式,框架保证执行。


六、生产环境部署实战

6.1 Docker Compose 部署 Harness

以下是生产级部署配置,包含持久化存储、监控、健康检查:

# docker-compose.yml
version: "3.9"

services:
  harness:
    image: deepseek/harness:latest
    container_name: dsh-agent
    ports:
      - "8080:8080"
      - "8081:8081"  # metrics 端口
    environment:
      - HARNESS_CONFIG=/etc/harness/config.yaml
      - DEEPSEEK_API_KEY=${DEEPSEEK_API_KEY}
      - LOG_LEVEL=info
    volumes:
      - ./config:/etc/harness:ro
      - hns_data:/var/lib/harness  # 持久化数据卷
    deploy:
      resources:
        limits:
          cpus: "4"
          memory: 8G
        reservations:
          cpus: "2"
          memory: 4G
    healthcheck:
      test: ["CMD", "curl", "-f", "http://localhost:8080/health"]
      interval: 30s
      timeout: 10s
      retries: 3
    restart: unless-stopped
    cap_add:
      - NET_ADMIN  # Firecracker 需要,用于网络配置
    devices:
      - /dev/kvm:/dev/kvm  # 硬件虚拟化支持

  # 可选:持久化向量存储插件
  qdrant:
    image: qdrant/qdrant:v1.7.0
    container_name: dsh-vector-store
    ports:
      - "6333:6333"
      - "6334:6334"
    volumes:
      - qdrant_storage:/qdrant/storage
    profiles:
      - with-vector-store

  # Prometheus 监控
  prometheus:
    image: prom/prometheus:latest
    container_name: dsh-prometheus
    ports:
      - "9090:9090"
    volumes:
      - ./prometheus.yml:/etc/prometheus/prometheus.yml:ro
      - prometheus_data:/prometheus
    command:
      - '--config.file=/etc/prometheus/prometheus.yml'
      - '--storage.tsdb.path=/prometheus'
    profiles:
      - with-monitoring

volumes:
  hns_data:
  qdrant_storage:
  prometheus_data:

6.2 Harness 配置文件

# config/harness.yaml
harness:
  name: production-agent
  log_level: info
  
plugins:
  - name: llm/deepseek
    package: cordis-llm-deepseek
    enabled: true
    config:
      api_key: ${DEEPSEEK_API_KEY}
      model: deepseek-chat
      temperature: 0.7
      max_tokens: 8192
      retry:
        max_attempts: 3
        backoff_ms: 1000
  
  - name: sandbox/firecracker
    package: cordis-sandbox-firecracker
    enabled: true
    config:
      snapshot: /opt/harness/snapshots/base-snapshot.bin
      max_instances: 4  # 最大并发沙箱数量
      memory_mb: 512
      vcpus: 2
      timeout_seconds: 60
  
  - name: storage/qdrant
    package: cordis-storage-qdrant
    enabled: true
    requires: [llm/deepseek]
    config:
      url: http://qdrant:6333
      collection: agent_memory
      vector_dim: 1536
  
  - name: loop/react
    package: cordis-loop-react
    enabled: true
    requires: [llm/deepseek, tools/*]
    config:
      max_iterations: 20
      timeout_seconds: 300
      reflection_enabled: true

tools:
  enabled:
    - web_search
    - code_execution
    - file_read
    - web_page_fetch
  
  web_search:
    engine: brave
    api_key: ${BRAVE_API_KEY}
    top_k: 5
  
  code_execution:
    sandbox: firecracker
    allowed_languages:
      - python
      - bash
      - javascript
    max_output_chars: 10000

monitoring:
  enabled: true
  port: 8081
  metrics:
    - agent_iterations
    - tool_call_count
    - llm_token_usage
    - sandbox_startup_time
    - plugin_load_time

6.3 性能基准测试

在生产环境中,Cordis 插件系统的开销实测数据(DeepSeek 官方 benchmark,2026-08-13):

操作平均耗时P99
插件加载(无依赖)45ms80ms
插件加载(含5个依赖)180ms320ms
插件卸载(含全部逆操作)25ms60ms
子上下文创建8ms15ms
子上下文销毁(触发全部撤销)120ms250ms
服务查询(ctx.get0.02ms0.05ms

关键观察:子上下文的撤销操作是最慢的环节,因为它需要按逆序执行所有注册的副作用。这个开销与注册的副作用数量成正比——如果你在一个子上下文中打开了100个文件,关闭这100个文件描述符就是撤销栈的执行时间。

优化建议:

  • 对长时间运行的任务,尽量把有副作用的操作提前注册,减少运行时的撤销栈深度
  • 对高频临时任务,考虑复用子上下文而不是每次新建(但要注意状态隔离)
  • 使用异步 I/O 包装文件和网络操作,让逆操作的执行更快

七、总结与展望

7.1 Cordis 的核心价值

Cordis 解决了一个非常具体但被长期忽视的问题:AI Agent 插件的生命周期管理。它的贡献不是发明了什么全新的概念,而是把"可逆副作用"这个函数式编程中的思想,成功地产品化、工程化,并应用到了 AI Agent 这个新兴领域。

三大核心价值:

  1. 可靠性:通过撤销栈和依赖图,保证插件卸载时不会留下资源泄漏
  2. 可组合性:声明式依赖 + 服务接口,让插件之间以最小耦合度协作
  3. 隔离性:子上下文机制,使得临时任务可以安全地运行在隔离环境中

7.2 局限性

Cordis 也不是银弹,以下场景它目前处理得不够好:

  • 跨进程副作用:如果插件 fork 了子进程,Cordis 的撤销栈无法追踪子进程的退出(需要手动处理 SIGCHLD
  • 分布式事务:当插件通过网络调用触发了远程状态变更,Cordis 的撤销是本地的,无法回滚远程状态
  • 插件图循环依赖:虽然 Cordis 在加载时会检测循环依赖,但某些合法的循环依赖场景目前会直接拒绝加载
  • 动态副作用:运行时动态创建的资源(比如根据请求动态创建文件),需要在运行时不断注册撤销记录,增加了开发负担

7.3 未来方向

根据 DeepSeek 官方路线图,Cordis 的未来发展方向包括:

  • Rust 重写核心:当前 Cordis SDK 有 Python 和 TypeScript 两个版本,性能关键路径(撤销栈执行引擎)将迁移到 Rust,以支持更低延迟的插件切换
  • WASM 插件支持:允许用 WASM 编译的插件作为隔离单元运行,进一步提升安全性和性能
  • 分布式 Cordis:支持跨多台机器的插件协调,通过 Raft 共识保证分布式撤销的一致性
  • 可视化调试工具:展示插件依赖图、撤销栈状态,帮助开发者理解复杂插件系统的运行机制

Cordis 是一个值得关注的技术方向。无论你最终是否使用 DeepSeek Harness,理解它背后的可逆副作用 + 依赖注入设计哲学,对构建任何需要精细生命周期管理的系统,都会有启发。


Tags: Cordis | DeepSeek Harness | AI Agent | 插件架构 | 可逆副作用 | 依赖注入 | Python | Firecracker | 沙箱隔离 | 生命周期管理

字数:约 9600 字

推荐文章

MCP 测试文章 18055
2026-08-13 06:22:01 +0800 CST
如何配置获取微信支付参数
2024-11-19 08:10:41 +0800 CST
php获取当前域名
2024-11-18 00:12:48 +0800 CST
程序员茄子在线接单