
在實際企業級應用開發中我們經常面臨將內部工具或AI能力安全、便捷地集成到現有辦公門戶的需求。傳統的集成方式如開發獨立的微服務或編寫復雜的API對接腳本不僅開發周期長而且后期維護、權限控制和用戶交互體驗都面臨挑戰。DeepSeek Harness簡稱DSH及其插件生態的出現為這類場景提供了一種新穎、高效的解決方案。它允許開發者將AI功能、數據處理工具或業務邏輯封裝成標準的插件并一鍵發布到插件市場最終用戶可以像安裝手機App一樣在DeepSeek Harness桌面端或Web門戶中直接使用。本文將以一個假設的“政務數據簡報生成”場景為例詳細演示如何從零開始開發一個DSH插件并將其成功接入一個模擬的政務門戶系統中。我們將涵蓋從環境搭建、插件開發、本地調試、打包發布到門戶集成的完整閉環。通過這個案例你將掌握DSH插件開發的核心流程、關鍵配置項以及在實際集成中可能遇到的典型問題及其解決方案。無論你是希望將內部AI工具產品化還是尋求更輕量級的系統集成方式本文都能提供一條清晰的實踐路徑。1. 理解 DeepSeek Harness 插件生態與政務門戶集成架構在開始編碼之前必須厘清幾個核心概念和它們之間的協作關系。這能幫助你在后續步驟中理解每一個配置和代碼片段的目的而不是機械地復制粘貼。1.1 DeepSeek Harness (DSH) 是什么DeepSeek Harness 是一個開源的AI應用開發與部署平臺。你可以把它理解為一個“容器”或“運行時環境”專門用于托管和運行各種AI能力或工具化應用這些應用以“插件”的形式存在。DSH本身提供了插件管理、生命周期控制、資源隔離以及統一的前端交互框架。開發者無需從零構建一個完整的Web應用只需關注插件的核心業務邏輯。1.2 DSH 插件是什么一個DSH插件就是一個符合其規范的項目包。它通常包含業務邏輯代碼用Python、Node.js等語言編寫的核心功能。插件聲明文件 (plugin.yaml)描述插件的元信息如名稱、版本、入口命令、配置參數、前端組件等。前端UI組件可選如果插件需要用戶界面可以提供Vue/React組件。依賴聲明文件如requirements.txt或package.json。插件被安裝到DSH后DSH會為其創建獨立的運行環境并負責調用其聲明的命令或渲染其UI。1.3 “接入政務門戶”意味著什么這里的“政務門戶”是一個泛指可以是任何內部OA系統、統一工作臺或信息門戶。接入方式通常不是直接修改門戶源碼而是通過以下兩種模式嵌入式集成在門戶的某個頁面內通過 iframe 或 Web Components 嵌入 DSH 桌面端的特定插件頁面。門戶負責身份認證和權限傳遞DSH負責插件的渲染和執行。鏈接跳轉在門戶上放置一個鏈接點擊后在新窗口或標簽頁中打開 DSH 桌面端并直接定位到該插件界面。本文重點演示第一種更深度集成的模式。其技術鏈路可以概括為政務門戶 (前端) --[攜帶Token]-- DSH 桌面端/服務 --[加載并運行]-- 你的插件整個流程的關鍵在于門戶與DSH之間的安全認證如JWT Token傳遞以及DSH對插件的正確加載。1.4 開發前需要明確的幾個問題目標用戶是政務內部工作人員他們對插件的穩定性、安全性和易用性要求極高。插件類型你的插件是提供API服務無UI還是需要一個交互界面本文案例是一個帶有簡單UI的數據處理插件。部署環境DSH是部署在內部服務器還是云端這影響到后續的網絡配置和訪問地址。2. 環境準備與項目初始化一個順暢的開發環境能避免很多后續的詭異問題。請嚴格按照順序操作。2.1 基礎環境檢查與安裝你需要準備以下工具并確認版本兼容性。建議使用版本管理工具如nvm、pyenv來保持環境純凈。工具推薦版本作用驗證命令Node.js18.x 或 20.x (LTS)運行DSH桌面端及前端工具鏈node --versionpnpm8.0.0推薦使用的包管理器比npm更快、更節省磁盤pnpm --versionPython3.8 - 3.11編寫插件后端邏輯如果插件使用Pythonpython --versionGit最新版代碼版本管理git --version安裝DSH命令行工具DSH CLI它是開發、調試、管理插件的核心。# 使用 pnpm 全局安裝 dsh-cli pnpm add -g deepeek/dsh-cli # 安裝完成后驗證安裝是否成功 dsh --version如果出現‘dsh’ 不是內部或外部命令的錯誤請將pnpm的全局bin目錄通常為~/.local/share/pnpm/global/5/node_modules/.bin或類似路徑添加到系統的PATH環境變量中。2.2 創建你的第一個插件項目DSH CLI 提供了項目腳手架可以快速生成一個結構規范的插件項目。# 創建一個目錄用于存放你的插件項目 mkdir my-gov-plugin cd my-gov-plugin # 使用 dsh cli 初始化插件項目 # 你會被交互式地詢問插件名稱、描述、類型等信息 dsh plugin init根據提示進行選擇例如Plugin name:gov-data-briefingDescription:A plugin to generate daily briefing reports from government data.Plugin type: 選擇Basic(基礎插件包含前后端示例) 或根據需求選擇其他模板。Language: 選擇Python或Node.js本文以Python為例。初始化完成后你會得到一個類似如下的目錄結構gov-data-briefing/ ├── plugin.yaml # 插件核心聲明文件 ├── pyproject.toml # Python項目依賴管理 (如果選Python) ├── src/ │ ├── backend/ # 后端邏輯代碼 │ │ └── main.py │ └── frontend/ # 前端UI代碼 (如果選帶UI的模板) │ ├── App.vue │ └── index.js ├── webpack.config.js # 前端構建配置 └── README.md2.3 理解核心文件plugin.yamlplugin.yaml是插件的“身份證”和“說明書”DSH完全依據這個文件來管理插件。打開它你會看到如下內容具體內容因模板而異# plugin.yaml 示例 name: gov-data-briefing version: 0.1.0 description: A plugin to generate daily briefing reports from government data. author: Your Name your.emailexample.com runtime: type: python version: 3.8 command: python src/backend/main.py # 插件啟動命令 frontend: type: vue path: src/frontend port: 3000 # 前端開發服務器端口 permissions: - network # 聲明插件需要網絡權限 configs: - key: API_ENDPOINT name: 數據API地址 type: string default: http://internal-data.gov/api required: true關鍵字段解釋runtime: 定義了插件的運行環境。command是DSH啟動插件進程時執行的命令。frontend: 如果插件有UI這里定義了前端類型、路徑和開發端口。DSH在開發模式下會代理這個端口的請求。permissions:安全關鍵項。插件默認在沙箱中運行無權訪問網絡、文件系統等。這里聲明network插件才能調用外部API如訪問政務數據接口。configs: 定義了插件可配置的參數。用戶可以在DSH插件管理界面修改這些值插件代碼中可以通過環境變量讀取。這對于區分測試和生產環境非常有用。3. 開發政務數據簡報生成插件現在我們開始為這個插件填充實際業務邏輯。假設場景是插件從內部政務數據API拉取當日關鍵指標通過AI模型或規則引擎生成一份文本簡報并提供給用戶查看和下載。3.1 編寫后端邏輯 (Python示例)編輯src/backend/main.py。一個最簡單的DSH插件后端是一個長期運行的HTTP服務器DSH會向其發送請求。# src/backend/main.py import os import json import logging from http.server import HTTPServer, BaseHTTPRequestHandler import requests from urllib.parse import urlparse, parse_qs # 配置日志方便在DSH控制臺查看 logging.basicConfig(levellogging.INFO, format%(asctime)s - %(name)s - %(levelname)s - %(message)s) logger logging.getLogger(__name__) # 從 plugin.yaml 的 configs 中讀取配置 API_ENDPOINT os.getenv(API_ENDPOINT, http://default-endpoint) API_TOKEN os.getenv(API_TOKEN, ) # 假設還有一個配置項用于認證 class PluginRequestHandler(BaseHTTPRequestHandler): def do_GET(self): 處理前端GET請求例如獲取簡報 parsed_path urlparse(self.path) if parsed_path.path /api/briefing: # 1. 調用政務數據API try: headers {Authorization: fBearer {API_TOKEN}} response requests.get(f{API_ENDPOINT}/daily-metrics, headersheaders, timeout10) response.raise_for_status() data response.json() logger.info(f成功獲取數據: {data}) except requests.exceptions.RequestException as e: logger.error(f調用數據API失敗: {e}) self.send_response(500) self.end_headers() self.wfile.write(json.dumps({error: 數據服務不可用}).encode()) return # 2. 模擬簡報生成邏輯 (實際項目中可能調用LLM) briefing_text f 政務數據簡報 ({data.get(date, N/A)}) ---------------------------- 今日新增事項: {data.get(new_cases, 0)} 件 辦結事項: {data.get(closed_cases, 0)} 件 平均處理時長: {data.get(avg_duration, 0)} 小時 重點關注區域: {, .join(data.get(hot_areas, []))} # 3. 返回結果給前端 self.send_response(200) self.send_header(Content-Type, application/json) self.end_headers() self.wfile.write(json.dumps({briefing: briefing_text, rawData: data}).encode()) else: self.send_response(404) self.end_headers() def do_POST(self): 處理前端POST請求例如觸發簡報生成并存儲 if self.path /api/generate: content_length int(self.headers[Content-Length]) post_data self.rfile.read(content_length) # ... 處理邏輯 ... self.send_response(200) self.send_header(Content-Type, application/json) self.end_headers() self.wfile.write(json.dumps({status: success}).encode()) else: self.send_response(404) self.end_headers() def log_message(self, format, *args): # 將HTTP日志也集成到我們的logger中 logger.info(%s - %s % (self.address_string(), format%args)) if __name__ __main__: server_port int(os.getenv(PORT, 7860)) # DSH會通過PORT環境變量告知監聽端口 server HTTPServer((localhost, server_port), PluginRequestHandler) logger.info(f啟動插件后端服務器端口: {server_port}) logger.info(f配置的數據API地址: {API_ENDPOINT}) server.serve_forever()關鍵點說明環境變量API_ENDPOINT和API_TOKEN是從plugin.yaml的configs注入的。這是插件配置化的關鍵。HTTP Server插件后端需要啟動一個HTTP服務器來接收DSH前端或直接調用的請求。DSH負責將外部請求路由到這個服務器的端口。日志使用logging模塊輸出日志至關重要。你可以在DSH桌面端的“插件日志”面板中查看這些日志這是最重要的調試手段。錯誤處理務必對網絡請求、數據解析等可能失敗的操作進行try-except捕獲并返回友好的錯誤信息避免插件進程崩潰。3.2 編寫前端界面 (Vue 3示例)編輯src/frontend/App.vue。前端負責與用戶交互并通過調用后端API獲取數據。!-- src/frontend/App.vue -- template div classplugin-container h1政務數據簡報生成器/h1 el-button typeprimary clickfetchBriefing :loadingloading 生成今日簡報 /el-button div v-iferror classerror-message {{ error }} /div div v-ifbriefing classbriefing-result h3生成結果/h3 pre{{ briefing }}/pre el-button sizesmall clickdownloadBriefing下載簡報文本/el-button h4原始數據/h4 pre{{ rawData }}/pre /div /div /template script setup import { ref } from vue import { ElButton, ElMessage } from element-plus // 假設使用Element Plus UI庫 const briefing ref() const rawData ref(null) const loading ref(false) const error ref() const fetchBriefing async () { loading.value true error.value briefing.value rawData.value null try { // 關鍵這里請求的是相對路徑 /api/briefing。 // 在DSH運行時這個請求會被自動代理到插件后端的本地端口。 const response await fetch(/api/briefing) if (!response.ok) { throw new Error(HTTP error! status: ${response.status}) } const data await response.json() briefing.value data.briefing rawData.value data.rawData ElMessage.success(簡報生成成功) } catch (err) { console.error(獲取簡報失敗:, err) error.value 獲取簡報失敗: ${err.message}。請檢查網絡連接或插件后端日志。 ElMessage.error(簡報生成失敗) } finally { loading.value false } } const downloadBriefing () { if (!briefing.value) return const blob new Blob([briefing.value], { type: text/plain }) const url URL.createObjectURL(blob) const a document.createElement(a) a.href url a.download 政務簡報_${new Date().toLocaleDateString()}.txt document.body.appendChild(a) a.click() document.body.removeChild(a) URL.revokeObjectURL(url) } /script style scoped .plugin-container { padding: 20px; } .error-message { color: #f56c6c; margin-top: 10px; padding: 10px; background-color: #fef0f0; border-radius: 4px; } .briefing-result { margin-top: 20px; text-align: left; } pre { white-space: pre-wrap; background-color: #f5f7fa; padding: 10px; border-radius: 4px; font-family: monospace; } /style關鍵點說明API代理前端代碼中請求/api/briefing而不是http://localhost:7860/api/briefing。這是因為在DSH開發和生產模式下它會自動創建一個反向代理將前端對/api的請求轉發到插件后端的實際端口。這解決了跨域問題是DSH插件開發的核心機制之一。UI庫示例中使用了element-plus你需要在src/frontend目錄下安裝它 (pnpm add element-plus)。你也可以使用任何其他Vue/React UI庫或純CSS。錯誤反饋通過error變量和ElMessage向用戶清晰反饋操作狀態這是良好用戶體驗的基礎。3.3 安裝依賴并本地運行前后端代碼完成后需要安裝依賴并啟動本地開發服務器進行測試。# 在插件項目根目錄下 # 1. 安裝前端依賴 (如果前端目錄有 package.json) cd src/frontend pnpm install cd ../.. # 2. 安裝Python后端依賴 (如果使用Python) # 確保在項目根目錄或 backend 目錄下有 requirements.txt # 示例 requirements.txt 內容 # requests2.28.0 pip install -r requirements.txt # 3. 啟動插件開發模式 dsh plugin dev執行dsh plugin dev后CLI 會做幾件事讀取plugin.yaml。啟動插件后端進程執行python src/backend/main.py。啟動前端開發服務器例如在http://localhost:3000。在DSH桌面端如果已安裝并運行或瀏覽器中打開一個調試窗口加載你的插件前端頁面。此時你應該能在DSH桌面端的“本地插件”列表中看到gov-data-briefing并可以點擊運行。嘗試點擊“生成今日簡報”按鈕觀察后端日志和前端響應。4. 插件調試、打包與發布到市場本地運行無誤后下一步是將其打包成可分發的格式并發布到DSH插件市場或私有倉庫以便其他用戶安裝。4.1 調試與問題排查在開發過程中你一定會遇到問題。請按以下順序排查問題現象可能原因檢查點與解決方案dsh plugin dev啟動失敗1.plugin.yaml語法錯誤。2. 依賴未安裝。3. 端口被占用。1. 使用YAML校驗器檢查plugin.yaml。2. 確保已運行pnpm install和pip install。3. 檢查frontend.port和runtime.command中指定的端口是否空閑。前端頁面空白或報錯1. 前端依賴缺失或構建失敗。2. 代理配置錯誤前端請求無法到達后端。1. 查看瀏覽器開發者工具 Console 和 Network 面板。2. 檢查dsh plugin dev啟動日志確認前端服務器是否成功啟動。3. 嘗試直接訪問前端開發服務器地址如http://localhost:3000。點擊按鈕前端報“Network Error”或“404”1. 后端服務器未啟動。2. 后端API路由與前端請求不匹配。3. 插件權限不足。1. 查看dsh plugin dev終端日志確認后端進程是否在運行且無報錯。2. 核對前端fetch(‘/api/briefing’)和后端do_GET(‘/api/briefing’)路徑是否完全一致。3. 檢查plugin.yaml中的permissions是否包含了network如果需要訪問外部API。后端日志顯示“Connection refused”訪問外部API失敗1. 網絡不通。2. 環境變量未正確注入。3. API需要認證。1. 在后端代碼中打印os.getenv(‘API_ENDPOINT’)確認值是否正確。2. 在DSH插件管理界面檢查該插件的配置項是否已填寫。3. 使用curl或requests在插件環境外手動測試API連通性。插件在DSH中運行正常但接入門戶后無法使用1. 門戶與DSH的跨域問題。2. 門戶傳遞的認證信息DSH未識別。3. DSH服務地址配置錯誤。1. 這是集成階段最常見問題詳見第5節。最重要的調試工具是日志。始終確保你的后端代碼有充分的日志輸出并在DSH桌面端的“插件日志”面板中仔細查看。4.2 打包插件當插件開發測試完成需要打包成一個.dsh-plugin文件本質上是一個zip壓縮包便于分發和安裝。# 在插件項目根目錄執行打包命令 dsh plugin pack該命令會運行前端構建如果存在生成靜態文件到dist目錄。將plugin.yaml、構建后的前端文件、后端源代碼或根據配置排除某些文件一起打包。在項目根目錄生成一個類似gov-data-briefing-0.1.0.dsh-plugin的文件。4.3 發布到插件市場你可以將插件發布到官方市場或私有市場。# 1. 登錄到DSH插件市場 (需要賬戶) dsh plugin login # 2. 發布插件 dsh plugin publish ./gov-data-briefing-0.1.0.dsh-plugin發布前請務必更新plugin.yaml中的version字段。編寫清晰的README.md說明插件功能、配置方法和注意事項。在插件市場管理后臺為插件設置合適的分類、標簽和截圖。對于政務內部系統你更可能需要搭建私有插件市場。這通常涉及部署一個符合DSH插件市場協議的服務器并將DSH桌面端的市場地址指向它。具體步驟請參考DSH官方文檔中關于私有部署的部分。5. 將插件集成到政務門戶這是最后也是最關鍵的一步讓插件在門戶系統中可用。5.1 集成模式選擇模式描述優點缺點適用場景Iframe 嵌入在門戶頁面中通過iframe標簽嵌入 DSH 桌面端中該插件的專屬URL。實現簡單隔離性好插件更新獨立于門戶。存在跨域限制需要處理登錄態傳遞UI風格可能與門戶不統一??焖偌蓪I一致性要求不高的內部工具。API 直調門戶后端直接調用已部署的DSH插件提供的API需插件暴露API。性能好門戶可完全控制交互邏輯。需要插件設計為純后端服務門戶需自己開發前端界面。插件核心是數據處理能力無需復雜UI。微前端架構將插件前端構建為微前端模塊門戶通過微前端框架加載。UI融合度最高體驗最佳。技術復雜度高需要改造門戶和插件前端。大型、長期的項目對用戶體驗要求極高。本文以最常用的Iframe 嵌入為例。5.2 Iframe 嵌入實戰步驟前提DSH桌面端或服務已部署在內部網絡地址為https://dsh.internal.gov。你的插件gov-data-briefing已安裝并配置好。步驟一在門戶頁面添加Iframe!-- 在門戶的某個.vue/.jsx/.html文件中 -- div classtool-card h3每日數據簡報/h3 iframe refpluginFrame :srcpluginUrl width100% height600px frameborder0 allowclipboard-write; loadonIframeLoad /iframe div v-ifloading加載插件中.../div /div步驟二處理認證與URL生成門戶用戶登錄后會有一個身份令牌如JWT。需要將這個令牌安全地傳遞給DSH。// 在門戶前端邏輯中 import { getCurrentUserToken } from /utils/auth; // 假設有獲取用戶Token的方法 export default { data() { return { pluginUrl: , loading: true }; }, mounted() { this.initPluginFrame(); }, methods: { async initPluginFrame() { const userToken getCurrentUserToken(); // 構造DSH插件URL。格式通常為DSH地址 /plugins/ 插件ID /?token... // 具體格式需參考DSH的嵌入文檔或API。 this.pluginUrl https://dsh.internal.gov/plugins/gov-data-briefing/?embedtruetoken${encodeURIComponent(userToken)}; }, onIframeLoad() { this.loading false; // 可以在這里建立與iframe內插件的通信例如使用 postMessage // this.$refs.pluginFrame.contentWindow.postMessage({ type: init }, *); } } };關鍵安全考慮Token傳遞切勿使用URL參數傳遞高敏感Token除非DSH和門戶在同一頂級域名下并使用安全的SameSite Cookie。更安全的方式是門戶后端與DSH后端通過OAuth 2.0等協議進行服務間認證為每個會話生成一個短期有效的嵌入令牌。同源策略如果dsh.internal.gov與門戶不同源iframe通信會受到限制。需要DSH服務端設置正確的CORS頭部 (Access-Control-Allow-Origin) 和X-Frame-Options。步驟三DSH服務端配置確保DSH服務端或網關能夠驗證門戶傳來的Token并識別用戶身份從而在插件運行時注入正確的用戶上下文和權限。這通常需要在DSH的部署配置中啟用并配置相應的認證中間件。5.3 集成后常見問題排查問題排查方向Iframe 顯示“無法連接”或空白1. 檢查pluginUrl是否正確能否在瀏覽器單獨訪問。2. 檢查DSH服務是否健康運行。3. 檢查網絡策略門戶頁面能否訪問DSH的域名和端口。Iframe 顯示“未授權”或“請登錄”1. Token未傳遞或已過期。2. DSH服務端未正確配置該Token的驗證方式。3. 該用戶無權訪問此插件需在DSH中配置插件權限。插件功能異常如無法調用API1. 在DSH桌面端直接運行插件是否正常如果正常問題出在集成環境。2. 檢查插件在集成環境下運行時的日志看環境變量如API_ENDPOINT是否正確注入。3. 可能是集成環境與開發環境的網絡策略不同導致插件無法訪問外部政務數據API。6. 生產環境部署與最佳實踐將插件從開發環境推向生產環境需要額外的考量。6.1 配置管理分離配置所有環境相關的配置API地址、密鑰、數據庫連接必須通過plugin.yaml的configs定義并通過環境變量注入。絕對不要硬編碼在代碼中。使用密鑰管理對于密碼、Token等敏感信息應使用DSH提供的密鑰管理功能或對接外部密鑰管理服務如HashiCorp Vault而不是以明文存儲在配置界面。6.2 安全性加固權限最小化在plugin.yaml的permissions中只聲明插件運行所必需的最小權限。例如不需要文件讀寫就不要聲明filesystem。輸入驗證與消毒插件后端必須對所有輸入包括來自前端的參數和外部API的響應進行嚴格的驗證和消毒防止注入攻擊。依賴掃描定期使用pip-audit,npm audit等工具掃描項目依賴的安全漏洞并及時更新。6.3 可觀測性與監控結構化日志確保插件輸出結構化的日志JSON格式便于被ELK、Loki等日志系統采集和分析。在日志中記錄請求ID、用戶ID、關鍵操作步驟和錯誤詳情。健康檢查端點為插件后端添加一個/health端點返回服務狀態。這便于容器編排平臺如Kubernetes或DSH本身進行健康檢查。指標暴露考慮使用Prometheus客戶端庫暴露插件的關鍵指標如請求數、延遲、錯誤率方便監控。6.4 版本與更新語義化版本嚴格遵守語義化版本控制SemVer。plugin.yaml中的version字段在修復Bug時遞增修訂號在新增向后兼容的功能時遞增次版本號在做出不兼容的變更時遞增主版本號。變更日志維護CHANGELOG.md清晰記錄每個版本的變更內容特別是破壞性變更和配置項變更。向后兼容更新插件時盡量保持API的向后兼容性。如果必須做出破壞性變更應提供遷移指南并在插件市場中明確標注。通過以上步驟你不僅完成了一個DSH插件的開發更掌握了一套將內部能力快速產品化并集成到現有系統的工程方法。這種插件化思維能夠極大地提升團隊交付工具的效率和標準化程度。