
后端前端AI 技能AI 插件【免费下载链接】skillhubopenJiuwen 生态的 Skill 托管与分发开源方案支持自建与可选 ClawHub 兼容。项目地址https://gitcode.com/openJiuwen/skillhub点击查看免费下载本文是 openJiuwen SkillHub开源 Skill 托管与分发方案中在线体验PlaygroundAPI的完整技术指南。该 API 由 marketplace 控制面对外暴露并透明转发到独立部署的 skill-runner 服务让用户无需本地安装即可在浏览器中直接试用已通过审核的 Skill。读完本文你将掌握在线体验的全部端点、鉴权与配额模型、SSE 事件协议、底层代理调用链以及 marketplace 与 skill-runner 两侧的关键配置项能够据此进行二次开发、接口联调与生产排障。一、总体架构两层服务、一条链路在线体验 API 并非由单一服务实现而是由两个进程协同完成marketplace 控制面对外暴露/api/v1/playground/*路由负责鉴权、每日配额、并发限制、审核状态检查与 Skill 内容注入然后把请求反向代理到 skill-runner。skill-runner 服务独立部署在 K8s 中的会话编排服务负责会话生命周期创建/发消息/SSE 流/结束与运行时隔离本身不执行 Skill 逻辑——执行委托给可插拔的沙箱执行器。二者的接线方式见 路由注册入口if settings.playground_enabled: from plugins_market.core.playground_state import get_playground_state_store from plugins_market.routers.playground_proxy import router as playground_proxy_router get_playground_state_store() app.include_router(playground_proxy_router, prefix/api/v1)代理目标由settings.skill_runner_url决定默认http://127.0.0.1:8900K8s 部署通常为集群内 Service 地址。前端无需任何 URL 切换命中的始终是/api/v1/playground/*真正的会话编排在 K8s 中独立部署的 skill-runner 服务完成。重要前置条件服务端必须配置PLAYGROUND_ENABLEDtrue否则/api/v1/playground/*路由不注册所有请求返回 404前端「试用」按钮也不显示。二、端点速查以下为在线体验对外暴露的全部端点能力概览以当前部署版本路由实现为准方法路径说明鉴权POST/api/v1/playground/sessions创建体验会话BearerPOST/api/v1/playground/sessions/{session_id}/messages发送消息BearerGET/api/v1/playground/sessions/{session_id}/stream?pt{proxy_token}SSE 流式接收输出会话能力令牌ptPOST/api/v1/playground/sessions/{session_id}/files上传临时文件BearerDELETE/api/v1/playground/sessions/{session_id}结束会话Bearer除上述端点外代理还暴露了两个辅助端点用于配额展示与页面卸载时的会话清理方法路径说明鉴权GET/api/v1/playground/quota查询当前用户今日配额使用情况BearerPOST/api/v1/playground/sessions/{session_id}/beaconsendBeacon入口逻辑同 DELETE会话能力令牌pt为什么 SSE 必须用pt令牌proxy_tokenpt由创建会话接口返回。浏览器EventSource无法设置Authorization请求头因此 SSE 连接必须通过pt查询参数携带该令牌。同时sendBeacon同样无法携带自定义请求头/beacon入口也依赖?pt完成鉴权。该令牌由secrets.token_urlsafe(24)生成校验使用secrets.compare_digest进行常量时间比较防止时序侧信道见 playground_proxy.py。另外值得注意代理在转发时会主动剥离查询参数中的pt见_forward中的fwd_params过滤确保能力令牌不会外泄给上游 skill-runner。三、核心能力说明能力说明创建会话创建一次在线体验会话并注入审核通过的 Skill 内容发送消息向已有会话发送用户输入SSE 流接收模型输出、推理过程、工具调用和最终答复上传文件向当前会话上传临时输入文件结束会话主动结束会话并释放运行资源四、创建会话鉴权、并发、配额与内容注入创建会话是流程最复杂的端点。从 create_session 实现 可以看到完整的处理链鉴权 → 剥离客户端执行内容 → 注入 Skill 内容 → 注入 user_id → 并发检查 → 每日配额扣减 → 转发 → 登记会话并下发令牌。4.1 请求体核心字段skill-runner 侧 CreateSessionRequest 定义了创建会话的请求结构字段类型说明skill_idstr要体验的 Skill 资产 IDversionstr版本号默认latest取最新版本skill_typestrordinary单 DeepAgent/swarm多角色 TeamAgent默认ordinarysystem_promptstr系统提示词为空时 skill-runner 用skill_md workflow_md roles自行组装skill_mdstrSKILL.md文本workflow_mdstrworkflow.md文本可选rolesdictSwarmSkill 角色{角色名: 角色文档文本}team_modestrSwarmSkill 团队模式自动推导显式hybrid/default/predefinedpackage_bytes_b64strZIP 包 base64由 marketplace 代理编码user_idstr由 marketplace 注入的调用方用户 ID用于 LLM 代理侧 token 计量前端实际提交的字段更精简。见 playground.tsexport async function createPlaygroundSession( skillId: string, version: string, skillType: ordinary | swarm ordinary, ): PromisePlaygroundSession { const resp await apiClient.postPlaygroundSession(API_ENDPOINTS.PLAYGROUND.sessions, { skill_id: skillId, version, skill_type: skillType, }) return resp.data }4.2 执行内容必须由 marketplace 注入安全底线客户端不应直接提交skill_md、system_prompt等执行内容。这是在线体验最重要的安全约束。代理定义了_CLIENT_FORBIDDEN_FIELDSskill_md、workflow_md、roles、system_prompt、package_bytes_b64、team_mode非管理员请求体若自带这些字段会被直接剥离并记日志见 playground_proxy.py。否则客户端自行携带skill_md/system_prompt就能绕过审核执行未过审内容。marketplace 的注入链路_inject_skill_content分为三步查库取资产按skill_id查MarketAssetRepository按version或latest查MarketAssetVersionRepository审核状态检查版本moderation_status必须为APPROVED或空否则返回 403skill_not_approved未过审 Skill 无法在 Playground 执行见 playground_proxy.pyZIP 下载与解析通过 S3 存储下载归档解析出skill_md、workflow_md、roles并把team_mode按需透传仅显式声明时透传空值交给 skill-runner 自动推导老 Skill 零影响ZIP 不超过MAX_FILE_SIZE时以package_bytes_b64一并注入超限则只带文本字段。其中 ZIP 解析_parse_skill_zip使用了仓库的 zip_utils 安全工具链validate_zip_safety做元数据预检快速拒绝异常包DecompressCounter跨成员累计解压字节、超限即中止且只读取skill.md、workflow.md、roles/*.md三类文本成员其余成员不读以省解压开销。4.3 team_mode 推导规则team_mode的推导与 TeamAgentSpec 的自动推导对齐见 playground_proxy.pyfrontmatter 显式声明team_modedefault/predefined/hybrid→最高优先级尊重声明有roles/*.md且任意 role 的count为列表 →hybrid保留预定义名单同时允许spawn_member有roles/*.md但无 count 范围 → 空串skill-runner 侧返回predefined锁定名单无roles/*.md→ 空串skill-runner 侧返回None框架自动推导default。4.4 响应与令牌下发创建成功后代理登记会话归属/路由信息并下发能力令牌。关键点见 _register_created_session从响应中读取session_id剥除instance_addr字段多实例下 skill-runner 回带的实例基址用于粘性路由但绝不外泄给浏览器生成proxy_token写入PlaygroundSessionRecord并追加到响应体的proxy_token字段返回给客户端会话记录带 TTL默认 7200 秒存入状态存储供后续pt校验、归属校验与并发计数使用。前端类型定义见 PlaygroundSessionsession_id、statusstarting/ready/active/done/error、timeout_seconds、proxy_token。4.5 并发与配额两种状态存储实现创建会话的并发与配额检查在 per-user 创建锁保护下进行锁超时转 429create_busy带Retry-After: 5响应头。其状态存储有内存与 Redis 两种实现由 playground_state.py 按开关选择单实例PLAYGROUND_MULTI_INSTANCEfalse默认进程内存实现MemoryPlaygroundStateStore会话跟踪、创建锁、消息限流都在进程内与多副本无关多实例PLAYGROUND_MULTI_INSTANCEtrueRedis 实现RedisPlaygroundStateStore会话记录用 hash、用户会话集用 set、创建锁用SET NX EX Lua 释放校验持有者防止 TTL 过期后误删他人新锁。注意开启该开关但未配置 Redis 会启动即报错RuntimeError因为静默退回内存会让并发/归属/令牌校验在多副本下悄悄失效。配额检查的要点每日配额PLAYGROUND_DAILY_LIMIT默认 20每用户每自然日最多创建的 session 数0 不限制管理员始终不受限。配额超限返回 429quota_exceeded并携带X-RateLimit-Limit、X-RateLimit-Remaining、X-RateLimit-Reset响应头并发上限PLAYGROUND_MAX_CONCURRENT_SESSIONS默认 3创建前会先并行「验活」探测 skill-runner 会话状态剔除已死会话再判断活跃数超限返回 409session_conflict配额扣减失败时_refund_quota会退回一次已扣配额。4.6 配额查询端点GET /api/v1/playground/quota返回当前用户今日配额使用情况见 playground_proxy.py{ used: 3, limit: 20, is_unlimited: false, reset_at: 2026-10-12T00:00:0000:00 }reset_at为下一个自然日零点UTC管理员返回is_unlimited: trueused恒为 0。前端对应 PlaygroundQuota 类型与getPlaygroundQuota()调用。此外配额端点与创建会话在 test_rate_limit_policy.py 中被验证为限流豁免路径。五、发送消息与文件上传5.1 发送消息POST /sessions/{session_id}/messages请求体为{content: 用户输入}响应{message_id: msg-...}。处理链归属校验 → 消息限流 → 转发见 send_message。归属校验非管理员不能操作他人的会话否则 403not_your_session管理员可操作任意会话记录不存在时放行避免重启锁死。消息限流PLAYGROUND_MSG_RATE_PER_MIN默认 10每用户每分钟发消息上限0 不限制管理员不受限超限返回 429rate_limited带Retry-After: 60。skill-runner 侧send_message还会校验会话不存在 404、仍在初始化 503session still initializing、已结束 410、单条消息超message_max_chars默认 4096400、轮数超message_max_turns默认 50429、上一轮仍在运行 409previous turn still running防止并发写同一事件队列交错。5.2 上传临时文件POST /sessions/{session_id}/files使用multipart/form-data上传前端见 uploadPlaygroundFile返回{path: uploads/data.csv, size: 123}。上传文件仅用于当前会话具体大小和类型限制以实例配置为准。marketplace 侧upload_file做了四道校验文件名清洗取 basename、拒绝路径穿越\→/后取末段拒绝./../控制字符超长截断到 255 字符单文件大小PLAYGROUND_UPLOAD_MAX_FILE_BYTES默认 5 MB超限 413file_too_large空文件400empty_file可执行文件 magic bytes 黑名单拒绝 ELF、MZ/PE、Mach-O、Java class、shebang 脚本、WebAssembly 等可执行前缀400executable_rejected。Playground 上传的是给 Skill 分析的数据文件不该是可执行体这是沙箱隔离之外的纵深防护。skill-runner 侧upload_file再做纵深校验base64 解码失败 400、单文件超SKILL_RUNNER_UPLOAD_MAX_FILE_BYTES默认 5 MB413、会话累计文件数超SKILL_RUNNER_UPLOAD_MAX_FILES默认 10429、会话累计字节超SKILL_RUNNER_UPLOAD_MAX_TOTAL_BYTES默认 20 MB413防单会话占满 pod 磁盘。六、SSE 流式协议单连接覆盖整个会话6.1 事件类型SSE 流由GET /sessions/{session_id}/stream?pt{proxy_token}提供一条连接覆盖整个会话支持多轮done不关闭连接事件何时触发ready会话创建成功text/reasoningLLM 流式增量输出tool_call/tool_result沙箱内工具调用answer一轮最终答复done一轮结束连接不关闭支持多轮error单轮错误session_ended会话被删除连接关闭前端 SseEvent 类型还覆盖了更多事件形态usage单次 LLM 调用 token 用量含input_tokens/output_tokens/total_tokens/session_total、team_ready/team_completeSwarm 团队会话、keepalive以及 Swarm 场景下的事件来源字段role:leader/teammate、member具体成员名。6.2 SSE 帧格式与连接行为skill-runner 侧 stream 实现 定义了帧格式与连接语义每帧格式id: {递增序号}\ndata: {JSON}\n\n每 30 秒无事件时发送: keepalive\n\n注释帧维持连接事件类型为done时不关闭连接支持多轮为session_ended时关闭连接响应头Cache-Control: no-cache、X-Accel-Buffering: no禁用 Nginx 缓冲保证流式实时性、Connection: keep-alive所有事件在投递前经过_redact_event脱敏正则替换api_key/secret/password/token/bearer等密钥类串防止工具输出泄露凭据。6.3 消费端实现前端使用浏览器原生EventSourceopenPlaygroundStreamexport function openPlaygroundStream( sessionId: string, onEvent: (event: SseEvent) void, onError: (err: Event) void, proxyToken?: string, ): EventSource { const tokenQs proxyToken ? ?pt${encodeURIComponent(proxyToken)} : const url ${API_CONFIG.BASE_URL}${API_ENDPOINTS.PLAYGROUND.stream(sessionId)}${tokenQs} const es new EventSource(url, { withCredentials: true }) es.onmessage (e) { try { const data JSON.parse(e.data) as SseEvent onEvent(data) } catch { // ignore malformed events } } es.onerror onError return es }6.4 代理层的流式透传marketplace 对 SSE 采用流式透传而非缓冲转发见_forward的streamTrue分支与 catch-all 代理识别条件GET方法且路径以/stream结尾使用httpx.AsyncClient.send(streamTrue)建立上游流通过StreamingResponse的生成器把aiter_raw()的原始字节逐块转发给浏览器连接关闭时同步关闭上游透传时剔除 hop-by-hop 头部connection、keep-alive、transfer-encoding、upgrade、host、content-length等见_HOP_BY_HOP避免逐跳语义错误传递非流式转发的 read 超时为 300 秒流式转发的 read 超时为None无限由上游自行控制生命周期上游不可达时流式返回 502skill-runner unreachable。6.5 会话生命周期与探活skill-runner 侧维护了会话状态机SessionStatusstarting → ready → active → done/error并配套两个后台任务app.py 的 lifespan空闲回收器idle session reaper每 60 秒扫描超过SKILL_RUNNER_SESSION_TIMEOUT默认 1800 秒空闲的会话被强制结束置 DONE、投递session_ended、销毁执行器pod 回收器pod reaper由 k8s executor 提供每 120 秒回收孤儿 pod。marketplace 侧创建会话前的「验活」探活_session_still_alive规则skill-runner 返回 404idle reaper 已回收→ 判定失活并释放计数实例级地址不可达 → 判定实例已死Service 地址探测失败 →保守拒绝防绕过并发限制控制面 5xx → 拒绝并提示重试。七、结束会话DELETE 与 beaconDELETE /sessions/{session_id}校验归属后转发2xx/404 或多实例粘性地址下的502 时释放代理侧并发计数与会话记录POST /sessions/{session_id}/beacon逻辑同 DELETE但凭?pt令牌校验专供页面关闭/跳转时用navigator.sendBeacon上报无法携带鉴权头的场景也能完成清理。skill-runner 侧 end_session 的清理顺序取消正在运行的_drive_turn任务等待 finally 完成避免竞态→ 投递session_ended→_executor.destroy(session)销毁沙箱 →store.end移除会话 →clear_session_tokens清除 LLM 代理侧的 token 计数。前端对应 endPlaygroundSession。八、安全模型与配额边界约束实现客户端不得自带执行内容_CLIENT_FORBIDDEN_FIELDS强制剥离非 admin 一律走 marketplace 注入链路审核状态检查版本moderation_status非APPROVED返回 403skill_not_approved每日配额PLAYGROUND_DAILY_LIMIT默认 20每用户每自然日0 不限管理员不受限并发上限PLAYGROUND_MAX_CONCURRENT_SESSIONS默认 3每用户同时活跃 session 数消息限流PLAYGROUND_MSG_RATE_PER_MIN默认 10每用户每分钟会话归属非管理员只能操作自己的会话403not_your_session上传安全文件名清洗 大小限制 可执行文件 magic bytes 黑名单运行时隔离所有 Skill 代码与 LLM 决策的 shell 命令都跑在隔离容器内不允许无沙箱本地 subprocess 模式九、配置项总表9.1 marketplace 侧.env.example / config.py环境变量默认值说明PLAYGROUND_ENABLED别名MARKET_PLAYGROUND_ENABLEDfalse在线体验开关关闭时路由不注册、前端按钮不显示SKILL_RUNNER_URL别名MARKET_SKILL_RUNNER_URLhttp://127.0.0.1:8900skill-runner 服务地址K8s 部署为集群内 Service 地址PLAYGROUND_DAILY_LIMIT20每用户每自然日最多创建 session 数0 不限管理员始终不受限PLAYGROUND_MAX_CONCURRENT_SESSIONS3每用户同时活跃 session 数上限0 不限管理员始终不受限PLAYGROUND_MSG_RATE_PER_MIN10每用户每分钟发消息上限0 不限管理员始终不受限PLAYGROUND_MULTI_INSTANCEfalse多实例开关true 需配置 Redismarketplace 可多副本并支持粘性路由PLAYGROUND_SESSION_TTL7200多实例下会话记录 Redis TTL 兜底秒正常路径由 DELETE/beacon/探活清理PLAYGROUND_UPLOAD_MAX_FILE_BYTES52428805 MB上传单文件字节上限入口主闸9.2 skill-runner 侧skill-runner.env.example / config.py环境变量默认值说明SKILL_RUNNER_EXECUTORk8s执行器k8s 控制面每 session 起 podlocal worker pod 内部使用SKILL_RUNNER_MAX_SESSIONS20并发 session 上限超出则 create 返回 429SKILL_RUNNER_SESSION_TIMEOUT1800会话空闲超时秒由 idle reaper 回收SKILL_RUNNER_MSG_MAX_CHARS4096单条消息最大字符数SKILL_RUNNER_MSG_MAX_TURNS50每会话最大轮数SKILL_RUNNER_SSE_BUFFER256SSE 事件队列容量上限SKILL_RUNNER_SSE_PUT_TIMEOUT30向 SSE 队列投递事件的最长等待超时 消费者已断连中止本轮释放 podSKILL_RUNNER_UPLOAD_MAX_FILE_BYTES52428805 MB上传单文件字节上限纵深校验SKILL_RUNNER_UPLOAD_MAX_FILES10每会话累计上传文件数上限SKILL_RUNNER_UPLOAD_MAX_TOTAL_BYTES2097152020 MB每会话累计上传总字节上限SKILL_RUNNER_MULTI_INSTANCEfalse控制面多副本create 响应回带实例地址做粘性路由SKILL_RUNNER_USER_DAILY_TOKEN_LIMIT500000每用户每日 LLM token 上限llm_proxy 层累计0 不限SKILL_RUNNER_POOL_SIZE0worker pod 预热池大小0 即用即弃配置边界提醒PLAYGROUND_ENABLED、SKILL_RUNNER_URL、PLAYGROUND_DAILY_LIMIT、PLAYGROUND_MULTI_INSTANCE属于 marketplace 侧配置SKILL_RUNNER_*、LLM、worker pod、K8s executor 等配置属于 skill-runner 侧配置边界说明。Redis 只有在多实例或需要共享状态时才需要配置。十、验证与排障10.1 可用性验证最小冒烟GET /api/v1/playground/quotaBearer 鉴权返回 200 即代表在线体验已启用且路由已注册404 则说明PLAYGROUND_ENABLEDfalse。会话全链路冒烟仓库 k8s_smoke.py 提供了创建 → 发消息 → 读流 → 结束的完整冒烟脚本可直接对照接口行为。限流豁免验证配额端点在 test_rate_limit_middleware.py 与 test_rate_limit_policy.py 中有测试覆盖。10.2 常见错误码速查错误触发场景404在线体验未启用PLAYGROUND_ENABLEDfalse或会话不存在403skill_not_approvedSkill 版本未通过审核403not_your_session操作他人会话非管理员403invalid_session_tokenSSE/beacon 的pt令牌无效409session_conflict活跃会话数已达上限429quota_exceeded每日配额已用完429create_busy创建锁等待超时请求过于频繁429rate_limited每分钟消息数超限503skill_runner_unavailable控制面skill-runner暂不可达502流式/非流式转发时上游不可达413file_too_large上传单文件超限400executable_rejected上传了可执行文件十一、相关文档导航用户侧使用流程在线体验使用指南含「试用」按钮、基本流程与常见状态说明运行时设计与部署约束在线体验运行时K8s 部署要求、Executor 选型、镜像构建说明skill-runner 部署skill-runner 部署、LLM 代理与密钥配置、Redis 多实例配置K8s 部署清单docker/k8s/marketplace-config.yaml、docker/k8s/skill-runner-config.yaml、docker/k8s/skill-runner-deploy.yaml其余 API 参考openJiuwen-Agentic-Hub-接口参考、ClawHub 兼容层需要说明在线体验仅支持 K8s 部署Windows 本地安装和 Docker 等非 K8s 基础部署应保持PLAYGROUND_ENABLEDfalse具体请求/响应字段以部署版本的路由实现为准本文给出的字段与行为均对应当前仓库源码。赞分享后端前端AI 技能AI 插件【免费下载链接】skillhubopenJiuwen 生态的 Skill 托管与分发开源方案支持自建与可选 ClawHub 兼容。项目地址https://gitcode.com/openJiuwen/skillhub点击查看免费下载相关推荐openJiuwen Skillhub 在线体验多实例部署Redis 会话共享与限流配置实战openJiuwen Skillhub 在线体验多实例部署Redis 会话共享与限流配置实战 本指南聚焦 openJiuwen Skillhub 在线体验P后端前端AI 技能AI 插件openJiuwen Skillhub 在线体验Playgroundmarketplace 环境变量配置指南openJiuwen Skillhub 在线体验Playgroundmarketplace 环境变量配置指南 导读 本文围绕 openJiuwen Skil后端前端AI 技能AI 插件openJiuwen Agentic Hub 在线体验Playground使用指南从「试用」按钮到沙箱会话的完整实战与原理openJiuwen Agentic Hub 在线体验Playground使用指南从「试用」按钮到沙箱会话的完整实战与原理 在线体验Playground后端前端AI 技能AI 插件上一篇TypeGraphQL 性能优化指南衡量抽象层开销与使用 simpleResolvers 加速查询下一篇在 Weblate 中翻译 AsciiDoc 文档格式支持、组件配置与重复字符串处理创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考