deepseek-recipe ≠ DeepInfer engine
Protocol layer: convert API requests, render prompts, encode tokens, parse outputs. It does not run inference. You provide the backend, tools, and HTTP.
Is / is-not
| deepseek-recipe | DeepInfer | |
|---|---|---|
| Is | Request → Conversation → prompt / token IDs; output → Chat Completions / Responses / Messages | High-performance inference engine (offline OSS path for V4.1-Flash) |
| Is not | Does not load weights or run kernels | Does not replace protocol conversion (use recipe or your own glue) |
| Caller must provide | Model inference + tool execution + HTTP transport | Supported accelerators + build env |
| License | MIT | Apache-2.0 |
Protocol surface
- Formats: Messages, Chat Completions, Responses — streaming and complete
- Prompts: DeepSeek V4 / V4.1 conversation rendering + tokenizer encoding
- Thinking mode, reasoning effort, temperature, top_p, output token limits
- Output parsing: reasoning, tool calls, JSON object, stop sequences
- Structured output: JSON Schema / regex (caller decides if backend enforces constrained decoding)
- Images (V4.1): base64 or URLs via image component; V4 replaces images with
[Unsupported Image]
max_tokens defaults
From the recipe README: after encoding, ConversationRequest::resolve_max_tokens supplies defaults when the request sets none:
| Mode | Default max_tokens |
|---|---|
| Non-thinking | 8192 |
| Thinking | 65536 |
Thinking + max effort | 131072 |
Python install
Python 3.10+:
python3 -m pip install deepseek-recipe
from deepseek_recipe import ChatCompletionRequest, ConversionOptions, DeepseekV41Encoding
request = ChatCompletionRequest({
"model": "DeepSeek-V4.1-Flash",
"messages": [{"role": "user", "content": "Hello"}],
})
converted = request.convert(ConversionOptions())
rendered = DeepseekV41Encoding().render_conversation(converted.conversation)
print(rendered.prompt)
Rust install
cargo add deepseek-recipe@0.2 deepseek-recipe-encoding@0.2 serde_json@1
See upstream development guide for source builds and image dependencies. Demo: cargo run -p encoding-decoding-demo --locked → http://127.0.0.1:7778.
Glue notes
- Recipe alone never downloads DeepInfer weights or starts an engine
- Wire recipe in front of DeepInfer offline, another backend, or the official API
- Agents / harness → dshbase.com (not recipe, not this site’s install path)
- Example servers in-repo:
server-rs(Axum + mock inference),server-py(FastAPI + mock inference)
API triad (Messages · Chat Completions · Responses)
From the recipe README and production explainers: one Conversation format is shared; adapters map Messages / Chat Completions / Responses in and out. Special-token injection is blocked by encoding control tokens by ID while ordinary text that looks like tags stays literal. Streaming uses a state machine across UTF-8 / DSML / tool-argument chunk boundaries.
| Concern | Recipe responsibility | Caller still owns |
|---|---|---|
| Request shapes | Convert triad → Conversation + prompt / tokens | HTTP auth, rate limits |
| Injection safety | Special tokens by ID; user text cannot inject control tokens | Untrusted URL fetch filters for images |
| Streaming | Incremental parse of reasoning / body / tools | Inference token stream from your backend |
| Tools | Parse tool-call events into protocol frames | Actually execute tools |