Skip to Content
开发者指南Daemon快速启动与操作

快速启动与操作

本页重点介绍如何启动 qwen serve、如何验证其是否正常工作,以及从 qwen serve 到监听服务器的内部调用链。架构、组件和通信协议的详细信息请参阅其他 daemon 深度解析页面。

1. 最短路径

qwen serve

输出:

qwen serve listening on http://127.0.0.1:4170 (mode=http-bridge, workspace=/your/cwd) qwen serve: bound to workspace "/your/cwd" qwen serve: bearer auth disabled (loopback default). Set QWEN_SERVER_TOKEN to enable.

在浏览器中打开 http://127.0.0.1:4170/ 即可获取 Web Shell UI:聊天、会话列表和工作区检查。createServeApp()bearerAuth 之前挂载打包的 Web Shell 资源(packages/cli/src/serve/web-shell-static.ts),因此 Shell 本身无需 token 即可加载;其自身的 API 调用在配置了 bearer 时会携带 bearer token——启动 daemon 时使用 --open(将 token 放在 URL fragment 中,永远不会发送到服务器)或在启用认证时手动追加 #token=…--no-web 退出 Web Shell,使 daemon 仅提供 API。

2. 启动方案

# 1. 本地开发默认配置(loopback,无 token) qwen serve # 2. 显式指定工作区 + 临时端口 qwen serve --workspace /path/to/repo --port 0 # 3. 加固的 loopback 开发模式(即使在 loopback 也强制 bearer 认证) QWEN_SERVER_TOKEN=$(openssl rand -hex 32) qwen serve --require-auth # 4. 暴露到局域网(非 loopback 需要 token) QWEN_SERVER_TOKEN=$(openssl rand -hex 32) \ qwen serve --hostname 0.0.0.0 --port 4170 # 5. 针对多会话和更大的重放环进行调优 qwen serve --max-sessions 0 --event-ring-size 32000 # 6. 多客户端协作 + 严格的 MCP 预算 QWEN_SERVER_TOKEN=secret \ qwen serve --require-auth \ --mcp-client-budget 10 \ --mcp-budget-mode enforce # 7. 使用 settings.json 中配置的 consensus 策略启动 # settings.json: { "policy": { "permissionStrategy": "consensus", "consensusQuorum": 2 } } qwen serve # 8. 调试日志 QWEN_SERVE_DEBUG=1 qwen serve # 9. 禁用 F2 池(回退到每会话 MCP 客户端) QWEN_SERVE_NO_MCP_POOL=1 qwen serve # 10. 允许浏览器 Web UI 跨域访问 QWEN_SERVER_TOKEN=secret \ qwen serve --allow-origin 'http://localhost:3000' # 11. Prompt 截止时间 + SSE 空闲超时 qwen serve --prompt-deadline-ms 300000 --writer-idle-timeout-ms 600000 # 12. 在最后一个会话关闭后保持 ACP 子进程处于预热状态 qwen serve --channel-idle-timeout-ms 60000 # 13. 启用 HTTP 速率限制 QWEN_SERVE_RATE_LIMIT=1 qwen serve

使用加固的 loopback 方案 (3) 时,/healthbearerAuth 之后注册,因此探针必须像其他 API 路由一样携带 token(Web Shell 静态资源按设计保持预认证;传递 --no-web 可获得纯 API 的 daemon)。

3. 完整启动选项

CLI 定义在 packages/cli/src/commands/serve.ts 中:

选项类型默认值何时必需作用
--port <n>number4170-TCP 端口;0 表示由操作系统分配的临时端口。
--hostname <host>string127.0.0.1非 loopback 需要 token绑定地址。Loopback 值:127.0.0.1localhost::1[::1][::1] 的方括号会自动去除;如果输入 host:port 格式会被拒绝,并提示使用 --port
--token <s>stringenv / none非 loopback 和 --require-authBearer token;会进行一次 trim 处理。它会出现在 /proc/<pid>/cmdline 中,因此建议优先使用 QWEN_SERVER_TOKEN。启动时的 stderr 也会对此发出警告。
--max-sessions <n>number32-每个工作区的活跃会话上限。超出限制的 spawn 请求将返回 503。0 表示无限制。NaN 或负值会抛出异常。
--max-total-sessions <n>number多个启动/恢复工作区时推导-Daemon 级别的活跃会话上限。省略时,从每个工作区的上限和启动/恢复的工作区数量一次性推导出有限默认值;动态注册不会重新计算。0 表示无限制。
--memory-budget-mb <n>integer in [1024, 1048576]50% of cgroup/host memory-Daemon 进程树的总内存预算,上限为解析后的可用内存。没有子进程从中分配大小;当前唯一的消费者是自适应 live-journal 增长池(参见 --max-journal-bytes)。在 limits.memory 下报告,包括建模的每子进程分区。
--max-journal-events <n>positive safe integer10000-每个会话的 liveJournal 重放条目的基线上限。自适应增长可以提高它(参见 --max-journal-bytes);固定任一 journal 标志会禁用增长。
--max-journal-bytes <n>positive safe integer8388608-每个会话的 liveJournal 的基线字节上限。超限的轮次会按需增长上限(向双倍增长,受剩余池余量限制),在一个 daemon 全局池中(有效 --memory-budget-mb 的 5%,上限为 1024 MB;当有效预算低于 1024 MB 下限时为 0——增长禁用),永远不会超过每会话 256 MiB 的硬上限;固定任一 journal 标志会禁用增长。
--memory-pressure-mode <mode>off | observeobserveObservation only两种模式下均报告 runtime.memory.pressure;仅 observe 会触发 daemon_memory_pressure issue。仅限根进程。
--child-heap-mode <mode>off | observeobserveObservation onlyobserve 下,报告 limits.memory.childHeap 下的建模分区;不应用任何限制也不拒绝任何请求。在 off 下,该块的两个数据为 null
--max-pending-prompts-per-session <n>number5-每个会话已接受但处于 pending/running 状态的 prompt 上限。超出的 prompt 将返回 503。0 / Infinity 表示无限制。负值或非整数值会抛出异常。
--workspace <dir>string / repeatableprocess.cwd()-启动工作区运行时;重复以注册额外的隔离运行时。第一个为主运行时。每个值必须是绝对路径、必须存在且必须是目录。启动时通过 canonicalizeWorkspace 对每个值进行规范化。POST /sessioncwd 不匹配时返回 400 workspace_mismatch
--max-connections <n>number256-监听器级别的 server.maxConnections0 / Infinity 表示无限制。NaN 或负值会导致启动失败,以避免 fail-open 行为。
--require-authbooleanfalse需要 token将 bearer 认证扩展到 loopback /health。如果没有 token,启动将拒绝执行。
--enable-session-shellbooleanfalse需要 token启用直接的 POST /session/:id/shell 执行。调用方还必须发送与会话绑定的 X-Qwen-Client-Id
--event-ring-size <n>number8000-每个会话的 SSE 重放环深度。软上限为 MAX_EVENT_RING_SIZE = 1_000_000;超出范围的值会在构建 bridge 时抛出异常。
--http-bridgebooleantrue-Bridge 模式:生产环境尝试预热一个主要的 qwen --acp 子进程,并在首次使用失败后重试;受信任的次级运行时按需启动一个,而不受信任的次级运行时无法启动 ACP。阶段 2 进程内模式尚未实现;--no-http-bridge 回退并输出到 stderr。
--mcp-client-budget <n>numbernonemcp-budget-mode=enforce 时必需工作区 MCP 客户端上限。必须是正整数。
--mcp-budget-mode <m>'enforce' | 'warn' | 'off'设置了预算时为 warn,否则为 offenforce 需要 --mcp-client-budgetenforce 会拒绝请求,warn 仅在达到 75% 时发出警告,off 仅用于观察。
--allow-origin <pattern>repeatable stringnone-替换默认 Origin 拒绝策略的 CORS 允许列表。* 需要 token。
--allow-private-auth-base-urlbooleanfalse-允许安装 localhost / 私有网络 auth provider 的 baseUrl。仅用于受信任的本地开发。
--prompt-deadline-ms <n>numbernone-服务端 prompt 的挂钟时间限制(毫秒);超时将中止 prompt。
--writer-idle-timeout-ms <n>numbernone-每个 SSE 连接的空闲超时时间(毫秒)。
--channel-idle-timeout-ms <n>number0-在最后一个会话关闭后保持 ACP 子进程存活。0 表示立即回收。
--initialize-timeout-ms <n>number10000-ACP 子进程请求超时,包括 initialize 握手(毫秒)。
--session-reap-interval-ms <n>number60000-会话回收器扫描间隔。0 表示禁用。
--session-idle-timeout-ms <n>number1800000-已断开会话的空闲超时时间。0 表示禁用。
--rate-limit / --no-rate-limitbooleanenv / off-启用或禁用分层 HTTP 速率限制。
--rate-limit-prompt <n>number10--rate-limit每个时间窗口内的 prompt 请求数。
--rate-limit-mutation <n>number30--rate-limit每个时间窗口内的 mutation 请求数。
--rate-limit-read <n>number120--rate-limit每个时间窗口内的 read 请求数。
--rate-limit-window-ms <n>number60000--rate-limit速率限制窗口长度;必须 >= 1000

4. 环境变量

环境变量等效选项 / 作用
QWEN_SERVER_TOKEN等效于 --token--token 优先级更高。启动时会进行一次 trim 处理,以避免 cat token.txt 带来的尾部换行符。
QWEN_SERVE_DEBUG1 / true / on / yes(不区分大小写)启用详细的 stderr 日志。
QWEN_SERVE_NO_MCP_POOL1 完全禁用工作区 MCP 池,并回退到每会话的 McpClientManager。Capabilities 将停止通告 mcp_workspace_pool / mcp_pool_restart
QWEN_SERVE_MCP_CLIENT_BUDGETACP 子进程的内部预算输入。CLI 通过 childEnvOverrides--mcp-client-budget 生成它;它不是父进程的环境变量回退。
QWEN_SERVE_MCP_BUDGET_MODEACP 子进程的内部预算模式。CLI 通过 childEnvOverrides--mcp-budget-mode 生成它;它不是父进程的环境变量回退。
QWEN_SERVE_PROMPT_DEADLINE_MS--prompt-deadline-ms 的环境变量回退。
QWEN_SERVE_WRITER_IDLE_TIMEOUT_MS--writer-idle-timeout-ms 的环境变量回退。
QWEN_SERVE_MCP_POOL_TRANSPORTS由 ACP 子进程读取。逗号分隔的池化 transport 允许列表;默认为 stdio,websocket
QWEN_SERVE_MCP_POOL_DRAIN_MS由 ACP 子进程读取。池条目空闲排空延迟;默认为 30000,限制在 1000..600000 毫秒之间。
QWEN_SERVE_RATE_LIMIT1 / true 启用速率限制;CLI 选项优先级更高。
QWEN_SERVE_RATE_LIMIT_PROMPT--rate-limit-prompt 的环境变量回退。
QWEN_SERVE_RATE_LIMIT_MUTATION--rate-limit-mutation 的环境变量回退。
QWEN_SERVE_RATE_LIMIT_READ--rate-limit-read 的环境变量回退。
QWEN_SERVE_RATE_LIMIT_WINDOW_MS--rate-limit-window-ms 的环境变量回退。

每个 handle 的环境变量覆盖是有意为之的:在同一进程中运行的两个 daemon 不会在 process.env 上产生竞争。defaultSpawnChannelFactory 会在 spawn 时对 env 进行快照。

5. 同时读取 settings.json

启动时会调用一次 loadSettings(boundWorkspace)

类型行为
policy.permissionStrategy'first-responder' | 'designated' | 'consensus' | 'local-only'设置 BridgeOptions.permissionPolicy启动时会使用 validatePolicyConfig 进行验证;未知值会抛出 InvalidPolicyConfigError,而不是静默回退。
policy.consensusQuorumpositive integerconsensus 策略的 N 值。默认为 floor(M/2)+1。如果在非 consensus 策略下设置,它将被忽略,并且启动时会在 stderr 中记录警告。
context.fileNamestring覆盖 getCurrentGeminiMdFilename() 并控制 POST /workspace/init 写入哪个文件。
tools.disabledstring[]在影响下一次 ACP 子进程 spawn 之前,通过 normalizeDisabledToolList() 进行规范化(trim、丢弃空条目、去重)。
tools.approvalModestring默认会话审批模式。
telemetryobjectOTel 配置:enabledotlpEndpointotlpProtocol、每个 signal 的 endpoint 等。请参阅 17-configuration.md

设置 I/O 失败(例如 JSON 格式错误)会回退到默认值。InvalidPolicyConfigError 是例外情况:策略配置错误会明确导致启动失败。

6. 启动拒绝场景(明确失败)

在以下情况下,run-qwen-serve.ts 会故意抛出异常而不是回退:

场景错误前缀
无 token 绑定非 loopback 地址Refusing to bind ... without a bearer token
设置 --require-auth 但无 tokenRefusing to start with --require-auth set but no bearer token
--workspace 不存在、不是目录或不是绝对路径Invalid --workspace ...
--workspace stat 权限被拒绝Invalid --workspace ...: permission denied
--mcp-client-budget 不是正整数Must be a positive integer
设置 --mcp-budget-mode=enforce 但未设置预算requires a positive mcpClientBudget
--hostname 写成了 localhost:4170 格式looks like a "host:port" combination. Use --port
--hostname [::1]:8080Invalid --hostname ... brackets indicate an IPv6 literal but the value is not a clean [addr] form
--max-connectionsNaN 或负数Must be >= 0
--event-ring-size > 1_000_000在构建 bridge 时抛出异常
设置 --allow-origin '*' 但未配置 tokenRefusing to start with --allow-origin '*' but no bearer token configured
--prompt-deadline-ms / --writer-idle-timeout-ms 不是正整数Must be a positive integer
--initialize-timeout-ms 不是正整数或超过 2^31-1Must be a positive integer / Exceeds maximum JS timer delay
未知的 policy.permissionStrategy 或非正数的 policy.consensusQuorumInvalidPolicyConfigError

7. Curl 验证清单

# 1. Liveness curl http://127.0.0.1:4170/health # -> {"status":"ok"} # 1.1 Deep health curl -s 'http://127.0.0.1:4170/health?deep=1' | jq # 2. Capabilities curl -s http://127.0.0.1:4170/capabilities | jq # 3. Preflight readiness curl -s http://127.0.0.1:4170/workspace/preflight | jq # 4. Env snapshot (secrets only report presence) curl -s http://127.0.0.1:4170/workspace/env | jq # 5. MCP pool / budget snapshot curl -s http://127.0.0.1:4170/workspace/mcp | jq # 6. Create a session curl -s -X POST http://127.0.0.1:4170/session \ -H 'Content-Type: application/json' \ -H 'X-Qwen-Client-Id: curl-debug' \ -d '{}' | jq # 7. Tail SSE (replace <sid>) curl -N \ -H 'Accept: text/event-stream' \ -H 'X-Qwen-Client-Id: curl-debug' \ -H 'Last-Event-ID: 0' \ 'http://127.0.0.1:4170/session/<sid>/events' # 8. Web Shell UI open http://127.0.0.1:4170/

启用 Bearer 认证时,请在每个请求中添加 -H "Authorization: Bearer $QWEN_SERVER_TOKEN"

8. 是否有浏览器 UI?

有——Web Shell。 resolveWebShellDir() 查找构建好的资源(在发布版中与 CLI bundle 一起打包,在 checkout 中位于 packages/web-shell/dist),mountWebShellAssets() 将它们挂载在 //assets/session/:id 的文档导航上(浏览器深度链接——纯 curl /session/<id> 只会得到 API 的 401/404,而非 Shell)。当资源缺失时,daemon 会降级为纯 API 模式而不是崩溃;--no-web 可以显式退出。

静态 Shell 在所有启动模式下都挂载在 bearerAuth 之前——浏览器无法为地址栏导航或 <script src> 子资源附加 Authorization 头,因此对其进行门控只会破坏 UI。它调用的每个 API 路由仍然受 token 门控,前端自行附加 bearer。在非 loopback 绑定下,Shell 是只读的,除非传递 --allow-origin <origin>——同源 POST 携带的 Origin 头会被 CORS 墙拒绝(403)——因此在 loopback 以外的任何绑定都需要传递 --allow-origin

CSP 由 buildWebShellCsp() 构建,比静态页面的策略更宽松(内联 performance.measure 补丁使用 'unsafe-inline',shiki 和 mermaid 使用 eval/wasm/blob worker,katex 字体使用 data:,SSE 使用 connect-src 'self')。frame-ancestors 'none'X-Frame-Options: DENY 阻止点击劫持,除非通过 --allow-origin 显式允许了扩展源以便 UI 可以托管在 Chrome 侧边栏中(#5626)。

如需原始协议检查,请直接订阅 SSE 流(routes/sse-events.ts)——参见第 7 节中的 curl 方案。

9. 从 qwen serve 到监听服务器的调用链

qwen serve | v (process) packages/cli/index.ts main() | v gemini.tsx main() - parseArguments() | v (yargs assembly) config/config.ts import { serveCommand } ... config/config.ts .command(serveCommand) config/config.ts await yargsInstance.parse() | v (handler) commands/serve.ts handler(argv) - boot pre-checks commands/serve.ts const { runQwenServe } = await import('../serve/index.js') # lazy load commands/serve.ts await runQwenServe({...}) | v serve/run-qwen-serve.ts runQwenServe(opts, deps) | |- trim token | |- hostname mismatch fallback | |- auth preflight | |- workspace validation + canonicalization | |- MCP budget validation + childEnvOverrides | |- loadSettings + validatePolicyConfig | |- PermissionAuditRing + publisher | |- resolveBridgeFsFactory | `- createHttpAcpBridge({...}) | v serve/run-qwen-serve.ts const app = createServeApp(opts, () => actualPort, {...}) | v serve/server.ts createServeApp() - builds Express app (**does not listen**) | |- middleware chain (Host allowlist / CORS / bearerAuth / mutation gate / rate limit) | |- route mounting (health / web-shell static / capabilities / workspace / session / SSE / ACP HTTP) | `- return app | v serve/run-qwen-serve.ts server = createServer(app) / https.createServer(..., app) | |- lifecycle.bindServer(server, { startupReady, drainHost }) | |- server.listen(port, hostname) | |- server.maxConnections = cap | |- actualPort = server.address().port | |- write "qwen serve listening on ..." | |- register SIGINT / SIGTERM (onSignal) | `- resolve(handle: RunHandle) | v commands/serve.ts await blockForever() // block forever until signal

关键事实:

  • createServeApp 仅负责构建,不负责监听。 它返回一个挂载了中间件和路由的 express() 实例。仅需普通路由的嵌入者可以继续自行管理 app.listen()。使用 Live/Conversations 的嵌入者必须在监听之前将实际的 Node 服务器绑定到导出的应用生命周期,并在关闭期间 await 该生命周期。
  • () => actualPort 是一个惰性闭包。 actualPortserver.listen 的回调中赋值。hostAllowlist 中间件按需读取它,因此临时端口(--port 0)仍能正确校验 Host 请求头。
  • await blockForever() 是有意为之。 如果 yargs.parse() 解析完成,CLI 顶层会进入交互式 TUI 入口(gemini.tsx)。SIGINT / SIGTERM 通过 runQwenServeonSignal 路径退出。

10. HTTP 路由文件拆分

主要的组装工作在 server.tscreateServeApp() 中完成,它会连接中间件并挂载专门的路由模块:

路由文件挂载入口
/healthpackages/cli/src/serve/routes/health.tshealthRoutes.register()
/daemon/statuspackages/cli/src/serve/routes/daemon-status.tsregisterDaemonStatusRoutes()
/capabilities、workspace init/tool/MCP mutation 路由、ACP HTTP bridgepackages/cli/src/serve/server.ts直接在 createServeApp() 内部注册
Workspace 状态、env、preflight、MCP/tool/provider/skill 摘要packages/cli/src/serve/routes/workspace-status.tsregisterWorkspaceStatusRoutes(), registerWorkspaceDiagnosticStatusRoutes()
Workspace 扩展及扩展操作packages/cli/src/serve/routes/workspace-extensions.tsregisterWorkspaceExtensionRoutes()
/workspace/memory (GET/POST)packages/cli/src/serve/workspace-memory.tsmountWorkspaceMemoryRoutes()
所有 /workspace/agents CRUD 路由packages/cli/src/serve/workspace-agents.tsmountWorkspaceAgentsRoutes()
GET /file, /file/bytes, /list, /glob, /statpackages/cli/src/serve/routes/workspace-file-read.tsregisterWorkspaceFileReadRoutes()
POST /file/write, /file/editpackages/cli/src/serve/routes/workspace-file-write.tsregisterWorkspaceFileWriteRoutes()
Workspace setup、trust、settings、permissions 和 voice 路由packages/cli/src/serve/routes/workspace-*.tsregisterWorkspaceSetupGithubRoutes(), registerWorkspaceTrustRoutes()
Workspace auth provider 和 device-flow 路由packages/cli/src/serve/routes/workspace-auth.tsregisterWorkspaceAuthRoutes()
Session 生命周期、prompt、metadata、language、shell、recap、rewind、branch 和 list 路由packages/cli/src/serve/routes/session.tsregisterSessionRoutes()
GET /session/:id/events SSE 流packages/cli/src/serve/routes/sse-events.tsregisterSseEventsRoutes()
Permission 响应路由packages/cli/src/serve/routes/permission.tsregisterPermissionRoutes()

有关完整的路由和有线协议参考,请参阅 ../qwen-serve-protocol.md。有关架构信息,请参阅 01-architecture.md

11. 优雅关闭与强制关闭

  • 首次 SIGINT / SIGTERM -> runQwenServeonSignal -> 两阶段优雅关闭:
    1. bridge.shutdown():每个 channel 获得 KILL_HARD_DEADLINE_MS(10 秒)的超时时间,然后执行 channel.kill()
    2. server.close():排空进行中的请求,SHUTDOWN_FORCE_CLOSE_MS(5 秒)后触发 closeAllConnections(),然后再应用 2 秒的超时时间。
  • 退出过程中再次收到 SIGINT / SIGTERM -> bridge.killAllSync() 同步向所有 ACP 子进程发送 SIGKILL,并调用 process.exit(1) 以避免产生孤儿进程。

runQwenServe 返回的 RunHandle.close() 是供嵌入方和测试使用的编程式等效方法。

12. 嵌入式调用(绕过 CLI)

import { runQwenServe } from '@qwen-code/qwen-code/serve'; const handle = await runQwenServe({ port: 0, // ephemeral hostname: '127.0.0.1', mode: 'http-bridge', maxSessions: 20, workspace: '/abs/path/to/repo', }); console.log(`Daemon at ${handle.url}`); // ... call handle.bridge directly or access handle.server await handle.close(); // programmatic shutdown

或者直接获取 Express app 并自行绑定监听器生命周期。当嵌入方使用 Live/Conversations 时必须使用此形式:

import { createServer } from 'node:http'; import type { AddressInfo } from 'node:net'; import { createServeApp, getServeAppLifecycle, } from '@qwen-code/qwen-code/serve'; let actualPort = 0; const app = createServeApp( { port: 0, hostname: '127.0.0.1', mode: 'http-bridge', maxSessions: 20, }, () => actualPort, { /* deps: bridge, fsFactory, ... */ }, ); const lifecycle = getServeAppLifecycle(app); const server = createServer(app); lifecycle.bindServer(server); await new Promise<void>((resolve, reject) => { server.once('error', reject); server.listen(0, '127.0.0.1', () => resolve()); }); actualPort = (server.address() as AddressInfo).port; console.log('listening on', server.address()); // 停止准入,排空应用工作,关闭监听器,并释放所有权。 await lifecycle.close();

调用原始的 server.close() 也会启动相同的事件驱动清理,但只有当进程保持存活时才是尽力而为的;始终 await lifecycle.close() 以接收关闭错误。如果未绑定服务器,Live/Conversations 请求会 fail closed,而普通应用行为不受影响。

注意:直接调用 createServeApp 时,默认的 fsFactory.trusted = false。Agent 端的 ACP writeTextFile 会被作为 untrusted_workspace 拒绝,并在 stderr 打印一次警告。你可以注入带有显式信任配置的 deps.fsFactory,注入 deps.bridge,或者接受默认的信任门控行为。

13. 调试方案

请参阅 19-observability.md 中的调试部分。常用命令如下:

# Is the daemon alive? curl http://127.0.0.1:4170/health # Which capabilities are advertised? curl -s http://127.0.0.1:4170/capabilities | jq # Daemon-host readiness curl -s http://127.0.0.1:4170/workspace/preflight | jq # Tail live SSE curl -N -H 'Accept: text/event-stream' \ -H 'Last-Event-ID: 0' \ 'http://127.0.0.1:4170/session/<sid>/events' # Verbose logs QWEN_SERVE_DEBUG=1 qwen serve

参考资料

  • CLI 入口:packages/cli/src/commands/serve.ts
  • 引导程序:packages/cli/src/serve/run-qwen-serve.ts
  • Express 工厂函数:packages/cli/src/serve/server.ts
  • 中间件:packages/cli/src/serve/auth.ts
  • Bridge 工厂函数:packages/acp-bridge/src/bridge.ts
  • Web Shell 静态挂载:packages/cli/src/serve/web-shell-static.ts
  • 用户文档:../../users/qwen-serve.md
  • 有线协议:../qwen-serve-protocol.md
Last updated on