Skip to content

plugin-llm-deepseek — DeepSeek LLM 服务 ​

包名: @aalis/plugin-llm-deepseek
源码: packages/plugin-llm-deepseek/src/index.ts

概述 ​

DeepSeek API 的 LLM 提供者:为每个可用模型实现一个 LLMModel(@aalis/api-llm)并注册为 llm 服务条目,支持流式输出、工具调用和思考模式。

插件声明 ​

ts
definePlugin({
  name: '@aalis/plugin-llm-deepseek',
  displayName: 'DeepSeek',
  subsystem: 'llm',
  reusable: true,
  provides: [llm],
  uses: { config, logger, lifecycle, provide, events },
  apply: registerModels,
})

无其它服务依赖。每个模型 provide.use(llm, metered(handle, events.use), { entryId: \${lifecycle.use.id}/${modelId}`, label }):拿到用量的调用发 llm:usage`(见 api-llm 的记账)。

配置 ​

字段类型默认值说明
apiKeystring必填API Key:DeepSeek API 密钥(secret)。缺失时 apply 直接抛错,插件转 error 态——启动不中断,但本插件不提供任何模型
baseUrlstring'https://api.deepseek.com'API 地址:API 端点完整前缀(官方无版本段);插件只在其后拼 /chat/completions 与 /models
customModelstextarea''自定义模型:手动添加的模型名称(每行一个或逗号分隔)。用于补充自动发现列表中未出现的模型。与自动发现重复时会提示去重。
discoverModelsbooleantrue自动发现模型:启动时请求 /models 发现可用模型。网关不提供 /models 时关闭:不发发现请求,只注册 customModels(此时必填)。
modelCapabilitiestextarea''单模型能力覆盖:按行指定某个模型的能力集。有该模型的表项时覆盖插件启发式推断,与 adapter 默认能力仍取并集。 格式:<modelId>: <cap1>,<cap2>,...,每行一条。如:deepseek-chat: chat,tool_calling,streaming
providerCapabilitiesstring''适配器默认能力(逗号分隔):为本适配器下所有模型额外补充的能力。最终某模型的能力 = 此处能力 ∪ 模型级别能力。例:chat,tool_calling,streaming
timeoutnumber120停顿超时(秒):多久收不到新的生成内容算超时(秒)。一直在输出(含思考内容)不算超时;不流式的请求要在这段时间内收到整份回复。0 = 不限制。
temperaturenumber0.7温度:0-2,越高越随机
maxTokensnumber8192最大 Token:单次回复最大生成 token 数,须为正整数,否则实例转为出错
contextLengthnumber131072上下文长度:模型上下文窗口大小
strictToolCallsbooleanfalseStrict 工具调用:启用后所有工具调用将使用 strict 模式,模型输出严格遵循 JSON Schema(参考 api-docs.deepseek.com)
forceJsonOutputbooleanfalse强制 JSON 输出:启用后所有最终回复请求将携带 response_format: {type:"json_object"},配合角色卡 outputFormat 使用可提升格式遵循率。工具调用阶段不受影响(工具响应走 tool_calls 字段)。需确保 system prompt 中含有 json 字样(启用 outputFormat 的角色卡会自动满足此条件)。
thinkingselect'auto'默认思考档位:能思考的模型(v4、reasoner 等,或单模型能力覆盖里写了 thinking 的)在请求没指定档位时用这一档,会话设置的「深度思考」压过它。可选 off(关)、high(高)、auto(自动:开启思考,强度由 DeepSeek 按场景在高与最高之间选)、max(最高)。不能思考的模型一律按关发。

特性 ​

  • 思考档位: 能力里有 thinking 的模型声明关、高、自动、最高四档(off、high、auto、max),默认档取实例配置 thinking;请求带了档位按请求,没带按默认档,带了别的档位拒绝。档位翻成请求体字段:

    档位thinking.typereasoning_efforttemperature
    offdisabled不发发
    highenabledhigh不发
    autoenabled不发不发
    maxenabledmax不发

    不能思考的模型不声明档位,一律按 off 发(v4 系列不发 thinking 会保持开启)。思考内容在非流式响应中通过 reasoningContent 返回,在流式响应中通过 reasoningDelta 逐段返回

  • Strict 工具调用: 启用 strictToolCalls 后,每个工具定义的 function 字段带上 strict: true;关闭时沿用各工具自身声明的 strict

  • SSE 流式解析: chatStream() 解析 SSE 事件流,累积 tool_calls delta

  • 漏进正文的工具调用标记: 服务端没解析出工具调用时,模型的工具调用标记(DSML)会漏进 content。插件只剥离、不当调用执行,工具调用只取服务端给的,并记一条 warn:流式在检测到标记起始后不再交出之后的正文,只剩标记之前的文字(可能为空);非流式去掉标记块,其余正文照留

  • 模型发现: 启动时 fetchRemoteModelIds() 请求 /models 获取远端模型列表(停用或停机时中止),与 customModels 合并后为每个模型注册一个独立的 llm 服务条目。发现失败(不可达、超时、非 2xx、响应不是 JSON 或不是模型列表)时记一条 warn(带 URL 与原因),只注册 customModels;一个模型都没有(发现失败且未配置 customModels,或已连接但列表为空)时实例转为出错,错误信息先写怎么修(检查 apiKey、baseUrl 与网络,或在 customModels 里写明要用的模型),再写原因。网关不提供 /models 时关闭 discoverModels:不发发现请求、不记 warn,只注册 customModels(此时必填,留空时实例转为出错并点名该字段)

  • 超时: timeout 按停顿计,规则见 api-llm 的生成请求的超时。算作新内容的是 content(含为防 DSML 泄漏暂不交出的)、reasoning_content 与工具调用的名字和参数;超时报「DeepSeek 请求超时:<timeout> 秒内没有收到新的生成内容,可在配置里调大 timeout」。对话请求经插件自己的连接池发出:没有 Node 自带 fetch 等响应头与读响应体各 300 秒的默认时限,也不走全局 dispatcher,经 NODE_USE_ENV_PROXY 或 setGlobalDispatcher 配的代理对它不起作用

  • 错误信息: 对话请求失败时的错误信息会经 agent 发回会话,只写状态码与原因:非 2xx 时写状态码,401/403、402、404、429、5xx 各加一句提示(密钥无效或没有权限、余额不足或需要付费、模型或地址不对、请求过多或额度不足、上游服务故障),并附上游 JSON 里的说明(error.message、error 字符串或顶层 message,折成一行后截断);取不到说明(如 HTML 错误页)时写「详情见日志」。超时、连不上、插件已停用或重载(停用或重载之后还拿着旧句柄发的请求)各一句;非流式请求的应答是 200 但不是 JSON 时写明。响应体与底层原因(如 connect ECONNREFUSED <地址>)只记 warn 日志,响应体先把换行与连续空白折叠成一个空格,再截断到 500 个字符(按代理对安全截断)。模型发现失败的原因带响应体摘录(同样折叠与截断)

  • baseUrl 校验: 带用户名或密码(user:pass@)、带查询串或片段(? 或 # 之后的部分)或解析不了的 baseUrl 在读配置时报配置错误,实例转为出错、不发请求,错误信息不带 URL;密钥填在 apiKey。带凭据的 URL 本就发不出请求(fetch 拒绝),凭据还会出现在报错与 WebUI 的模型下拉里;插件在 baseUrl 后面拼路径,带查询串或片段时拼出来的地址是坏的

  • 能力覆盖: modelCapabilities 每行按最后一个冒号切分模型 id 与能力段,baseUrl 指向兼容网关时带冒号的模型 id(如 qwen3:8b)照原样写即可

  • system 位置归一化: DeepSeek 把请求里所有 system 消息提升到上下文最前部,排在历史之后的每轮材料会让历史的前缀缓存失效。出口因此把首个非 system 消息之后的 system 消息改为 user,一律补 [系统提示] 标记(自带 [系统通知] 这类标记的也补),空内容保持原样。本轮指令块豁免:metadata.injector 属于 DIRECTIVE_KINDS(workflow 代发的任务、宿主通知、空闲开话题的提示)的消息保持 system,改成 user 会被模型当成真实用户在指挥。代价是它们渲染时被提到上下文最前部、离决策点远;这类回合低频,牺牲该轮缓存(见消息到 LLM 的处理流水线 §9)

配置校验 ​

baseUrl 和 apiKey 的显式无效值会使实例进入错误态;地址格式、查询串与片段及 URL 内的用户名、密码在模型发现前校验。缺省地址仍用官方端点。其余数字、布尔字段按 schema 解析,错误类型回落默认值并告警。

文档对应 dev@c4e046e41,core 0.21.0,构建于 2026-11-02
基于 MIT 许可发布