使用 DeepSeek 完成第一次请求

对应源码

运行环节源码
nanobot 命令入口pyproject.toml 的 [project.scripts]、nanobot/cli/commands.py::agent、onboard、status
配置路径与加载nanobot/config/paths.py、nanobot/config/loader.py::load_config、nanobot/config/schema.py::ProvidersConfig
DeepSeek 注册信息nanobot/providers/registry.py 中名为 deepseek 的 ProviderSpec
Provider 构造nanobot/providers/factory.py::load_provider_snapshot、make_provider
OpenAI-compatible 请求实现nanobot/providers/openai_compat_provider.py::OpenAICompatProvider

学习目标

完成本节后,你应当能够:

  • 从当前 code-CN 源码安装 nanobot;
  • 使用独立配置和 workspace,避免污染默认实例;
  • 通过环境变量提供 DeepSeek key;
  • 完成配置检查、普通请求和交互式请求;
  • 根据失败发生的位置判断问题属于安装、配置、Provider 还是 Agent runtime。

前置知识

不要粘贴真实密钥到文档

本节使用 DEEPSEEK_API_KEY 环境变量。不要把 key 写进 Markdown、Git、截图或共享日志。

1. 切换到当前源码

Set-Location "example\nanobot\code-CN"

当前 pyproject.toml 要求 Python 3.11 或更高版本:

python --version

2. 安装当前源码和开发依赖

建议在你自己的 Conda 环境中运行:

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 --version

如果提示符同时出现 (base) 和 (venv),先运行 deactivate,避免 python 继续指向旧的 venv。

-e 表示 editable install,命令实际导入当前工作区中的源码。后续阅读或示例修改后,不需要重新复制整个包。

源码依据:

  • pyproject.toml
    • requires-python = ">=3.11"
    • [project.scripts]
    • nanobot = "nanobot.cli.commands:app"

3. 创建隔离的学习实例

使用临时目录,避免修改默认的 ~/.nanobot/config.json 和 workspace:

$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 $nanobotWorkspace

这一步会:

  • 创建独立配置;
  • 将 workspace 写入该配置;
  • 初始化 workspace 模板;
  • 不改动本仓库的 learning-CN 或 code-CN 内容。

相关源码:

  • nanobot/cli/commands.py::onboard
  • nanobot/config/loader.py
  • nanobot/config/paths.py

4. 设置 DeepSeek key

仅对当前 PowerShell 进程及其子进程生效:

$env:DEEPSEEK_API_KEY = "在本机粘贴你的真实 key"

不要把上面这一行连同真实值保存到笔记或脚本。

5. 编辑学习配置

打开 $nanobotConfig,合并以下字段,不要删除 onboard 已生成的其他配置:

{
  "providers": {
    "deepseek": {
      "apiKey": "${DEEPSEEK_API_KEY}"
    }
  },
  "modelPresets": {
    "learning": {
      "label": "DeepSeek Learning",
      "provider": "deepseek",
      "model": "deepseek-v4-flash",
      "reasoningEffort": "none"
    }
  },
  "agents": {
    "defaults": {
      "modelPreset": "learning"
    }
  }
}

为什么这样配置:

  • providers.deepseek 对应 ProvidersConfig.deepseek;
  • ${DEEPSEEK_API_KEY} 在加载时由 config/loader.py 解析;
  • named preset 同时绑定 Provider、模型和生成参数;
  • 显式写 provider: deepseek 比第一次运行时依赖自动猜测更容易调试;
  • reasoningEffort: none 让第一个请求先走非思考模式,减少观察变量。

当前 nanobot 源码中的 DeepSeek Provider:

  • 名称:deepseek
  • backend:openai_compat
  • 默认 API base:https://api.deepseek.com
  • 环境变量:DEEPSEEK_API_KEY
  • 注册位置:nanobot/providers/registry.py

当前模型名

DeepSeek 当前官方模型为 deepseek-v4-flash 和 deepseek-v4-pro。旧别名 deepseek-chat、deepseek-reasoner 已进入停用节点,因此本学习库不使用旧别名。

外部依据:

6. 先检查配置

nanobot status 只检查默认实例,不能指定 --config。学习实例应直接运行一个明确带配置路径的请求:

nanobot agent `
  --config $nanobotConfig `
  --workspace $nanobotWorkspace `
  --message "只回复:nanobot 已连接 DeepSeek"

预期结果:

  • 配置能够加载;
  • Provider 能够创建;
  • 模型请求成功;
  • 输出一条正常 assistant 回复;
  • workspace 下出现 session 等运行数据。

回复文字可能不完全相同,不要把固定文本当作成功条件。

7. 打开运行日志

如果请求失败,加 --logs:

nanobot agent `
  --config $nanobotConfig `
  --workspace $nanobotWorkspace `
  --logs `
  --message "用一句话说明你已经就绪"

重点观察:

  • 当前 config 路径;
  • workspace 路径;
  • 解析出的 Provider 和模型;
  • 请求是否到达 Provider;
  • 是认证错误、参数错误、超时还是 Agent 错误;
  • 最终是否保存 Session。

8. 运行交互式 CLI

nanobot agent `
  --config $nanobotConfig `
  --workspace $nanobotWorkspace `
  --logs

依次发送:

记住数字 37。
我刚才让你记住哪个数字?

这个实验只证明同一个 CLI session 可以复用历史,不等于证明长期 Memory 已经工作。Session、Memory 和上下文的区别会在后续章节解释。

9. 最小 Tool Call 观察

在学习 workspace 中创建一个普通文本文件,然后让 nanobot 读取。不要让它访问真实项目或敏感目录。

Set-Content -LiteralPath (Join-Path $nanobotWorkspace "hello.txt") `
  -Value "nanobot-tool-check" `
  -Encoding utf8

在交互式 CLI 中请求:

请读取 workspace 根目录中的 hello.txt,并告诉我文件内容。

如果开启日志,可以观察:

  • 模型是否生成 Tool Call;
  • ToolRegistry 是否找到文件工具;
  • 路径是否落在 workspace;
  • tool result 是否回到下一次模型请求;
  • 最终文本是否引用正确内容。

这不是安全测试

当前实验只观察正常路径。Workspace 越权、Shell 和 SSRF 会在安全章节单独验证。

10. 运行后检查什么

检查实验目录:

Get-ChildItem -LiteralPath $nanobotLab -Recurse -Force

重点识别:

  • config.json:实例配置;
  • workspace/:Agent 工作空间;
  • workspace/sessions/:Session JSONL;
  • workspace 模板和 memory 目录;
  • 后续 Gateway 运行时可能出现的 cron 数据。

常见失败与第一判断

现象先检查
找不到 nanobot 命令Conda 环境是否已激活、editable install、python -m nanobot --version
${DEEPSEEK_API_KEY} 无法解析当前 PowerShell 是否设置环境变量
401key 是否正确、是否复制了额外空格
402DeepSeek 账户余额
422模型名、Provider 参数或生成参数
429请求频率
500/503Provider 服务状态和重试
Provider 无法匹配preset 中是否显式写 provider: deepseek
CLI 有回复但工具没调用请求是否确实需要工具、模型是否选择直接回答、工具是否已注册

DeepSeek 状态码含义参考 官方错误码。

你应该能解释

  1. 为什么使用单独的 config 和 workspace?
  2. ${DEEPSEEK_API_KEY} 在什么时候解析?
  3. 为什么 preset 要同时写 Provider 和 model?
  4. 为什么普通回复成功不能证明 Tool Call 流程也成功?
  5. 为什么交互式历史不等于长期 Memory?

下一步

阅读 五个入口与运行边界。