
ChatDev 2.0 附件與工件 API 詳解文件上傳、實時工件事件與會話歸檔下載【免費下載鏈接】ChatDevChatDev 2.0: Dev All through LLM-powered Multi-Agent Collaboration項目地址: https://gitcode.com/GitHub_Trending/ch/ChatDev本文基于 ChatDev 2.0 倉庫中的 附件與工件 API 指南系統(tǒng)講解直接對接后端 REST/WS 端點時如何處理“附件Attachment”與“工件Artifact”如何上傳/列舉文件、如何在執(zhí)行請求中引用附件、如何實時監(jiān)聽節(jié)點產(chǎn)出的文件事件、如何按模式下載工件并打包整個會話以及文件生命周期與大小/安全策略。讀完后你可以為自有前端、CLI 或自動化流水線構(gòu)建完整的附件接入層并能在排障時準確定位 413/404、事件缺失等常見問題。1. 核心概念A(yù)ttachment 與 Artifact 的分工ChatDev 2.0 中文件能力被拆成兩個層次Attachment附件Session 生命周期內(nèi)可上傳、下載、由節(jié)點注冊的文件。它落到磁盤并有attachments_manifest.json清單跟蹤元數(shù)據(jù)ID、文件名、MIME、大小、來源等。Artifact工件附件發(fā)生變化時發(fā)出的事件抽象。節(jié)點在代碼工作區(qū)里新建/修改文件后系統(tǒng)生成artifact_created事件客戶端可通過 WebSocket 或 REST 長輪詢實時訂閱。這個分層從源碼結(jié)構(gòu)看非常清晰存儲層是 AttachmentStore以文件系統(tǒng)目錄為根維護記錄字典、哈希索引與 manifest 文件會話級服務(wù) AttachmentService 負責(zé)按session_id組裝路徑、保存上傳、清理策略事件側(cè)由 ArtifactEvent 與 ArtifactEventQueue 提供帶游標的有界隊列節(jié)點產(chǎn)出文件則由 WorkspaceArtifactHook 掃描工作區(qū)并注冊工件。2. 上傳與列舉附件2.1 上傳文件POST /api/uploads/{session_id}請求頭Content-Type: multipart/form-dataForm 字段file單個文件服務(wù)端路由見 uploads.py先通過ensure_known_session校驗會話再調(diào)用manager.attachment_service.save_upload_file(session_id, file)落盤。文檔給出的響應(yīng)示例{ attachment_id: att_bxabcd, name: spec.md, mime: text/markdown, size: 12345 }需要注意一個實現(xiàn)細節(jié)當(dāng)前倉庫的路由實際返回的字段名為mime_type而非mime見 uploads.py 返回體。對接時請以實際響應(yīng)字段為準。2.2 上傳后的落盤位置與清單AttachmentService._session_attachments_path 表明文件最終保存到WareHouse/session_session_id/code_workspace/attachments/其中WARE_HOUSE_DIR默認就是WareHouse見 settings.py。每個附件注冊為一條記錄后AttachmentStore會持久化到該目錄下的attachments_manifest.jsonmanifest 讀寫邏輯。上傳時的處理流程在 save_upload_file先寫入臨時目錄逐塊1MB拷貝上傳內(nèi)容用mimetypes猜測 MIME優(yōu)先使用upload.content_type調(diào)用store.register_file(...)并通過MessageBlockType.from_mime_type(mime_type)把類型歸入 image/audio/video/file 四類供后續(xù)消息塊渲染extra中記錄source: user_upload、origin: web_upload、session_id。register_file本身還有值得了解的參數(shù)見 AttachmentStore.register_filekind、display_name、mime_type、copy_file是否拷貝進存儲目錄、persist是否寫入 manifest、deduplicate基于 SHA-256 哈希去重。哈希索引_hash_index讓相同內(nèi)容的文件可以復(fù)用已有記錄。2.3 列舉附件GET /api/uploads/{session_id}返回該會話所有附件的元數(shù)據(jù)ID、文件名、MIME、大小、來源。實現(xiàn)非常直接list_attachments 返回{attachments: manifest}即AttachmentStore.export_manifest()的輸出export_manifest鍵為attachment_id值為完整記錄字典ref、kind、description、extra。2.4 在執(zhí)行請求中引用附件POST /api/workflow/execute請求體可攜帶attachments: [att_xxx]請求模型見 WorkflowRequest路由將attachments透傳給manager.workflow_run_service.start_workflow(...)見 execute.py。WebSockethuman_input消息同樣支持attachments數(shù)組見 message_handler.py。文檔提示調(diào)用 execute 時仍需提供task_prompt。不過從源碼結(jié)構(gòu)看同步執(zhí)行入口對這一約束更寬松execute_sync.py 只在task_prompt與attachments同時為空時才拋Task prompt cannot be empty即“僅上傳文件”的場景可以通過同步接口發(fā)起。附件如何進入執(zhí)行上下文build_attachment_blocks 會把每個attachment_id查成記錄必要時ingest_record拷貝到目標存儲跨存儲根目錄時才真正拷貝文件最終轉(zhuǎn)換為MessageBlock隨任務(wù)輸入下發(fā)。3. 工件事件與下載3.1 實時事件GET /api/sessions/{session_id}/artifact-events該接口實現(xiàn)為長輪詢見 poll_artifact_events。查詢參數(shù)及默認值如下以源碼Query約束為準參數(shù)說明默認/約束after序列號游標返回該游標之后的事件可選 0wait_seconds無事件時阻塞等待時長默認25.0范圍0~60include_mimeMIME 前綴白名單逗號分隔可選include_ext擴展名白名單逗號分隔可帶或不帶點可選max_size只返回不超過該字節(jié)數(shù)的事件可選 0limit單次返回事件數(shù)默認25范圍1~100響應(yīng)包含events[]、next_cursor、has_more、timed_out四個字段其中has_more由queue.last_sequence (next_cursor or 0)判定timed_out表示本輪等待超時仍無匹配事件。過濾邏輯在 ArtifactEvent.matches_filterinclude_mime支持精確匹配或前綴匹配如image/include_ext歸一化后按文件后綴匹配max_size做大小上限過濾。隊列本身是線程安全的有界隊列ArtifactEventQueue默認最多保留 2000 條事件超出后丟棄最舊事件并推進_min_sequence因此after游標若指向過舊的序列號會被鉗制到仍在窗口內(nèi)的位置。wait_for_events通過threading.Condition阻塞等待新事件到達路由側(cè)用asyncio.to_thread包裝以避免阻塞事件循環(huán)。3.2 事件樣例每條事件的核心字段to_dict輸出見 ArtifactEvent.to_dict{ artifact_id: art_123, attachment_id: att_456, node_id: python_runner, path: code_workspace/result.json, size: 2048, mime: application/json, hash: sha256:..., timestamp: 1732699900 }文檔中的樣例是示意寫法當(dāng)前源碼的實際字段還包括event_id、sequence、file_name、relative_path、workspace_path、mime_type、sha256、data_uri、created_at、change_typecreated/updated/deleted與extra。3.3 WebSocket 鏡像artifact_created同一批工件事件也會通過 WebSocket 下發(fā)消息類型為artifact_created見 artifact_dispatcher.py。因此儀表盤類客戶端可以直接訂閱 WS 實現(xiàn)實時刷新無需輪詢 REST。3.4 事件從哪里來WorkspaceArtifactHook節(jié)點運行期間WorkspaceArtifactHook 負責(zé)把“節(jié)點改了哪些文件”翻譯成工件事件只對python、agent類型節(jié)點生效node_types默認值before_node對工作區(qū)做 SHA-256 快照after_node成功后對比快照找出新增/變更/刪除的文件每個變更文件調(diào)用attachment_store.register_file(copy_fileFalse, persistTrue)注冊為附件extra中記錄node_id、relative_path、hook: workspace_scan見 _register_artifact默認排除attachments、__pycache__目錄掃描上限為 500 個文件或 500MB 字節(jié)超出會截斷并記錄 warning構(gòu)造函數(shù)參數(shù)。這解釋了文檔 FAQ 中“附件未在 Python 節(jié)點可見”的排查方向之一工作區(qū)掃描與附件目錄共享code_workspace/且掃描本身排除attachments目錄。3.5 下載單個工件GET /api/sessions/{session_id}/artifacts/{artifact_id}實現(xiàn)見 get_artifact。查詢參數(shù)modemeta默認或stream正則約束^(meta|stream)$downloadtrue|false影響Content-Disposition取attachment還是inline。兩種模式的實際行為modestream讀取ref.local_path返回StreamingResponse流式下載Content-Type取mime_type缺省application/octet-stream。文件不存在或無本地路徑時返回 404Artifact content unavailable/Artifact file missing。modemeta返回元數(shù)據(jù) JSON包含artifact_id、name、mime_type、size、sha256、data_uri、local_path、extra。當(dāng)ref未預(yù)置data_uri且文件不超過 20MB路由常量MAX_FILE_SIZE 20 * 1024 * 1024時服務(wù)端會現(xiàn)場用 encode_file_to_data_uri 編碼內(nèi)聯(lián) base64——這就是文檔所說“小文件可返回data_uri若服務(wù)器啟用”的實現(xiàn)來源。另外注意路由中store.get(artifact_id)查詢的是附件存儲事件里的attachment_id才是下載端點的鍵事件to_dict中artifact_id字段與文檔命名略有出入對接時以attachment_id為準更穩(wěn)妥。3.6 打包下載整個會話GET /api/sessions/{session_id}/download實現(xiàn)見 download_session嚴格校驗session_id僅含字母/數(shù)字/_-正則^[a-zA-Z0-9_-]$不合法時記錄INVALID_SESSION_ID_FORMAT安全事件并返回 400定位WareHouse/session_session_id/目錄不存在返回 404用shutil.make_archive打包為 zip通過FileResponse返回Content-Disposition: attachment; filenamesession_xxx.zip響應(yīng)完成后由BackgroundTask清理臨時 zip 文件。打包下載不會刪除原文件歸檔與清理需自行安排定時任務(wù)。4. 文件生命周期結(jié)合文檔與源碼一個附件從上傳到可下載的完整鏈路是上傳階段POST /api/uploads/{session_id}寫入code_workspace/attachments/manifest 記錄ref含本地路徑、kind、description、extra含source、workspace_path等由調(diào)用方寫入的字段。節(jié)點注冊Python/Agent 節(jié)點可通過AttachmentStore.register_file()把工作區(qū)文件注冊為附件支持deduplicate哈希去重WorkspaceArtifactHook自動掃描節(jié)點前后差異并同步到事件流。保留策略默認保留所有附件以便運行結(jié)束后下載。AttachmentService 構(gòu)造時 讀取環(huán)境變量MAC_AUTO_CLEAN_ATTACHMENTS1/true/yes視為開啟開啟后cleanup_session會在會話結(jié)束時shutil.rmtree刪除attachments/目錄cleanup_session關(guān)閉時僅打日志保留文件。打包下載zip 下載只讀取不刪除需要額外的 cron/job 做歸檔或清空。5. 大小與安全建議大小限制后端上傳路徑本身未做硬編碼上限save_upload_file逐塊讀取但未限制總量應(yīng)在反向代理層設(shè)置client_max_body_size/max_request_body_size或在自有分支的AttachmentService.save_upload_file中增加校驗。工件meta模式的data_uri內(nèi)聯(lián)則有 20MB 代碼上限見 artifacts.py。文件類型MIME 推斷決定MessageBlockTypeimage/audio/video/file見 save_upload_file客戶端可用include_mime過濾事件流。病毒/敏感數(shù)據(jù)建議客戶端上傳前預(yù)掃描也可在保存后觸發(fā)掃描服務(wù)倉庫未內(nèi)置掃描器。權(quán)限附件 API 依賴session_id定位資源。會話 ID 字符集校驗可防路徑穿越見 sessions.py 的正則與安全日志但生產(chǎn)部署仍應(yīng)在代理層或 JWT 內(nèi)部校驗調(diào)用者身份防止越權(quán)下載他人會話的制品。6. 常見問題排查FAQ問題排查步驟上傳 413 Payload Too Large調(diào)高反向代理或 FastAPI 的client_max_size確認磁盤配額下載鏈接 404檢查session_id拼寫僅允許字母/數(shù)字/_-確認會話目錄未被清理download_session 對目錄不存在直接返回 404工件事件缺失確認 WebSocket 已連接或用artifact-events長輪詢并攜帶after游標重拉注意事件隊列僅有 2000 條滑動窗口附件未在 Python 節(jié)點可見檢查code_workspace/attachments/是否被MAC_AUTO_CLEAN_ATTACHMENTS清理以及 Python 執(zhí)行上下文中的工作區(qū)根路徑python_workspace_root是否正確7. 客戶端接入模式Web UI優(yōu)先訂閱 WebSocket 的artifact_created或退化為artifact-events長輪詢wait_seconds最大 60 秒實時刷新附件列表節(jié)點成功后提供“下載全部”按鈕直接請求/api/sessions/{session_id}/download。CLI/自動化運行結(jié)束后調(diào)用/download拉取整包 zip若只需部分文件先用artifact-events配合include_ext如csv,png與max_size精準過濾再逐個以modestreamdownloadtrue下載。測試環(huán)境用腳本模擬“上傳 → execute 引用 → 輪詢事件 → 下載”全流程提前驗證反向代理的 body size 限制與 CORS 配置。8. 延伸閱讀英文原文Attachment Artifact API Guide中文版附件與工件 API 指南核心實現(xiàn)AttachmentStore、AttachmentService、上傳路由、工件路由、會話下載路由、事件隊列、工作區(qū)鉤子【免費下載鏈接】ChatDevChatDev 2.0: Dev All through LLM-powered Multi-Agent Collaboration項目地址: https://gitcode.com/GitHub_Trending/ch/ChatDev創(chuàng)作聲明:本文部分內(nèi)容由AI輔助生成(AIGC),僅供參考