8. LLM、上下文与压缩
这一章覆盖模型调用、流式协议、系统提示词、上下文压缩、Web 访问、技能、类型图(Typert)。
LLM 能力 seam(packages/llm)
dsh-llm 独占 Service Definition + Consumer 角色:只定义词汇,不实现 provider。核心是 LlmRuntime(ctx.llm)。
注册面
registerAdapter(providers, adapter):全有或全无(冲突抛LlmError('DUPLICATE_ADAPTER')),返回AdapterRegistrationHandle(带replace()原子换路由)。registerConfigurableProviders():声明可配置 provider 目录。registerModelDiscovery(ns, discover):端点探测。listProviders()/listModels()/resolveModelInfo()/resolveCallConfig()/prepareCall():元数据与一次性调用绑定。- 拓扑变更后发
llm/adapters-updated(emit)。
调用面
stream(options): AsyncIterable<StreamChunk>是唯一流式入口。llm/stream是 waterfall 事件,可拦截/包装(缓存、日志、路由),监听者必须next()。
消息词汇
Message:不可变值(MessageId品牌 + role + 内容块 + 类型化source),构造器createMessage/createUserMessage/createAssistantMessage/createToolResultMessage/freezeMessage。ContentBlockMap(merge-extensible):text/reasoning/image/tool-call/tool-result。MessageSourceMap:user/plugin/model/tool;ContextForm有instructions/catalog/snapshot/notice/relay/recall。
流式 chunk 协议
StreamChunk 联合:block-start / text-delta / reasoning-delta / tool-call-delta / block-end / usage / finish。
finish是唯一终态;FinishReasonMap为stop/tool-calls/max-tokens/aborted/error。TokenUsage的 input/cacheRead/cacheWrite 计数互斥。BlockAssembler是唯一 chunk→block 组装器,产出带ModelMessageSource的冻结 assistant 消息。
适配器接口与错误
LlmAdapter抽象基类只需实现stream(),可覆写providerRetryPolicy()/providerInfo()/listModels()/resolveModel()。- 错误体系
HarnessError→LlmError(稳定code+ 可序列化failure),常量CONTEXT_WINDOW_EXCEEDED_CODE/QUOTA_EXCEEDED_CODE/EMPTY_RESPONSE_CODE/INVALID_CREDENTIAL_CODE。
两个内置适配器
- llm-deepseek:注册唯一路由
deepseek-official,直连 fetch +eventsource-parserSSE;reasoning_content→reasoning-delta、tool_calls→tool-call-delta(参数保持原始 JSON 串);resolveAdapterOptions()每次调用经 thunk 重读(settings/credentials 动态生效);错误码AUTH/QUOTA/RATE_LIMIT/CONTEXT_WINDOW_EXCEEDED/TRANSPORT/ABORTED/STREAM_CLOSED/MALFORMED_RESPONSE/EMPTY_RESPONSE;请求带 attribution header 与x-deepseek-harness-compact。 - llm-pi-ai:Pi AI 适配器(不同 API 格式)。
系统提示词(core/system-prompt)
基于 ScopedLayers(global + per-scope 链,同名就近遮蔽),已在「核心包拆解」介绍。renderContextSnapshot() 生成 "Current runtime context. This snapshot supersedes earlier runtime-context snapshots." 快照。
上下文压缩(compaction)
抽象层(dsh-compaction)
CompactionEngine(ctx.compaction):compactIfNeeded(agent, trigger: 'pressure'|'context-overflow', signal)、compactNow、compactRegion(start,end)。CompactionResult:compactionId/shadowedRange/shadowedSeqs/shadowedTokenCount。toolPairingBalancedBefore/After():保证切口不跨未闭合的 tool-call/result 对。- 会话事件(log-only、无 surfaceOp):
compaction/start(持锁)、compaction/summary、compaction/end(放锁)、compaction/prune。 - surface 上唯一变更是一条带
surfaceOp:{op:'replace',start,end}的user/message;deriveMessages()把摘要渲染为用户角色消息。
基本实现(dsh-compaction-basic)
- 压力策略:
agent/pre-step监听做 token 压力检查(ctx.tokenMeter计价),agent/request-error监听做 context-overflow 恢复。 thresholdRatio0.8、保留尾部retainRatio0.16。summarize()是唯一子类钩子:一次直达ctx.llm.stream()(purpose:'compaction'),逐字重放系统提示 + 工具 + 被遮蔽消息以复用 KV cache,只取文本块,输出包<compacted-summary>标签。- 可选
ctx.toolResultPruner无模型预剪枝;command-compact暴露/compact人类命令。
Token 计量(token-meter)
ctx.tokenMeter 拥有按会话隔离的回放折叠区,压力消费方共享不可变且带修订版本的测量结果。
Web 能力(packages/web)
WebRuntime(ctx.web)是 search + fetch 双操作单 seam:
registerSearchProvider/registerFetchProvider(重复 id 抛WebError('WEB_DUPLICATE_PROVIDER'))。search(request, signal)/fetch(request, signal)执行期选择 provider(显式 id 或唯一可用者自动)。- 词汇:
WebSearchRequest{query,maxResults}→WebSearchResult{content,sources[],truncated}、WebFetchRequest{url}→WebFetchResult{url,statusCode,body,truncated}。 - Provider:exa/perplexity/deepseek 搜索 +
web-fetch-http。 - tool-web 是唯一模型消费方:注册
web_search/web_fetch(snake_case 参数、并发安全),同时ctx.systemPrompt.section({name:'tool:web_search', order:110})注入指引;从不 import 具体 provider。
Skill 能力(packages/skill)
SkillRegistry(ctx.skills):registerProvider(create)(同步工厂)、snapshot({cwd,signal,scope})→{skills, complete}、list()/get(name)、register()(运行时内嵌技能,rank 250)。- 调用策略
invocation:{modelInvocable, userInvocable}双轴独立。 renderSkillContent()是<skill_content>渲染的唯一真源。- skill-filesystem:按 rank 扫描项目/自定义/用户根(
.dsh/skills、.agents/skills、$DSH_HOME/skills等),解析SKILL.mdfrontmatter,Chokidar watch +fs/observed快速失效。 - tool-skill:
agent/pre-step渲染 durable<system-reminder>技能目录,注册skill工具,支持用户/name手势注入skill_content。
Typert(packages/typert)
四件套分离「源码分析 / 运行时 / 发现 / 协议」:
- generator(构建期):
WorkspaceAnalyzer从 tsconfig 建ts.Program,产出FaceModel/TypeGraph,FaceModelEmitter生成含 Zod schema 的TYPERT清单(lib/typert.host.{js,d.ts})。 - registry(
ctx.typert):TypertRegistry.register(contribution)原子登记<package>#<face>反射与<package>#<name>活 schema。 - loader:消费
ctx.loader+ctx.typert,扫描 Loader 条目、import./typert导出并校验清单。 - protocol:
@Remote/@RemoteScope装饰器、TypertRemoteService、InvocationDescriptor,供 api/gateway 的 Remote RPC 网关使用。
与 core 的对接
ctx.llm:agent-loop 每步先systemPrompt.assemble(),经agent/requestwaterfall 定 provider/model,再prepareCall()→llm.stream();request/header会话事件记录有效配置。ctx.tools:tool-web/tool-skill 等 Consumer 经ToolRuntime.register注册模型工具。ctx.systemPrompt:指引 section 与tools()汇入GenerateOptions.system/tools。Message词汇同时被 dsh-session 持久化日志与 dsh-llm 请求共用,保证「模型可见 ⟺ 可重建」。