自学教程

DeepSeek Harness 实战

DeepSeek Harness 实战:从零实现一套可替换能力(Definition/Provider/Consumer 完整落地)

前置必读:《DeepSeek Harness 能力三角色:Definition / Provider / Consumer》

前面我们掌握了 Harness 最核心的架构理论:能力接缝(Capability Seam)三段式架构。

理论总结一句话:Definition 定契约、Provider 做实现、Consumer 接模型。三者解耦,实现底层随意替换,上层零变更。

本文我们从零手写一套完整可替换能力,带你彻底吃透 Harness 可插拔架构的落地方式。

本次实战目标:实现一个 文本摘要能力

  • 两套底层实现:本地极简摘要 / AI 智能摘要
  • 切换底层 Provider,模型工具、业务代码完全不用改
  • 完全遵循官方 Seam 规范,可直接用于生产插件开发

一、实战架构总览

我们将完整实现一套标准 Capability Seam,包含三个角色:

  1. Definition(服务契约):定义摘要接口、入参、出参、抽象服务,无任何业务逻辑
  2. Provider(底层实现)
    • 本地 Provider:纯前端截断、关键词提取(无需 LLM)
    • AI Provider:调用 LLM 实现智能润色摘要(依赖模型服务)
  3. Consumer(模型工具):封装为模型可调用工具,对外暴露统一能力

核心效果:切换「本地摘要」和「AI 摘要」仅需改一行配置,模型调用、工具描述、参数结构完全不变。


二、第一步:编写 Service Definition(契约层)

Definition 是整个能力的唯一稳定标准。只定义结构、不写逻辑、不依赖重型库。

新建模块 dsh-summary-definition

import type { Context } from '@deepseek-ai/cordis';
import { Service } from '@deepseek-ai/cordis';// 统一入参结构
export interface SummaryInput {
content: string;
maxLength?: number;
} // 统一出参结构
export interface SummaryOutput {
summary: string;
sourceLen: number;
shortenRate: string;
} // 扩展全局上下文类型,让 ctx.summary 拥有类型提示
declare module '@deepseek-ai/cordis' {
interface Context {
summary: SummaryService;
}
} // 抽象服务基类:只定义方法,不实现
export abstract class SummaryService extends Service {
constructor(ctx: Context) {
super(ctx, 'summary');
} abstract generate(input: SummaryInput): Promise<SummaryOutput>;
}

Definition 开发规范(官方强制)

  • 只做类型定义、抽象方法、上下文扩展
  • 不引入业务逻辑、不引入第三方重型依赖
  • 一旦稳定,尽量不做破坏性变更

三、第二步:编写双版本 Provider(可替换实现层)

Provider 依赖 Definition、实现抽象方法、注册服务到上下文。

我们实现两套可无缝替换的底层。

1. 本地极简 Provider(dsh-summary-local)

无模型依赖、纯本地处理,适合轻量快速场景。

import type { Context } from '@deepseek-ai/cordis';
import { SummaryService, SummaryInput, SummaryOutput } from 'dsh-summary-definition';

export class LocalSummaryProvider extends SummaryService {
async generate(input: SummaryInput): Promise<SummaryOutput> {
const { content, maxLength = 100 } = input;
const summary = content.length <= maxLength
? content
: content.slice(0, maxLength) + '...';
return {
summary,
sourceLen: content.length,
shortenRate: ((summary.length / content.length) * 100).toFixed(1) + '%'
};
}
}
export const name = 'dsh-summary-local';
export function apply(ctx: Context) {
// 向全局注册 summary 服务
ctx.plugin(LocalSummaryProvider);
}

2. AI 智能 Provider(dsh-summary-ai)

依赖 LLM 服务,生成高质量摘要,完全复用同一套契约。

import type { Context } from '@deepseek-ai/cordis';
import { SummaryService, SummaryInput, SummaryOutput } from 'dsh-summary-definition';// 声明依赖 llm 服务
export const inject = ['llm']; export class AiSummaryProvider extends SummaryService {
async generate(input: SummaryInput): Promise<SummaryOutput> {
const { content, maxLength = 100 } = input; // 调用全局 LLM 服务生成智能摘要 const res = await this.ctx.llm.complete({ prompt: `请将以下文本精简为${maxLength}字以内摘要:\n${content}` }); return { summary: res.text, sourceLen: content.length, shortenRate: ((res.text.length / content.length) * 100).toFixed(1) + '%' }; }
} export const name = 'dsh-summary-ai';
export function apply(ctx: Context) {
ctx.plugin(AiSummaryProvider);
}

Provider 核心特性(官方机制)

  • 同一个 Definition 同时只能激活一个 Provider(内核互斥)
  • 多 Provider 加载冲突时,后加载覆盖先加载
  • 所有底层差异收敛在 Provider 层,上层完全无感

四、第三步:编写 Consumer(模型调用层)

Consumer 唯一职责:将标准化服务包装成模型可调用工具。

Consumer 不感知任何底层实现,只依赖 Definition 契约。

新建 dsh-tool-summary

import type { Context } from '@deepseek-ai/cordis';
import { defineTool } from '@deepseek-ai/dsh-tools';// 只依赖标准化 summary 服务
export const name = 'dsh-tool-summary';
export const inject = ['tools', 'summary']; export function apply(ctx: Context) {
// 注册为模型工具
ctx.tools.register(defineTool({
name: 'generate_text_summary',
description: '对长文本进行智能摘要,精简内容、保留核心信息',
parameters: {
content: {
type: 'string',
required: true,
description: '需要摘要的原始文本'
},
maxLength: {
type: 'number',
required: false,
description: '最大摘要长度,默认100字'
}
},
async execute(args) {
// 完全通过抽象服务调用,不感知本地/AI实现
return await ctx.summary.generate({
content: args.content,
maxLength: args.maxLength
});
}
}));
}

五、最终能力切换:一行配置完成热替换

整套 Seam 搭建完成,现在演示 Harness 可替换能力的真正威力。

方案1:使用本地极简摘要

plugins:
  - name: dsh-summary-local
  - name: dsh-tool-summary

方案2:切换为 AI 智能摘要

plugins:
  - name: dsh-summary-ai
  - name: dsh-tool-summary

你会发现:

  • Consumer 工具代码零修改
  • 模型看到的工具名称、参数、描述零变化
  • Agent 调用逻辑、Prompt 适配零变更

真正实现:底层能力热插拔,上层业务完全无感。


六、深度复盘:三角色职责边界

结合本次实战,彻底固化架构认知:

1. Definition(稳定层)

定义「能力长什么样」,是上下游协作的协议。绝对不写业务逻辑,保证长期稳定。

2. Provider(可变层)

定义「能力怎么实现」,是唯一允许多样化、差异化的层级。本地、云端、沙箱、私有化全部在这里切换。

3. Consumer(接入层)

定义「模型怎么用能力」,负责 AI 交互适配,永远不触碰底层实现细节。


七、官方开发铁律(避坑必看)

  1. 禁止 Consumer 直接依赖 Provider:一旦硬编码导入,彻底丧失可替换能力
  2. 禁止 Definition 写业务逻辑:契约必须极简稳定
  3. 同一服务同时只能一个 Provider:内核单例互斥,避免能力冲突
  4. 能力扩展只新增 Provider,不修改上层 Consumer
  5. 轻量工具无需拆包:官方不推荐过度设计,简单能力可单包内实现三角色

八、本篇总结

通过本次实战,你完成了 Harness 架构的从理论到落地:

你不再只是看懂「三角色架构」,而是亲手实现了一套标准可插拔能力接缝。

所有 Harness 官方核心能力(Shell、文件、代码运行、LLM 推理),全部遵循本文同一套开发范式。

掌握这套写法,你就具备了开发企业级可替换插件、定制私有运行时、改造底层沙箱能力的完整能力。

标签:

0 条笔记