Skip to main content

DeepSee

DeepSeeLite (DSL) 是面向 DSH 的轻量独立版:保留视觉编排、兼容协议与网关能力,聚焦轻量部署与维护;完整 DeepSee 仍包含更广泛的服务、集成和扩展能力。

为 DeepSeek 官方 API 提供可插拔的视觉处理层,让 DeepSeek 获得多模态能力: 一次 ask_with_image() 调用,完成"视觉模型看图 → DeepSeek 推理回答"。

DSH 新手一键配置

已经安装 DSH Web 的用户,按下面四步即可让 DSH 使用 DeepSee 看图;不需要先理解 网关、插件或凭证文件。

1. 启动 DeepSee

pip install "seedeep[server]"
deepsee-server

首次启动会显示一条 public key 和一条 admin key。只复制 public key;不要复制或 填写 admin key。

2. 运行一键配置

在另一个终端运行:

curl -fsSL https://raw.githubusercontent.com/windyslime/DeepSee/main/scripts/install-dsh-dsv.sh | bash

看到 Configure DeepSee connection automatically? [Y/n/c] 时:

  • 直接按回车或输入 Y:选择自动配置;需要时粘贴刚才复制的 public key。
  • 输入 n:只安装,暂时不配置连接。
  • 输入 c:取消,不改动 DSH。

3. 重启 DSH 并发一张图片

在运行 DSH Web 的终端按 Ctrl+C 停止它,再用原来的启动命令重新启动并刷新浏览器。 然后在聊天中上传一张图片并提问。看到可折叠的“识图”行即表示连接生效。

4. 检查连接

curl -fsSL https://raw.githubusercontent.com/windyslime/DeepSee/main/scripts/install-dsh-dsv.sh \
  | bash -s -- --verify

看到 DeepSee gateway reachable 即表示 DSH 能找到 DeepSee。若提示网关不可达,确认第 1 步的 deepsee-server 仍在运行后重试。

没有交互终端时,先设置 public key,再使用自动配置;只想安装时使用仅安装模式:

export DEEPSEE_DSV_API_KEY='<DSV public key>'
curl -fsSL https://raw.githubusercontent.com/windyslime/DeepSee/main/scripts/install-dsh-dsv.sh \
  | bash -s -- --configure
curl -fsSL https://raw.githubusercontent.com/windyslime/DeepSee/main/scripts/install-dsh-dsv.sh \
  | bash -s -- --no-configure

完整排错见 docs/DSH-DSV-INSTALL.zh.md。安装器的技术约束、 凭证处理和发布检查见 CONTRIBUTING.md

安装

pip install seedeep

PyPI 上的 deepsee 已被 2014 年的无关项目占用,本包发布名为 seedeep; import 包名仍是 deepsee。启动本地服务时用 pip install "seedeep[server]"

快速开始

from deepsee import ask_with_image

answer = ask_with_image("photo.jpg", "这张图里有什么?")
print(answer)

配置

配置文件 deepsee.toml(放在当前目录或 ~/.config/deepsee/),也可以只用环境变量 (DeepSee_DEEPSEEK_API_KEY 等)。${ENV} 可引用环境变量:

[deepseek]
api_key = "${DEEPSEEK_API_KEY}"

[vision]
backend = "openai_compatible"   # openai_compatible | anthropic | gemini
api_key = "${VISION_API_KEY}"
base_url = "https://dashscope.aliyuncs.com/compatible-mode/v1"
model = "qwen-vl-max"

切换视觉后端只需修改 backend / api_key / base_url / model 四个字段。

用环境变量覆盖 VISION_BACKEND 切换后端时,TOML 中的 base_url / api_key / model 不会沿用(它们属于旧后端:base_url 指向旧主机,key 属于旧供应商, 会被发给错误的主机/供应商)。base_url 回落到新后端的官方默认主机 —— Anthropic 和 Gemini 有默认主机;OpenAI-compatible 没有默认值,必须显式设置 VISION_BASE_URLapi_keymodel 必须由环境变量显式提供,否则报错。 环境变量与 TOML 中字面量 backend 相同的 VISION_BACKEND 不算切换, TOML 配置原样保留(自定义代理 / 审计 / 数据驻留场景)。但 TOML backend 若写成 ${ENV} 插值(如 backend = "${VISION_BACKEND}"),一律视为切换: base_url 回落默认,且 api_key / model 必须使用标准环境变量 VISION_API_KEY / VISION_MODEL 显式提供 —— TOML 中的自定义 ${ENV} 占位符不会生效,旧变量可安全删除。

支持的后端

  • openai_compatible: Qwen-VL、GPT-4o、GLM-4V、Moonshot 等任意 OpenAI 兼容服务
  • anthropic: Claude 系列(原生 API)
  • gemini: Google Gemini(原生 API)

流式输出

for chunk in ask_with_image("photo.jpg", "讲个故事", stream=True):
    print(chunk, end="", flush=True)

异步 API

所有同步接口都有对应的 async 版本,签名一致:

import asyncio
from deepsee import ask_with_image_async

async def main():
    # 非流式
    answer = await ask_with_image_async("photo.jpg", "这张图里有什么?")
    print(answer)

    # 流式(async 迭代器)
    async for chunk in ask_with_image_async("photo.jpg", "讲个故事", stream=True):
        print(chunk, end="", flush=True)

asyncio.run(main())

另有 ask_async(纯文本)与 describe_image_async(仅视觉分析)。 错误语义与同步接口一致;图片处理(含 SSRF 防护)复用同一套同步管线。

本地网关

安装 server 依赖后启动网关:

pip install "seedeep[server]"
deepsee-server

网关默认启用入站鉴权。首次启动会创建一组 public/admin key,明文只在该次 启动输出,磁盘中的 ~/.config/deepsee/api-keys.json 只保存 SHA-256 摘要。 普通推理和模型列表使用 public key:

curl http://127.0.0.1:8712/v1/models \
  -H "Authorization: Bearer <public-key>"

/admin/* 管理端点使用独立的 admin key,通过 X-DeepSee-Admin-Key: <admin-key> 传递。需要补发密钥时运行 deepsee-server --create-recovery-keys;旧 key 保持有效,可通过管理 API 撤销。

临时本机开发可以显式关闭鉴权,但仅允许 loopback 地址:

deepsee-server --no-auth --host 127.0.0.1

默认每个身份每 60 秒最多 60 个推理请求,全局最多 8 个并发推理请求,并发队列 最多等待 2 秒。可用 DeepSee_RATE_LIMIT_REQUESTSDeepSee_RATE_LIMIT_WINDOWDeepSee_MAX_CONCURRENT_REQUESTSDeepSee_REQUEST_QUEUE_TIMEOUT 覆盖。计数只在当前进程内共享;多 worker 或多 实例部署还需要在反向代理层配置共享限速。

多协议端点

DSV 公开编排端点

POST /v1/dsv 是 DeepSee 对外提供的视觉编排/输出协议。客户端只提交图片、消息、 DeepSeek 模型和工具 schema;DeepSee 在内部调用配置的 OpenAI-compatible 视觉 API, 再编排 DeepSeek 推理。视觉 provider 的 api_key 不属于 DSV 请求体,也不会返回给 客户端。DSV v1 当前要求 [vision].backend = "openai_compatible"

请求中的图片可以使用 DSV 原生 base64 形状,工具结果继续使用 OpenAI-compatible 的 role: "tool" 消息回传:

{
  "model": "deepseek-chat",
  "stream": true,
  "messages": [{
    "role": "user",
    "content": [
      {"type": "text", "text": "这张图里有什么?"},
      {"type": "image", "source": {
        "type": "base64",
        "media_type": "image/png",
        "data": "<BASE64>"
      }}
    ]
  }],
  "tools": [],
  "vision": {"mode": "auto", "include_analysis": true}
}

SSE 流首先发送 response.createdvision.started 和完整的 vision.completed,随后发送 reasoning.deltaanswer.deltatool_call.delta。工具调用结束时发送 response.requires_action;调用方执行自己 的工具后,把结果作为下一次 DSV 请求的 role: "tool" 消息提交。DeepSee 不执行 调用方的工具。非流式响应将 visionanswerreasoningtool_callsusage 保持为独立字段。

服务同时暴露三种协议形状的聊天端点。视觉分析可以作为响应元数据返回, 供 GUI 像展开思考过程一样点击查看(字段语义 = "模型看到了什么"):

  • POST /v1/chat/completions — OpenAI 兼容;仅当请求包含 X-DeepSee-Include-Vision: 1 时,有图的非流式响应带 choices[0].message.vision_analysis,流式响应以独立前置 chunk 发出 choices[0].delta.vision_analysis(不含 content),随后是上游响应 chunk;
  • POST /v1/messages — Anthropic messages 形状;非流式响应顶层 vision_analysis;流式响应在 message_start 后发 {"type": "vision_analysis", "vision": ...} 事件;
  • POST /v1beta/models/{model}:generateContent — Gemini 形状;非流式 响应 parts 首位是 {"text": ..., "vision": true};流式响应以独立前置 chunk 发出该 part。

三种端点都支持 stream 参数(流式/非流式),图片输入按各自协议形状 (data URL / base64 source / inline_data / http URL),统一受 SSRF 防护与 字节上限约束;file:// 与本地路径一律拒绝。

示例(以 base64 图片 + 流式为例):

# OpenAI 兼容
curl -N http://127.0.0.1:8712/v1/chat/completions \
  -H "Authorization: Bearer <public-key>" \
  -H "X-DeepSee-Include-Vision: 1" \
  -H "Content-Type: application/json" -d '{
  "stream": true,
  "messages": [{"role": "user", "content": [
    {"type": "text", "text": "这张图里有什么?"},
    {"type": "image_url", "image_url": {"url": "data:image/png;base64,<BASE64>"}}
  ]}]
}'
# 响应:首个 chunk 为 {"choices":[{"delta":{"vision_analysis":"..."}}]},
#       之后 chunk 为 {"choices":[{"delta":{"content":"..."}}]},最后 data: [DONE]

# Anthropic messages
curl -N http://127.0.0.1:8712/v1/messages \
  -H "Authorization: Bearer <public-key>" \
  -H "Content-Type: application/json" -d '{
  "model": "claude-3-5-sonnet",
  "max_tokens": 1024,
  "stream": true,
  "messages": [{"role": "user", "content": [
    {"type": "image", "source": {"type": "base64", "media_type": "image/png", "data": "<BASE64>"}},
    {"type": "text", "text": "这张图里有什么?"}
  ]}]
}'
# 响应:message_start → {"type":"vision_analysis","vision":"..."} → content_block_delta(text) → message_stop

# Gemini generateContent
curl -N http://127.0.0.1:8712/v1beta/models/gemini-2.0-flash:generateContent \
  -H "Authorization: Bearer <public-key>" \
  -H "Content-Type: application/json" -d '{
  "stream": true,
  "contents": [{"parts": [
    {"inline_data": {"mime_type": "image/png", "data": "<BASE64>"}},
    {"text": "这张图里有什么?"}
  ]}]
}'
# 响应:首个 chunk 的 parts 为 [{"text":"...","vision":true}],后续 chunk 只带回答文本 part

安全限制

网关对模型、推理和分析端点强制 public key,对 /admin/* 强制 admin key; 直接导入 ASGI app 但未配置鉴权时 fail closed,只有 /health 保持公开。速率和 并发保护覆盖完整流式响应生命周期,客户端取消或上游异常后会释放并发名额。

图片加载对所有服务化图片入口统一生效(/v1/dsvimage.source/image_url/v1/chat/completionsimage_url/v1/messagessource.url/base64、 /v1beta/models/{model}:generateContentfile_data.file_uri/inline_data/analyze):

  • SSRF 防护:http(s) URL 的主机(含每一跳重定向目标)解析到私网、loopback、 link-local、保留或特殊用途地址(如 127.0.0.1169.254.169.254)时拒绝下载。 校验通过后,TCP 连接固定到已校验的 IP(域名只解析一次),消除 DNS rebinding TOCTOU;TLS 仍按原始域名校验证书。下载不读环境代理(trust_env=False), 防止代理绕过本地校验。RFC 6052 NAT64 前缀(64:ff9b::/9664:ff9b:1::/48) 显式拒绝;部署网络若使用其他自定义 NAT64 前缀,需自行扩展 deepsee/pipeline/image.py_NAT64_NETWORKS;
  • 本地路径:服务端只接受 data: 与 http(s) URL,file:// 与本地路径一律拒绝 (CLI 本地调用不受影响);
  • 资源上限:原始图片字节上限 20 MiB、解码像素上限约 1670 万(4096x4096), 超限在下载/解码前拒绝;下载请求 Accept-Encoding: identity 并拒绝压缩响应, 字节上限按原始字节流式累计(扩容前检查),防止大响应与解压炸弹耗尽内存;
  • 请求体上限:服务端请求体超过 32 MiB 返回 413,请求体流式读取, 无 Content-Length 的 chunked 请求同样受限;
  • 推理成本上限:默认最多 100 条消息/内容、4 张图片、20 万文本字符; 未指定输出长度时使用 4096 tokens,单次最多 8192 tokens。可通过 DeepSee_MAX_MESSAGESDeepSee_MAX_IMAGESDeepSee_MAX_TEXT_CHARSDeepSee_DEFAULT_MAX_OUTPUT_TOKENSDeepSee_MAX_OUTPUT_TOKENS 覆盖;
  • 流式超时:DeepSeek 流式响应的 HTTP 帧间超时 120 秒(完全静默的上游 120 秒后报错),另有总时长上限 300 秒(deepsee/composer/deepseek.py_STREAM_TOTAL_TIMEOUT)—— 持续发送 SSE keepalive 却永不 [DONE] 的上游会触发总时长上限,超时抛 ComposeError(服务端以 error chunk 通知)。 注意同步接口是检查点软上限(每次读到数据后检查截止时间,完全静默时 可能再等待一次 120 秒帧间超时);异步接口是响应体迭代阶段的硬上限 (响应头返回后每帧等待剩余时间;连接、响应头等待与重试不计入 300 秒);
  • 流式资源释放:库的流式接口(stream=True)返回的迭代器需完整消费或 调用 close() / aclose()(建议 contextlib.closing / aclosing)以释放 底层连接;服务端流式端点已用 aclosing 保证取消/断开时释放;
  • 环境代理:库发起的上游请求不读环境代理(trust_env=False)。SOCKS 代理 (如 ALL_PROXY=socks5://)在未安装 socksio 时会直接 ImportError,且代理 会把含 API key 的请求转发到第三方。依赖代理访问公网 API 的环境需直连或 自行配置传输层。

已知限制与后续工作

以下问题已确认但不在当前版本修复,列为后续工作:

  • CI: 仓库尚无 CI(GitHub Actions)。建议配置 pytest 在 Python 3.10-3.12 矩阵上运行,并开启依赖安全扫描;
  • 分支保护: 主分支保护属 GitHub 仓库设置,需人工开启(建议要求 PR 评审 与 CI 通过后才能合并)。

许可证

MIT

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

seedeep-0.1.0.tar.gz (60.8 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

seedeep-0.1.0-py3-none-any.whl (79.9 kB view details)

Uploaded Python 3

File details

Details for the file seedeep-0.1.0.tar.gz.

File metadata

  • Download URL: seedeep-0.1.0.tar.gz
  • Upload date:
  • Size: 60.8 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/7.0.0 CPython/3.13.11

File hashes

Hashes for seedeep-0.1.0.tar.gz
Algorithm Hash digest
SHA256 f56adb991d8f1f08e4663c09ee4b2b5b8b1d4e5fd0c65fcd6e2c357d9fad9262
MD5 4a202ad8c5da22303cb80a2615c07d7d
BLAKE2b-256 568e85e7c5bc03981bcab7d82450c78b6a085a2564e91aba03e84271b1a4063a

See more details on using hashes here.

File details

Details for the file seedeep-0.1.0-py3-none-any.whl.

File metadata

  • Download URL: seedeep-0.1.0-py3-none-any.whl
  • Upload date:
  • Size: 79.9 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/7.0.0 CPython/3.13.11

File hashes

Hashes for seedeep-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 94b4fd03425a3af48430859405c5c563e96252dd7991a66265f748d578f9c23a
MD5 c9fa8c165f407ff90002b8c279ea523d
BLAKE2b-256 d14ad4c54c7ab1a6089dfa75dfc51e5cb3e0741a2431008d329bc1e144b81145

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page