ARTICLE DETAIL

建站实战干货

来自一线的建站与推广经验沉淀,每一条都经过真实交付验证。

ChatDev 2.0 附件与工件 API 详解:文件上传、实时工件事件与会话归档下载

2026/9/6 16:42:18 拓冰建站 浏览量
ChatDev 2.0 附件与工件 API 详解:文件上传、实时工件事件与会话归档下载 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 指南系统讲解直接对接后端 REST/WS 端点时如何处理“附件Attachment”与“工件Artifact”如何上传/列举文件、如何在执行请求中引用附件、如何实时监听节点产出的文件事件、如何按模式下载工件并打包整个会话以及文件生命周期与大小/安全策略。读完后你可以为自有前端、CLI 或自动化流水线构建完整的附件接入层并能在排障时准确定位 413/404、事件缺失等常见问题。1. 核心概念Attachment 与 Artifact 的分工ChatDev 2.0 中文件能力被拆成两个层次Attachment附件Session 生命周期内可上传、下载、由节点注册的文件。它落到磁盘并有attachments_manifest.json清单跟踪元数据ID、文件名、MIME、大小、来源等。Artifact工件附件发生变化时发出的事件抽象。节点在代码工作区里新建/修改文件后系统生成artifact_created事件客户端可通过 WebSocket 或 REST 长轮询实时订阅。这个分层从源码结构看非常清晰存储层是 AttachmentStore以文件系统目录为根维护记录字典、哈希索引与 manifest 文件会话级服务 AttachmentService 负责按session_id组装路径、保存上传、清理策略事件侧由 ArtifactEvent 与 ArtifactEventQueue 提供带游标的有界队列节点产出文件则由 WorkspaceArtifactHook 扫描工作区并注册工件。2. 上传与列举附件2.1 上传文件POST /api/uploads/{session_id}请求头Content-Type: multipart/form-dataForm 字段file单个文件服务端路由见 uploads.py先通过ensure_known_session校验会话再调用manager.attachment_service.save_upload_file(session_id, file)落盘。文档给出的响应示例{ attachment_id: att_bxabcd, name: spec.md, mime: text/markdown, size: 12345 }需要注意一个实现细节当前仓库的路由实际返回的字段名为mime_type而非mime见 uploads.py 返回体。对接时请以实际响应字段为准。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拷贝上传内容用mimetypes猜测 MIME优先使用upload.content_type调用store.register_file(...)并通过MessageBlockType.from_mime_type(mime_type)把类型归入 image/audio/video/file 四类供后续消息块渲染extra中记录source: user_upload、origin: web_upload、session_id。register_file本身还有值得了解的参数见 AttachmentStore.register_filekind、display_name、mime_type、copy_file是否拷贝进存储目录、persist是否写入 manifest、deduplicate基于 SHA-256 哈希去重。哈希索引_hash_index让相同内容的文件可以复用已有记录。2.3 列举附件GET /api/uploads/{session_id}返回该会话所有附件的元数据ID、文件名、MIME、大小、来源。实现非常直接list_attachments 返回{attachments: manifest}即AttachmentStore.export_manifest()的输出export_manifest键为attachment_id值为完整记录字典ref、kind、description、extra。2.4 在执行请求中引用附件POST /api/workflow/execute请求体可携带attachments: [att_xxx]请求模型见 WorkflowRequest路由将attachments透传给manager.workflow_run_service.start_workflow(...)见 execute.py。WebSockethuman_input消息同样支持attachments数组见 message_handler.py。文档提示调用 execute 时仍需提供task_prompt。不过从源码结构看同步执行入口对这一约束更宽松execute_sync.py 只在task_prompt与attachments同时为空时才抛Task prompt cannot be empty即“仅上传文件”的场景可以通过同步接口发起。附件如何进入执行上下文build_attachment_blocks 会把每个attachment_id查成记录必要时ingest_record拷贝到目标存储跨存储根目录时才真正拷贝文件最终转换为MessageBlock随任务输入下发。3. 工件事件与下载3.1 实时事件GET /api/sessions/{session_id}/artifact-events该接口实现为长轮询见 poll_artifact_events。查询参数及默认值如下以源码Query约束为准参数说明默认/约束after序列号游标返回该游标之后的事件可选 0wait_seconds无事件时阻塞等待时长默认25.0范围0~60include_mimeMIME 前缀白名单逗号分隔可选include_ext扩展名白名单逗号分隔可带或不带点可选max_size只返回不超过该字节数的事件可选 0limit单次返回事件数默认25范围1~100响应包含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游标若指向过旧的序列号会被钳制到仍在窗口内的位置。wait_for_events通过threading.Condition阻塞等待新事件到达路由侧用asyncio.to_thread包装以避免阻塞事件循环。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 }文档中的样例是示意写法当前源码的实际字段还包括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 下发消息类型为artifact_created见 artifact_dispatcher.py。因此仪表盘类客户端可以直接订阅 WS 实现实时刷新无需轮询 REST。3.4 事件从哪里来WorkspaceArtifactHook节点运行期间WorkspaceArtifactHook 负责把“节点改了哪些文件”翻译成工件事件只对python、agent类型节点生效node_types默认值before_node对工作区做 SHA-256 快照after_node成功后对比快照找出新增/变更/删除的文件每个变更文件调用attachment_store.register_file(copy_fileFalse, persistTrue)注册为附件extra中记录node_id、relative_path、hook: workspace_scan见 _register_artifact默认排除attachments、__pycache__目录扫描上限为 500 个文件或 500MB 字节超出会截断并记录 warning构造函数参数。这解释了文档 FAQ 中“附件未在 Python 节点可见”的排查方向之一工作区扫描与附件目录共享code_workspace/且扫描本身排除attachments目录。3.5 下载单个工件GET /api/sessions/{session_id}/artifacts/{artifact_id}实现见 get_artifact。查询参数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返回元数据 JSON包含artifact_id、name、mime_type、size、sha256、data_uri、local_path、extra。当ref未预置data_uri且文件不超过 20MB路由常量MAX_FILE_SIZE 20 * 1024 * 1024时服务端会现场用 encode_file_to_data_uri 编码内联 base64——这就是文档所说“小文件可返回data_uri若服务器启用”的实现来源。另外注意路由中store.get(artifact_id)查询的是附件存储事件里的attachment_id才是下载端点的键事件to_dict中artifact_id字段与文档命名略有出入对接时以attachment_id为准更稳妥。3.6 打包下载整个会话GET /api/sessions/{session_id}/download实现见 download_session严格校验session_id仅含字母/数字/_-正则^[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响应完成后由BackgroundTask清理临时 zip 文件。打包下载不会删除原文件归档与清理需自行安排定时任务。4. 文件生命周期结合文档与源码一个附件从上传到可下载的完整链路是上传阶段POST /api/uploads/{session_id}写入code_workspace/attachments/manifest 记录ref含本地路径、kind、description、extra含source、workspace_path等由调用方写入的字段。节点注册Python/Agent 节点可通过AttachmentStore.register_file()把工作区文件注册为附件支持deduplicate哈希去重WorkspaceArtifactHook自动扫描节点前后差异并同步到事件流。保留策略默认保留所有附件以便运行结束后下载。AttachmentService 构造时 读取环境变量MAC_AUTO_CLEAN_ATTACHMENTS1/true/yes视为开启开启后cleanup_session会在会话结束时shutil.rmtree删除attachments/目录cleanup_session关闭时仅打日志保留文件。打包下载zip 下载只读取不删除需要额外的 cron/job 做归档或清空。5. 大小与安全建议大小限制后端上传路径本身未做硬编码上限save_upload_file逐块读取但未限制总量应在反向代理层设置client_max_body_size/max_request_body_size或在自有分支的AttachmentService.save_upload_file中增加校验。工件meta模式的data_uri内联则有 20MB 代码上限见 artifacts.py。文件类型MIME 推断决定MessageBlockTypeimage/audio/video/file见 save_upload_file客户端可用include_mime过滤事件流。病毒/敏感数据建议客户端上传前预扫描也可在保存后触发扫描服务仓库未内置扫描器。权限附件 API 依赖session_id定位资源。会话 ID 字符集校验可防路径穿越见 sessions.py 的正则与安全日志但生产部署仍应在代理层或 JWT 内部校验调用者身份防止越权下载他人会话的制品。6. 常见问题排查FAQ问题排查步骤上传 413 Payload Too Large调高反向代理或 FastAPI 的client_max_size确认磁盘配额下载链接 404检查session_id拼写仅允许字母/数字/_-确认会话目录未被清理download_session 对目录不存在直接返回 404工件事件缺失确认 WebSocket 已连接或用artifact-events长轮询并携带after游标重拉注意事件队列仅有 2000 条滑动窗口附件未在 Python 节点可见检查code_workspace/attachments/是否被MAC_AUTO_CLEAN_ATTACHMENTS清理以及 Python 执行上下文中的工作区根路径python_workspace_root是否正确7. 客户端接入模式Web UI优先订阅 WebSocket 的artifact_created或退化为artifact-events长轮询wait_seconds最大 60 秒实时刷新附件列表节点成功后提供“下载全部”按钮直接请求/api/sessions/{session_id}/download。CLI/自动化运行结束后调用/download拉取整包 zip若只需部分文件先用artifact-events配合include_ext如csv,png与max_size精准过滤再逐个以modestreamdownloadtrue下载。测试环境用脚本模拟“上传 → execute 引用 → 轮询事件 → 下载”全流程提前验证反向代理的 body size 限制与 CORS 配置。8. 延伸阅读英文原文Attachment Artifact API Guide中文版附件与工件 API 指南核心实现AttachmentStore、AttachmentService、上传路由、工件路由、会话下载路由、事件队列、工作区钩子【免费下载链接】ChatDevChatDev 2.0: Dev All through LLM-powered Multi-Agent Collaboration项目地址: https://gitcode.com/GitHub_Trending/ch/ChatDev创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考