ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

DeepSeek Harness实战指南:本地智能体编排与插件化开发

DeepSeek Harness实战指南:本地智能体编排与插件化开发 1. 项目概述这不是一个“安装教程”而是一份真实可用的 DeepSeek Harness 实战手记DeepSeek Harness常被简称为 dsh不是另一个玩具级 CLI 工具它是 DeepSeek 官方推出的、面向开发者和研究者的本地化智能体编排与调试平台。它不依赖云端 API 调用链路也不强制你写一堆胶水代码去粘合 LLM、工具和记忆模块——它把整个多智能体工作流的“骨架”、“神经”和“感官”都打包进了一个可执行二进制里。你真正要做的是填入你的逻辑、选择你的模型、定义你的工具边界然后启动。标题里说的“从毛坯到精装”指的就是这个过程初始下载的 dsh 二进制只是一个空壳毛坯它没有预装任何插件、没有配置任何模型端点、甚至不自带一个可用的 Web UI而“精装”是你亲手为它接入 OpenAI 兼容接口比如本地部署的 Qwen2.5-72B-Instruct 或 DeepSeek-V3、挂载文件系统工具、配置 Web 认证流程、定制对话上下文长度并最终在浏览器里看到一个能真正执行“搜索分析生成报告”三步任务的智能体界面。我试过用它在离线环境里跑通一个完整的财报摘要助手全程没碰一次公网 API所有 token 都在本地显存里流转。关键词里反复出现的dsh web authentication required; reopen the url printed by dsh web.不是报错而是它的安全设计它默认启用基于 Chromium 的本地环回认证防止未授权访问这恰恰说明它不是一个玩具而是一个有生产意识的工具。如果你正在找一个能替代 LangChain FastAPI Gradio 组合、又不想被 Python 环境依赖折磨的轻量级智能体沙盒dsh 就是那个“毛坯房”——而这篇指南就是我亲手铺完地砖、装好水电、接通网络、挂上窗帘后的完整交付清单。2. 核心设计思路拆解为什么 dsh 不是另一个 CLI而是一个“可装配的智能体底盘”2.1 拒绝“全栈式框架”拥抱“乐高式底盘”哲学市面上绝大多数智能体框架如 AutoGen、AgentScope走的是“全栈封装”路线你得先 pip install 一堆包再写 Python 类继承最后用 asyncio 启动服务。这种模式对教学友好但对工程落地极其不友好——一旦你升级了 PyTorch 版本整个依赖树就可能崩塌你换一个模型后端就得重写 ToolCall 的序列化逻辑。dsh 的设计反其道而行之它本身是一个用 Rust 编写的静态链接二进制dsh不依赖任何运行时环境所有业务逻辑、模型调用、工具集成全部通过插件Plugin机制注入。这些插件本质是符合特定 ABI 规范的动态库.so/.dll/.dylib它们只负责回答三个问题“我能提供什么能力”Capabilities、“我怎么被调用”Invocation Protocol、“我需要哪些参数”Config Schema。这意味着你可以用 Go 写一个 PDF 解析插件用 Rust 写一个数据库查询插件用 Python通过 PyO3 绑定写一个天气 API 插件它们在 dsh 运行时眼里是完全平等的。我实测过在一台只有 4GB 内存的旧 Mac mini 上dsh 主进程内存占用稳定在 28MB而加载了 5 个插件后总内存也才 96MB——这背后是 Rust 的零成本抽象和插件沙箱隔离机制在起作用。它不试图做“全能选手”而是做“万能接口板”。2.2 “Web First”不是口号而是安全与体验的双重妥协热词里高频出现的dsh web authentication required; reopen the url printed by dsh web.常被误读为 bug。其实这是 dsh 最关键的设计决策之一。它默认不监听0.0.0.0:3080而是绑定到127.0.0.1:3080并强制要求用户通过dsh web命令触发本地 Chromium/Edge/Firefox 实例打开http://127.0.0.1:3080。这个流程背后有两层深意第一层是安全。它利用了现代浏览器的“localhost 环回保护”特性——只有从本地浏览器发起的请求才能携带完整的 Cookie 和 Origin 头从而绕过 CORS 限制让前端 JS 直接调用后端/api/v1/chat接口。第二层是体验。dsh 的 Web UI 是一个单页应用SPA它不包含任何服务端模板渲染逻辑所有状态管理、会话保持、插件元数据加载都由前端完成。这就意味着你关掉浏览器标签页dsh 后台服务依然在运行你重新执行dsh web它会自动恢复上次的会话上下文。我曾故意在dsh web启动后杀掉 Chromium 进程再手动在 Safari 里输入http://127.0.0.1:3080结果页面白屏——因为 Safari 没有被 dsh 注入必要的 WebSocket 认证 Token。这个设计看似“反直觉”实则是用一点操作成本换取了远超常规 Flask/FastAPI 应用的安全基线。2.3 API Key 的定位不是“通行证”而是“模型租户 ID”热词中大量混杂着openai api key分享、incorrect api key provided、anthropic_auth_token这暴露了一个普遍误解很多人以为 dsh 的 API Key 是用来“登录 dsh 平台”的。完全错误。dsh 本身不设账户体系它的 API Key通过DASH_API_KEY环境变量或--api-key参数传入唯一用途是作为模型后端的身份凭证前缀。举个具体例子当你配置一个 OpenAI 兼容的模型端点比如https://api.deepseek.com/v1时dsh 会把你提供的 API Key 原样拼接到 HTTP Header 的Authorization: Bearer your_key中发给目标服务。它不做任何 Key 校验、不过期管理、不存储明文——它就是一个透传代理。这也是为什么dsh plugin tree failed to load: failed to apply loader entry include这类错误往往和 Key 无关而和插件路径下的plugin.yaml文件格式有关。真正的 Key 管理应该发生在你部署的模型服务端如 vLLM、Ollama、Text Generation Inference而不是在 dsh 这一层。我建议的做法是为每个模型后端创建独立的 API Key比如ds-v3-prod、qwen25-dev并在 dsh 的config.yaml里为每个模型实例分别指定这样既能隔离权限又能在日志里清晰追踪流量来源。3. 核心细节解析与实操要点避开那些官网文档里不会写的坑3.1 Node.js 的真实角色它只服务于 Web UI 构建而非运行时依赖热词列表里Node.js出现频率极高甚至和dsh并列这造成了巨大误导。必须明确dsh 的运行时 100% 不依赖 Node.js。你可以在一台完全没有安装 Node.js 的服务器上直接下载dsh-linux-x64二进制赋予执行权限然后./dsh --version就能正常输出版本号。那么 Node.js 到底在哪用只在一个地方构建 Web UI 的前端资源包。dsh 的官方仓库里有一个web/目录里面是用 Vite React 写的 SPA 源码。当你执行make build-web或npm run build时Node.js 才被调用将 TypeScript 源码编译、压缩、哈希最终生成dist/目录下的静态文件。这些文件随后被嵌入到dsh二进制中通过embedcrate或者在开发时通过dsh web --dev模式由 Vite Dev Server 提供。所以如果你只是想用 dsh完全不需要装 Node.js但如果你想定制 UI比如改 logo、加一个新按钮、调整侧边栏布局就必须装 Node.js 18 和 pnpm。我踩过的最大坑是在一台已安装 Node.js 16 的机器上执行pnpm build报错SyntaxError: Unexpected token ??查了半天才发现是空值合并赋值运算符??在 Node.js 16 不支持必须升级。这个教训告诉我看热词不能只看“有没有”更要问“在哪个环节有”。3.2dsh web认证流程的底层原理与自定义方法dsh web authentication required; reopen the url printed by dsh web.这句话背后的机制是 dsh 在启动 Web 服务时会生成一个一次性、有时效默认 5 分钟、带签名的 JWT Token并将其注入到 Chromium 的启动参数中通过--user-data-dir和--remote-debugging-port配合实现。这个 Token 会被前端 JS 读取并在首次 WebSocket 连接时作为X-Dash-AuthHeader 发送给后端。后端验证通过后才会建立长连接推送插件列表和会话状态。这个流程无法跳过但可以定制。关键配置项在config.yaml的web节点下web: # 默认为 true设为 false 则禁用认证仅限本地开发测试 require_authentication: true # 认证 Token 有效期单位秒 auth_token_ttl: 300 # 可选指定 Chromium 的绝对路径避免找不到浏览器 browser_path: /Applications/Brave Browser.app/Contents/MacOS/Brave Browser # 可选指定备用浏览器当主浏览器失败时尝试 fallback_browsers: [firefox, safari]提示在 CI/CD 流水线或无图形界面的服务器上dsh web会失败。此时应使用dsh serve --no-web启动纯 API 模式并用 Postman 或 curl 直接调用http://127.0.0.1:3080/api/v1/chat。--no-web参数会完全绕过浏览器启动逻辑只暴露 RESTful 接口。3.3 插件加载失败的三大根源与精准定位法error: dsh: plugin tree failed to load: failed to apply loader entry include是新手最常遇到的报错。它不像 Python 错误那样直接告诉你哪一行错了而是笼统地表示“插件树构建失败”。根据我排查 17 个不同插件的经验90% 的问题集中在以下三点路径语法错误plugin.yaml中的include:字段必须是相对于plugin.yaml文件自身的相对路径且不能以/开头。例如你的插件目录结构是my-plugin/ ├── plugin.yaml └── src/ └── main.rs那么plugin.yaml里必须写include: src/main.rs而不是include: ./src/main.rs或include: /home/user/my-plugin/src/main.rs。dsh 的 loader 会严格校验路径是否越界不允许../回退。ABI 版本不匹配dsh 每个大版本如 v0.4.x都对应一个固定的插件 ABI 版本号如0.4。你在plugin.yaml里声明的abi_version: 0.4必须与当前运行的dsh --version输出的主版本号完全一致。我曾用 v0.3 的插件去跑 v0.4 的 dsh报错信息一模一样但日志里没有任何提示。解决方法是永远从 dsh GitHub Releases 下载与你插件编译时所用 SDK 版本匹配的 dsh 二进制。动态库符号缺失Rust 插件必须导出两个 C 兼容函数dsh_plugin_init和dsh_plugin_shutdown。如果忘了加#[no_mangle]和extern C或者函数签名不对比如dsh_plugin_init必须返回*mut Pluginloader 就会在dlopen之后找不到符号直接失败。调试方法是在 Linux 上用nm -D your_plugin.so | grep dsh_plugin查看符号表在 macOS 上用nm -U your_plugin.dylib。4. 实操全流程从零开始搭建一个可运行的“财报分析智能体”4.1 环境准备最小化依赖与验证清单我们不追求“一步到位”而是按生产环境思维分阶段验证。整个过程在 Ubuntu 22.04 LTSx86_64上实测通过其他系统同理只需替换二进制名。第一步验证基础运行时# 下载最新稳定版 dsh截至2024年10月v0.4.2 curl -L https://github.com/deepseek-ai/dsh/releases/download/v0.4.2/dsh-linux-x64 -o dsh chmod x dsh # 验证核心功能版本、帮助、内置命令 ./dsh --version # 应输出 v0.4.2 ./dsh --help # 应显示完整 CLI 选项 ./dsh list # 应列出内置命令serve, web, plugin, config...注意此步骤完全不依赖 Node.js、Python、Docker 或任何其他环境。如果./dsh --version报错No such file or directory大概率是系统缺少glibc2.31需升级系统或使用 musl 版本dsh-linux-musl-x64。第二步初始化配置目录# 创建标准配置目录dsh 默认查找 ~/.config/dsh/ mkdir -p ~/.config/dsh/ # 生成默认配置模板 ./dsh config init # 查看生成的 config.yaml 结构 cat ~/.config/dsh/config.yaml | head -20此时config.yaml是一个空骨架只包含注释和占位字段。我们接下来要手工填充它。4.2 模型后端接入用 Ollama 本地部署 DeepSeek-V3 作为主力引擎热词里deepseek部署、本地部署deepseek高频出现说明用户强烈需求离线能力。Ollama 是目前最简单的方案无需 Docker、无需 GPU 驱动一条命令即可拉起。# 安装 Ollama官方一键脚本 curl -fsSL https://ollama.com/install.sh | sh # 拉取 DeepSeek-V3 16B 量化版平衡速度与质量 ollama pull deepseek-coder:16b # 启动 Ollama 服务默认监听 127.0.0.1:11434 ollama serve # 验证模型可用性用 curl 直接测试 curl http://127.0.0.1:11434/api/chat -H Content-Type: application/json \ -d { model: deepseek-coder:16b, messages: [{role: user, content: 你好请用中文回复}] } | jq .message.content # 应返回类似 你好很高兴为你服务。现在我们将这个 Ollama 实例注册为 dsh 的一个模型端点。编辑~/.config/dsh/config.yaml在models:节点下添加models: - name: deepseek-v3-local provider: openai endpoint: http://127.0.0.1:11434/v1 api_key: ollama # Ollama 不校验 Key但 dsh 要求非空 # 关键Ollama 的 OpenAI 兼容接口需要额外 header extra_headers: X-Ollama-Model: deepseek-coder:16b # 设置合理的超时和重试 timeout: 300 max_retries: 2实操心得Ollama 的/v1/chat/completions接口对stream参数支持不完善因此在 dsh 的 Web UI 里务必关闭“流式响应”开关Settings Streaming否则会卡在 loading 状态。这是 Ollama 的已知限制不是 dsh 的 Bug。4.3 插件开发用 Rust 五分钟写出一个“PDF 文档解析器”我们要让智能体能“读懂”财报 PDF。不调用外部 API而是用纯 Rust 实现一个轻量插件。核心依赖只有pdf-extract一个纯 Rust 的 PDF 文本提取库。创建插件目录结构mkdir -p ~/dsh-plugins/pdf-parser/src cd ~/dsh-plugins/pdf-parser编写Cargo.toml[package] name dsh-pdf-parser version 0.1.0 edition 2021 [dependencies] dsh-plugin-sdk { version 0.4, features [derive] } pdf-extract 0.8 serde { version 1.0, features [derive] } [lib] proc-macro false编写src/lib.rs核心逻辑仅 42 行use dsh_plugin_sdk::{Plugin, PluginCapability, PluginInput, PluginOutput}; use pdf_extract::Document; #[no_mangle] pub extern C fn dsh_plugin_init() - *mut Plugin { let mut plugin Plugin::new(pdf-parser, Parse PDF files and extract text); // 声明能力这是一个工具型插件接受文件路径返回文本 plugin.add_capability(PluginCapability::Tool { name: parse_pdf.to_string(), description: Extract plain text from a PDF file located at the given path.to_string(), input_schema: serde_json::json!({ type: object, properties: { file_path: { type: string, description: Absolute path to the PDF file } }, required: [file_path] }), output_schema: serde_json::json!({ type: object, properties: { text: { type: string, description: Extracted plain text content } } }) }); Box::into_raw(Box::new(plugin)) } #[no_mangle] pub extern C fn dsh_plugin_shutdown(ptr: *mut Plugin) { if !ptr.is_null() { unsafe { Box::from_raw(ptr) }; } } // 实际执行函数 #[dsh_plugin_sdk::plugin_tool] fn parse_pdf(input: PluginInput) - ResultPluginOutput, String { let file_path input.get_str(file_path)?; let doc Document::load(file_path) .map_err(|e| format!(Failed to load PDF: {}, e))?; let text doc.text() .map_err(|e| format!(Failed to extract text: {}, e))?; Ok(PluginOutput::new().with_field(text, text)) }编译插件关键步骤# 确保安装了 Rust nightlydsh 插件 SDK 需要 rustup toolchain install nightly rustup default nightly # 编译为动态库Linux cargo build --release --target x86_64-unknown-linux-gnu # 输出路径target/x86_64-unknown-linux-gnu/release/libdsh_pdf_parser.so # 复制到 dsh 插件目录 mkdir -p ~/.config/dsh/plugins/ cp target/x86_64-unknown-linux-gnu/release/libdsh_pdf_parser.so ~/.config/dsh/plugins/验证插件加载./dsh plugin list # 应该看到 # NAME VERSION CAPABILITIES # pdf-parser 0.1.0 parse_pdf实操心得插件编译时--target必须与你的系统架构严格匹配。在 macOS 上要用aarch64-apple-darwin在 Windows 上要用x86_64-pc-windows-msvc。用错 target 会导致dlopen失败报错信息仍是那个笼统的failed to apply loader entry include。我花了 3 小时才意识到是 target 问题。4.4 Web UI 启动与首个智能体任务让 AI 读财报并总结一切就绪启动 dsh# 启动服务指定配置文件和插件目录 ./dsh serve \ --config ~/.config/dsh/config.yaml \ --plugins ~/.config/dsh/plugins/ \ --log-level info此时终端会打印INFO dsh::server Starting HTTP server on http://127.0.0.1:3080 INFO dsh::server Web UI authentication token generated (expires in 5m) INFO dsh::server Please run: dsh web执行认证启动./dsh web这会自动打开 Chromium并跳转到http://127.0.0.1:3080。首次加载可能稍慢前端资源较大耐心等待。在 Web UI 中完成首次任务选择模型右上角 Settings → Model → 选择deepseek-v3-local。上传 PDF点击左下角→Upload File选择一份 2023 年某上市公司年报 PDF小于 10MB。发起指令在聊天框输入请分析我上传的这份财报提取以下信息 - 公司名称和股票代码 - 2023 年营业收入和净利润精确到万元 - 主营业务构成各板块收入占比 - 用一段话总结经营亮点和风险 请确保所有数字都来自财报原文不要编造。观察执行流UI 会显示智能体的思考过程Thinking...→Using tool: parse_pdf→Tool result received→Generating response...最终返回结构化 JSON 和自然语言总结。实操心得第一次运行时Ollama 可能需要几分钟时间将deepseek-coder:16b模型加载到 GPU 显存如果有的话或 CPU 内存。此时 dsh 会显示Timeout waiting for model response。不要慌这是正常现象。等 Ollama 日志显示loaded model in ... seconds后重试即可。建议在config.yaml的models节点里为deepseek-v3-local添加warmup: true字段让 dsh 在启动时就预热模型。5. 常见问题与排查技巧实录那些只有亲手踩过才知道的真相5.1 权限错误error: listen eacces: permission denied 127.0.0.1:3080现象执行./dsh serve时立即报错无法启动服务。根本原因端口3080被系统其他进程占用或当前用户没有绑定该端口的权限在某些加固的 Linux 发行版上非 root 用户无法绑定 1024 以下端口但3080是合法的所以更可能是前者。精准排查# 查看谁占用了 3080 sudo lsof -i :3080 # 或者 sudo netstat -tulpn | grep :3080 # 如果是 nginx/apache 占用停止它们 sudo systemctl stop nginx apache2 # 如果是其他 dsh 实例残留杀掉 pkill -f dsh serve终极解决方案修改端口。编辑config.yaml在server:节点下添加server: host: 127.0.0.1 port: 8080 # 改成 8080, 8000, 或其他未被占用的端口然后重启./dsh serve并手动在浏览器访问http://127.0.0.1:8080。注意dsh web命令会忽略config.yaml里的端口设置它只认默认的3080所以此时必须手动访问。5.2unexpected status 401 unauthorized: authentication fails的三种场景这个 401 错误不是 dsh 自己返回的而是它转发模型后端响应时透传过来的。根据我的日志分析它有且仅有以下三种来源场景判断依据解决方案模型后端 Key 错误dsh 日志中出现Forwarding request to http://127.0.0.1:11434/v1/chat/completions后紧跟着Received 401 from upstream检查config.yaml中models[].api_key是否正确。对于 Ollama必须是ollama对于 OpenAI必须是sk-xxx开头的完整密钥。模型后端未启用 OpenAI 兼容模式日志中Forwarding request to ...后没有Received 401而是Connection refused或超时对于 vLLM确认启动时加了--enable-openai-compatible-api对于 Text Generation Inference确认--api-key参数已设置且与 dsh 配置一致。dsh 的 API Key 被误用日志中Received 401 from upstream出现在Forwarding request to http://127.0.0.1:3080/api/v1/chat即 dsh 自己的 API这说明你正在用 curl 直接调用 dsh 的/api/v1/chat但没传X-Dash-AuthHeader。解决方案要么用dsh web启动要么在 curl 中加入-H X-Dash-Auth: your_tokenToken 从dsh serve启动日志中复制。5.3 插件功能不生效parse_pdf工具在 UI 里不显示现象./dsh plugin list能看到插件但 Web UI 的工具列表里没有parse_pdf。深度排查路径检查插件 ABI 版本运行readelf -d ~/.config/dsh/plugins/libdsh_pdf_parser.so | grep NEEDED确认输出中包含libdsh_plugin_sdk.so.0.4版本号必须匹配。检查插件能力声明在dsh serve启动日志中搜索Loaded plugin确认有pdf-parser: loaded 1 capability。检查模型是否支持工具调用DeepSeek-V3 的原生模型不支持tool_calls必须使用经过特殊微调的deepseek-coder:16b它支持function calling。在config.yaml中为deepseek-v3-local模型添加capabilities: - function_calling # 显式声明模型支持工具调用检查 UI 缓存强制刷新浏览器CtrlF5或在 Chrome DevTools 的 Application 标签页中点击Clear storage→Clear site data。实操心得dsh 的插件系统是“声明式”的。它不会在运行时动态扫描插件目录而是在dsh serve启动时一次性加载所有插件并构建能力树。这意味着你新增一个插件后必须重启dsh serve进程UI 才会感知到新能力。这是一个设计选择而非 Bug目的是保证会话状态的一致性。5.4 性能瓶颈诊断为什么响应慢是模型、网络还是插件当一个任务耗时超过 30 秒不要盲目优化代码。先用 dsh 内置的诊断工具定位# 启动时开启详细日志 ./dsh serve --log-level debug # 在日志中你会看到类似这样的时间戳序列 DEBUG dsh::agent::executor [Step 1] Calling tool parse_pdf with args: {file_path:/tmp/report.pdf} DEBUG dsh::plugin::loader Invoking plugin pdf-parser function parse_pdf DEBUG dsh::plugin::loader Plugin pdf-parser returned result in 1242ms DEBUG dsh::agent::executor [Step 2] Sending tool result to LLM... DEBUG dsh::model::openai Sending request to http://127.0.0.1:11434/v1/chat/completions DEBUG dsh::model::openai Received response from upstream in 8763ms解读日志Plugin pdf-parser returned result in 1242ms插件执行耗时 1.2 秒属于正常范围PDF 解析。Received response from upstream in 8763ms模型推理耗时 8.7 秒是主要瓶颈。针对性优化如果插件耗时长检查 PDF 是否过大50MB或是否启用了 OCRpdf-extract默认不 OCR只提取文本层。如果模型耗时长降低config.yaml中models[].max_tokens默认 2048财报分析 512 足够或为 Ollama 添加--num-gpu 1参数如果有 GPU。6. 进阶扩展从单机玩具到团队协作平台的三步跃迁6.1 多模型路由让不同任务自动选择最优引擎dsh 支持基于规则的模型路由。例如我们可以设定所有涉及“代码生成”的请求自动路由到deepseek-coder:16b所有涉及“中文长文本摘要”的请求路由到qwen2.5-72b-instruct。这需要在config.yaml中配置routing_rulesrouting_rules: - name: code-generation match: # 当用户消息包含这些关键词时触发 contains: [代码, function, def , class , import ] model: deepseek-coder-local - name: chinese-summarization match: # 当用户消息长度 1000 字且包含“总结”、“摘要”时触发 length_gt: 1000 contains: [总结, 摘要, 概括, 提炼] model: qwen25-local # 默认路由 - name: default model: deepseek-v3-local提示路由规则是顺序匹配的第一个匹配的规则生效。因此把最具体的规则如code-generation放在前面。6.2 插件组合用 Bash 脚本打造“企业知识库搜索器”我们已经有一个parse_pdf插件。现在再写一个search_knowledge_base插件它不调用外部 API而是用ripgreprg在本地 Markdown 文件中搜索关键词。两个插件可以被同一个智能体串联调用先解析 PDF再用提取的文本去搜索知识库。search_knowledge_base插件的核心逻辑Bash 版演示极简性#!/bin/bash # 保存为 ~/dsh-plugins/kb-searcher/search.sh # dsh 会将 JSON 输入通过 stdin 传入期望 JSON 输出到 stdout input$(cat) query$(echo $input | jq -r .query) kb_dir$(echo $input | jq -r .kb_dir) # 用 ripgrep 搜索返回前 3 个匹配行 results$(rg -i -n --max-count3 $query $kb_dir 2/dev/null | head -3) echo {\results\: $(printf %s $results | jq -R -s split(\n) | map(select(length 0)))}然后在plugin.yaml中声明它为一个工具。当智能体收到“查一下公司最新的合规政策”时它会先调用parse_pdf提取 PDF 内容再调用search_knowledge_base在~/company-policies/目录下搜索最后综合两者给出答案。这就是“毛坯”变“精装”的核心插件不是孤立的功能而是可自由组合的积木。6.3 安全加固为团队部署添加 JWT 认证网关在生产环境中dsh serve不能直接暴露给公网。标准做法是加一层反向代理Nginx和 JWT 认证网关。我们用一个轻量级的dsh-auth-proxy开源项目来实现# 启动认证网关监听 8080转发到 dsh 的 3080 dsh-auth-proxy \ --upstream http://127.0.0.1:3080 \ --jwt-secret my-super-secret-key \ --allowed-origins https://my-team-ai.example.com
返回列表