Compendium.Adapters.DeepSeek
1.0.0-preview.0
dotnet add package Compendium.Adapters.DeepSeek --version 1.0.0-preview.0
NuGet\Install-Package Compendium.Adapters.DeepSeek -Version 1.0.0-preview.0
<PackageReference Include="Compendium.Adapters.DeepSeek" Version="1.0.0-preview.0" />
<PackageVersion Include="Compendium.Adapters.DeepSeek" Version="1.0.0-preview.0" />
<PackageReference Include="Compendium.Adapters.DeepSeek" />
paket add Compendium.Adapters.DeepSeek --version 1.0.0-preview.0
#r "nuget: Compendium.Adapters.DeepSeek, 1.0.0-preview.0"
#:package Compendium.Adapters.DeepSeek@1.0.0-preview.0
#addin nuget:?package=Compendium.Adapters.DeepSeek&version=1.0.0-preview.0&prerelease
#tool nuget:?package=Compendium.Adapters.DeepSeek&version=1.0.0-preview.0&prerelease
Compendium.Adapters.DeepSeek
Direct API adapter that wires DeepSeek's chat and reasoning
models into the Compendium IAIProvider
abstraction. DeepSeek's wire surface is OpenAI-compatible — this adapter implements the same
contract as compendium-adapter-openai so swapping providers is a one-line change.
services.AddCompendiumDeepSeek(opt =>
{
opt.ApiKey = Environment.GetEnvironmentVariable("DEEPSEEK_API_KEY")!;
opt.DefaultModel = DeepSeekOptions.DefaultChatModel; // "deepseek-chat"
});
What's supported
| Surface | Status | Notes |
|---|---|---|
Chat completions (/chat/completions) |
yes | Default model deepseek-chat. |
| Streaming SSE | yes | StreamCompleteAsync. usage arrives on the final chunk. |
| Tool / function calling | yes | OpenAI-compatible. deepseek-chat only — see notes below. |
Reasoning model (deepseek-reasoner) |
yes | reasoning_content exposed via GetReasoningContent(). |
| List models / health check | yes | /models. |
| Embeddings | no | DeepSeek does not expose a hosted embeddings endpoint. |
| Vision | no | Not a DeepSeek capability today. |
EmbedAsync returns Result.Failure(Error.Unavailable("AI.Unsupported", …)) instead of throwing —
plug compendium-adapter-openai or compendium-adapter-mistral for embeddings.
Quick start
dotnet add package Compendium.Adapters.DeepSeek
using Compendium.Abstractions.AI;
using Compendium.Abstractions.AI.Models;
using Compendium.Adapters.DeepSeek.Configuration;
using Compendium.Adapters.DeepSeek.DependencyInjection;
using Compendium.Adapters.DeepSeek.Reasoning;
var services = new ServiceCollection();
services.AddLogging();
services.AddCompendiumDeepSeek(opt =>
{
opt.ApiKey = Environment.GetEnvironmentVariable("DEEPSEEK_API_KEY")!;
});
await using var sp = services.BuildServiceProvider();
var provider = sp.GetRequiredService<IAIProvider>();
var result = await provider.CompleteAsync(new CompletionRequest
{
Model = DeepSeekOptions.DefaultChatModel,
Messages = [ Message.User("Explain hexagonal architecture in one paragraph.") ]
});
Console.WriteLine(result.IsSuccess ? result.Value.Content : result.Error.Message);
For a reasoning-model walkthrough see samples/01-reasoning-loop.
Options
Configure via IConfiguration (binds the DeepSeek section) or an Action<DeepSeekOptions>:
| Option | Default | Notes |
|---|---|---|
ApiKey |
required | Personal API key from https://platform.deepseek.com. |
BaseUrl |
https://api.deepseek.com |
DeepSeek-hosted endpoint. China-hosted — see EU caveats below. |
DefaultModel |
deepseek-chat |
deepseek-chat (V3, general-purpose) or deepseek-reasoner (R1, exposes reasoning trace). |
DefaultTemperature |
0.7 |
Default sampling temperature. |
DefaultMaxTokens |
4096 |
Applied when the request omits MaxTokens. |
TimeoutSeconds |
180 |
DeepSeek reasoner traces can run for minutes — keep generous. |
RetryAttempts |
3 |
Forwarded into the standard Microsoft.Extensions.Http.Resilience pipeline. |
InlineReasoningInContent |
false |
When true, prepend <think>…</think> to Content for reasoner responses. |
EnableLogging |
false |
Verbose request/response logging at Debug level. Off by default — request bodies can carry secrets. |
The Microsoft.Extensions.Http.Resilience standard pipeline is wired with relaxed timeouts
(attempt: 180 s, total: 600 s) so reasoner traces aren't cut off mid-thought.
Model selection — deepseek-chat vs deepseek-reasoner
| Model | Class | Strengths | Tool calling | Reasoning trace |
|---|---|---|---|---|
deepseek-chat |
DeepSeek-V3 | Fast, cheap, broad knowledge. Default. | yes | no |
deepseek-reasoner |
DeepSeek-R1 | Multi-step reasoning, math, code, logic puzzles. | no (today) | yes |
Pick deepseek-chat for chat assistants, summarisation, drafting, content classification.
Pick deepseek-reasoner when the question benefits from a visible chain-of-thought — debugging,
proof-style answers, code review.
Reasoning-content handling
deepseek-reasoner returns two assistant fields: content (the final answer) and
reasoning_content (the chain-of-thought trace). The Compendium AI abstractions (1.0.1) do not
have a first-class reasoning channel, so this adapter surfaces it as follows:
Non-streaming (CompleteAsync)
The full reasoning trace lands in CompletionResponse.Metadata under the well-known key
deepseek.reasoning_content. Read it via the helper:
using Compendium.Adapters.DeepSeek.Reasoning;
var result = await provider.CompleteAsync(request);
var reasoning = result.Value.GetReasoningContent(); // null when the model is deepseek-chat
var answer = result.Value.Content;
Set DeepSeekOptions.InlineReasoningInContent = true to additionally prepend the trace into
Content wrapped in <think>…</think> tags. Useful when piping through code that only inspects
Content (logging sinks, audit trails).
Streaming (StreamCompleteAsync)
CompletionChunk in the 1.0.1 abstractions has no side-channel Metadata dictionary. To stay
within the contract the adapter defaults to dropping pure-reasoning chunks from the stream so
ContentDelta carries only the visible answer. The final aggregated trace is not available
mid-stream in default mode — use CompleteAsync for full visibility.
When InlineReasoningInContent = true, reasoning deltas are streamed as <think>token</think>
fragments in ContentDelta so a downstream parser can still partition the stream.
Future work: when Compendium 1.1 ships
CompletionChunk.Metadata, we'll surface deltas viachunk.GetReasoningContentDelta()so consumers can multiplex the two streams cleanly.
Cost at a glance
DeepSeek's hosted pricing is dramatically lower than the western incumbents:
| Provider / model | Input $/M tokens | Output $/M tokens | Cached input $/M |
|---|---|---|---|
deepseek-chat (V3) |
$0.27 | $1.10 | $0.07 |
deepseek-reasoner (R1) |
$0.55 | $2.19 | $0.14 |
OpenAI gpt-4o |
$2.50 | $10.00 | $1.25 |
OpenAI gpt-4o-mini |
$0.15 | $0.60 | $0.075 |
OpenAI o1 |
$15.00 | $60.00 | $7.50 |
Anthropic claude-4.5-sonnet |
$3.00 | $15.00 | $0.30 |
Numbers from the providers' public pricing pages at the time of release; they can change without notice. Use the DeepSeek pricing page for the authoritative current figures.
The implication: deepseek-reasoner is roughly 25–30× cheaper than o1 for comparable
reasoning depth. That changes the unit economics of agent loops that fire many reasoning calls
per task.
EU / data-residency caveats
The hosted DeepSeek endpoint at api.deepseek.com is operated from China. Before adopting it for
production:
- GDPR: a transfer of EU personal data to DeepSeek constitutes an international transfer to a country without an EU adequacy decision. You need standard contractual clauses + a TIA, and you should be prepared to lose the ability to use the service if a regulator objects.
- Sensitive content: do not send PII, source code under NDA, or regulated data (health, finance, public-sector) through the hosted API without legal sign-off.
- Self-hosting: DeepSeek's open-weight models (DeepSeek-V3, DeepSeek-R1) can be self-hosted on
EU infrastructure (e.g. via vLLM or Ollama). Use
compendium-adapter-ollamaor a customBaseUrlpointing at a vLLM endpoint to keep data in-region.
Production checklist
-
ApiKeyinjected viaIConfiguration/KeyVault/ Compendium secret store — never committed to source. - Set a request
UserIdso DeepSeek can attribute requests to a specific tenant for abuse throttling. - Decide whether to inline reasoning into
Content— affects what downstream consumers see. - Override
TimeoutSecondsfor tight SLOs; default180sis sized fordeepseek-reasoner. - Wire an integration test gated on
DEEPSEEK_API_KEYso a future model rename trips CI. - Review data-residency before sending EU personal data.
- Monitor
Result.Error.Code = "AI.RateLimitExceeded"and back off accordingly — the standard resilience pipeline retries on 5xx but does not on 429 by default.
Versioning
Released as Compendium.Adapters.DeepSeek on NuGet. Version is computed from git tags by
MinVer; first tag v1.0.0-preview.0 is cut by the
orchestrator after this PR lands.
License
MIT — same as Compendium itself.
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net9.0 is compatible. net9.0-android was computed. net9.0-browser was computed. net9.0-ios was computed. net9.0-maccatalyst was computed. net9.0-macos was computed. net9.0-tvos was computed. net9.0-windows was computed. net10.0 was computed. net10.0-android was computed. net10.0-browser was computed. net10.0-ios was computed. net10.0-maccatalyst was computed. net10.0-macos was computed. net10.0-tvos was computed. net10.0-windows was computed. |
-
net9.0
- Compendium.Abstractions.AI (>= 1.0.1)
- Compendium.Core (>= 1.0.1)
- Microsoft.Extensions.Configuration.Abstractions (>= 9.0.16)
- Microsoft.Extensions.DependencyInjection.Abstractions (>= 9.0.16)
- Microsoft.Extensions.Http (>= 9.0.16)
- Microsoft.Extensions.Http.Resilience (>= 9.0.0)
- Microsoft.Extensions.Options (>= 9.0.16)
- Microsoft.Extensions.Options.ConfigurationExtensions (>= 9.0.16)
- System.Text.Json (>= 9.0.16)
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.
| Version | Downloads | Last Updated |
|---|---|---|
| 1.0.0-preview.0 | 49 | 5/21/2026 |