Complete your first request with DeepSeek
Corresponding source
| Runtime step | Source |
|---|---|
nanobot command entry | [project.scripts] in pyproject.toml; nanobot/cli/commands.py::agent, onboard, status |
| Configuration path and loading | nanobot/config/paths.py, nanobot/config/loader.py::load_config, nanobot/config/schema.py::ProvidersConfig |
| DeepSeek registration | The ProviderSpec named deepseek in nanobot/providers/registry.py |
| Provider construction | nanobot/providers/factory.py::load_provider_snapshot, make_provider |
| OpenAI-compatible request implementation | nanobot/providers/openai_compat_provider.py::OpenAICompatProvider |
Learning objectives
After this lesson, you should be able to:
- install nanobot from the current
code-CNsource; - use a separate configuration and workspace so the default instance remains untouched;
- supply a DeepSeek key through an environment variable;
- complete configuration validation, a one-shot request, and an interactive request;
- classify a failure as installation, configuration, Provider, or Agent runtime.
Prerequisites
- Run commands in PowerShell.
- Know JSON object and comma syntax.
- Have read LLM messages, streaming, and tool calling.
Never paste a real key into documentation
This lesson uses the
DEEPSEEK_API_KEYenvironment variable. Do not put the key in Markdown, Git, screenshots, or shared logs.
1. Change to the current source directory
Set-Location "example\nanobot\code-CN"The current pyproject.toml requires Python 3.11 or later:
python --version2. Install the current source and development dependencies
Run this in your own Conda environment:
conda create -n nanobot-learning -c conda-forge --override-channels python=3.11 pip -y
conda activate nanobot-learning
python -m pip install -e ".[dev]"
nanobot --versionIf the prompt shows both (base) and (venv), run deactivate first so python does not continue pointing to the old venv.
-e creates an editable install, so the command imports the source from the current workspace. You do not need to copy the package after reading it or changing an isolated example.
Source evidence:
pyproject.tomlrequires-python = ">=3.11"[project.scripts]nanobot = "nanobot.cli.commands:app"
3. Create an isolated learning instance
Use a temporary directory so the default ~/.nanobot/config.json and workspace remain untouched:
$nanobotLab = Join-Path $env:TEMP "nanobot-learning"
$nanobotConfig = Join-Path $nanobotLab "config.json"
$nanobotWorkspace = Join-Path $nanobotLab "workspace"
New-Item -ItemType Directory -Force -Path $nanobotLab | Out-Null
nanobot onboard --config $nanobotConfig --workspace $nanobotWorkspaceThis command:
- creates a separate configuration;
- writes the workspace location into that configuration;
- initializes workspace templates;
- does not modify this repository’s
learning-ENorcode-CNcontent.
Related source:
nanobot/cli/commands.py::onboardnanobot/config/loader.pynanobot/config/paths.py
4. Set the DeepSeek key
Set it only for the current PowerShell process and its child processes:
$env:DEEPSEEK_API_KEY = "paste your real key locally"Do not save that line with its real value in a note or script.
5. Edit the learning configuration
Open $nanobotConfig and merge these fields without deleting other configuration generated by onboard:
{
"providers": {
"deepseek": {
"apiKey": "${DEEPSEEK_API_KEY}"
}
},
"modelPresets": {
"learning": {
"label": "DeepSeek Learning",
"provider": "deepseek",
"model": "deepseek-v4-flash",
"reasoningEffort": "none"
}
},
"agents": {
"defaults": {
"modelPreset": "learning"
}
}
}Why these fields are explicit:
providers.deepseekmaps toProvidersConfig.deepseek;config/loader.pyresolves${DEEPSEEK_API_KEY}during loading;- a named preset binds the Provider, model, and generation parameters together;
provider: deepseekis easier to debug on the first run than automatic inference;reasoningEffort: nonekeeps the first request in non-reasoning mode and reduces the number of variables to observe.
The current DeepSeek Provider in nanobot has:
- name:
deepseek; - backend:
openai_compat; - default API base:
https://api.deepseek.com; - environment variable:
DEEPSEEK_API_KEY; - registration:
nanobot/providers/registry.py.
Current model names
DeepSeek’s current official models are
deepseek-v4-flashanddeepseek-v4-pro. The olddeepseek-chatanddeepseek-reasoneraliases are in a retirement phase, so this library does not use them.
External evidence:
6. Validate the configuration with an explicit request
nanobot status checks only the default instance and does not accept --config. For the learning instance, run a request with explicit paths:
nanobot agent `
--config $nanobotConfig `
--workspace $nanobotWorkspace `
--message "Reply only with: nanobot is connected to DeepSeek"Expected outcome:
- configuration loads;
- the Provider is created;
- the model request succeeds;
- one normal assistant response is printed;
- Session and other runtime data appear under the workspace.
The exact wording may differ. Do not treat a fixed sentence as the success condition.
7. Enable runtime logs
If the request fails, add --logs:
nanobot agent `
--config $nanobotConfig `
--workspace $nanobotWorkspace `
--logs `
--message "Confirm in one sentence that you are ready."Observe:
- the active config path;
- the workspace path;
- the resolved Provider and model;
- whether the request reached the Provider;
- whether the failure is authentication, parameters, timeout, or Agent logic;
- whether the Session was ultimately saved.
8. Run the interactive CLI
nanobot agent `
--config $nanobotConfig `
--workspace $nanobotWorkspace `
--logsSend these messages in order:
Remember the number 37.
Which number did I ask you to remember?This experiment proves only that one CLI session can reuse history. It does not prove that long-term Memory is working. Later lessons explain the differences among Session, Memory, and context.
9. Observe a minimal Tool Call
Create an ordinary text file inside the learning workspace, then ask nanobot to read it. Do not point it at a real project or sensitive directory.
Set-Content -LiteralPath (Join-Path $nanobotWorkspace "hello.txt") `
-Value "nanobot-tool-check" `
-Encoding utf8In the interactive CLI, ask:
Read hello.txt from the workspace root and tell me its contents.With logs enabled, observe:
- whether the model produces a Tool Call;
- whether ToolRegistry finds the filesystem tool;
- whether the resolved path remains inside the workspace;
- whether the tool result enters the next model request;
- whether the final text reports the correct contents.
This is not a security test
The exercise observes only the normal path. Workspace escape, Shell, and SSRF receive separate treatment in the security section.
10. Inspect the result
List the experiment directory:
Get-ChildItem -LiteralPath $nanobotLab -Recurse -ForceIdentify:
config.json: instance configuration;workspace/: Agent workspace;workspace/sessions/: Session JSONL;- workspace templates and the memory directory;
- cron data that may appear after a later Gateway run.
Common failures and first checks
| Symptom | Check first |
|---|---|
nanobot command not found | whether the Conda environment is activated, editable install, python -m nanobot --version |
${DEEPSEEK_API_KEY} cannot be resolved | whether the variable is set in the current PowerShell process |
| 401 | key correctness and accidental whitespace |
| 402 | DeepSeek account balance |
| 422 | model name, Provider arguments, or generation parameters |
| 429 | request rate |
| 500/503 | Provider status and retry behavior |
| Provider cannot be matched | whether the preset explicitly says provider: deepseek |
| CLI responds but does not call a tool | whether the request requires a tool, whether the model answered directly, and whether the tool was registered |
See the official DeepSeek error codes.
You should be able to explain
- Why use a separate config and workspace?
- When is
${DEEPSEEK_API_KEY}resolved? - Why should a preset specify both Provider and model?
- Why does a normal response not prove that the Tool Call path works?
- Why is interactive history not the same as long-term Memory?