首页 > 教程 > DeepSeek Harness 教程 > DeepSeek Harness LLM 适配器
DeepSeek Harness 教程

DeepSeek Harness LLM 适配器

第 25 / 35 节 2026-11-07

LLM 适配器是什么

想把 Harness 接到自己的模型端点,就要写一个 LLM 适配器:继承 LlmAdapter 并实现 stream() 方法的类。它把 Harness 的提供方无关请求转换成具体提供方的 API 调用,再把响应转换回 Harness 的分片 StreamChunk。整体三层:顶层 agent-loop 消费统一的流式生成服务;中间 ctx.llm 注册表维护抽象契约;底层各适配器对接不同 API 格式,用 ctx.llm.registerAdapter(['my-provider'], adapter) 绑定路由。

最小实现

stream() 是核心,返回异步生成器,标准流程三步:转换消息格式、调用流式 API、把响应转成 StreamChunk:

import type { Context } from '@deepseek-ai/cordis'
import Schema from '@deepseek-ai/schemastery'
import { LlmAdapter, type GenerateOptions, type StreamChunk } from '@deepseek-ai/dsh-llm'

class MyAdapter extends LlmAdapter {
  private apiKey: string

  constructor(apiKey: string) {
    super()
    this.apiKey = apiKey
  }

  async *stream(options: GenerateOptions): AsyncIterable<StreamChunk> {
    // 1. Convert options.messages to the provider format.
    // 2. Call the streaming API.
    // 3. Convert the response into StreamChunk values.
  }
}

export interface Config {
  apiKey: string
  providers: string[]
}

export const Config: Schema<Config> = Schema.object({
  apiKey: Schema.string().required(),
  providers: Schema.array(Schema.string()).required(),
})

export const name = 'my-llm-adapter'
export const inject = ['llm'] // 保证 ctx.llm 已就绪

export function apply(ctx: Context, config: Config) {
  const adapter = new MyAdapter(config.apiKey)
  ctx.llm.registerAdapter(config.providers, adapter)
}

apiKey 来自插件配置而非硬编码;providers 数组声明适配器负责哪些提供方路由。

GenerateOptions 与注册

stream() 接收的 GenerateOptions 以 @deepseek-ai/dsh-llm 导出的类型为准,关键字段包括:provider(选择已注册的适配器)、model(适配器拥有的模型 id,无需启动时注册)、messages、系统提示词、tools、可选的 reasoning 推理强度 ID,以及 signal 中止信号。适配器必须把支持的字段映射到具体 API;无法支持的字段应抛出带稳定 code 的 LlmError,不得静默丢弃。

需要向选择器公布模型选项时可覆写 listModels();需要返回确切身份时覆写 resolveModel(provider, model, signal?),一次返回提供方、模型身份及可选的 context、reasoning 元数据。reasoning 元数据包含有序的不透明 ID、展示名称与可选默认值——保留适配器给出的权威可选列表(包括上游返回的 off),不要提升为核心枚举;异步查询必须响应 signal;显式指定但不支持的推理强度会在 stream() 调用前被拒绝;省略 reasoning 表示该模型没有可选推理能力。

在 cordis.yml 中使用

# 文件:cordis.yml
- id: my-llm
  name: './src/my-llm-adapter.ts'
  config:
    apiKey: !!js process.env.MY_API_KEY
    providers:
      - my-provider

- id: agent-loop
  name: '@deepseek-ai/dsh-agent-loop'
  config:
    agents:
      - id: main
        provider: my-provider
        model: my-model-v1

密钥经环境变量读取不落盘;agent-loop 的 agents.main 配置 provider 与 model,生成请求时即命中新适配器。仓库里的 llm-deepseek(OpenAI 兼容格式)与 llm-pi-ai(不同 API 格式)是两个现成实现,对照阅读最能体会「契约不变、实现各异」的 seam 思想。

小结自测

LLM 适配器 = 继承 LlmAdapter + 实现 stream() + registerAdapter 路由注册 + cordis.yml 配置。自测:stream() 的返回类型是什么?registerAdapter 第一个参数代表什么?agent-loop 通过哪些配置项选择新适配器?

 

©️版权声明:
本网站(https://aigc.izzi.cn)刊载的所有内容,包括文字、图片、音频、视频等均在网上搜集。
访问者可将本网站提供的内容或服务用于个人学习、研究或欣赏,以及其他非商业性或非盈利性用途,但同时应遵守著作权法及其他相关法律的规定,不得侵犯本网站及相关权利人的合法权利。除此以外,将本网站任何内容或服务用于其他用途时,须征得本网站及相关权利人的书面许可,并支付报酬。
本网站内容原作者如不愿意在本网站刊登内容,请及时通知本站,予以删除。

继续学习其他教程