Qwen Code 接入
Qwen Code 是开源编码 Agent,可以在终端中理解项目、修改文件、运行命令并调用工具。它支持 OpenAI-compatible 提供方,因此可以把 Agent 请求交给 Lumoswitch。
配置 API 必须启用 OpenAI-compatible 输出,目标模型应支持流式输出与 Tool / Function Calling。以下 CLI 命令适用于 macOS、Linux 的 Bash / Zsh;开始前请确认 qwen --version 能返回版本号。
方式总览
| 方式 | 适合什么情况 | 会写入什么 | 退出后是否保留 |
|---|---|---|---|
| 仅本次启动 | 测试地址、Key 或模型 | Lumoswitch 临时设置文件 | 否 |
| 永久使用 | 日常从终端启动 | 原生设置、受管环境与可选维护启动器 | 是 |
| IDE Companion | 把当前 Qwen Code CLI 连接到编辑器 | 沿用当前 CLI 进程 | 随 CLI 方式而定 |
| VS Code 原生侧边栏 | 直接在扩展界面使用 | 用户级 Qwen Code 提供方配置 | 是 |
Qwen Code 没有独立的官方桌面端。官方提供 VS Code Extension Beta:既可连接当前 CLI,也可由扩展自己启动原生侧边栏 Agent。这两个入口的配置边界不同,具体见下文。
准备连接信息
| 占位符 | 应填写的内容 |
|---|---|
{{api_base_url}} | 配置 API 显示的 OpenAI-compatible 请求地址,应以 /v1 结尾 |
{{access_key}} | 配置 API 的 Access Key |
{{model}} | 配置 API 显示的下游模型名称 |
{{qwen_settings_json}} | 按有效推理能力生成的完整 Qwen Code 设置 JSON |
从控制台复制的命令会自动填入真实值。每个模型的 generationConfig.reasoning 由有效能力单独生成:可调模型使用安全默认档位,明确不支持推理的模型关闭推理,未知或固定推理模型不注入控制字段。
仅本次启动
在要使用 Qwen Code 的项目目录运行。命令会为当前进程创建临时提供方目录,并通过环境传入 Key;退出后临时目录立即删除,不会修改用户级或项目级 Qwen Code 配置。
(
set -e
LUMOSWITCH_QWEN_SETTINGS="$(mktemp "${TMPDIR:-/tmp}/lumoswitch-qwen.XXXXXX")"
trap 'rm -f "$LUMOSWITCH_QWEN_SETTINGS"' EXIT
printf '%s\n' '{{qwen_settings_json}}' > "$LUMOSWITCH_QWEN_SETTINGS"
chmod 600 "$LUMOSWITCH_QWEN_SETTINGS"
env \
LUMOSWITCH_QWEN_API_KEY="{{access_key}}" \
QWEN_CODE_SYSTEM_SETTINGS_PATH="$LUMOSWITCH_QWEN_SETTINGS" \
qwen --auth-type openai --model "{{model}}"
)永久使用
首次设置,或 Lumoswitch 地址、Access Key、模型发生变化时,运行下面的完整命令。它会写入 Qwen Code 支持的系统设置路径和受管环境,并保存可选维护启动器;不会覆盖默认用户配置。
永久导入会把 Access Key 保存到仅当前用户可读的受管环境或 Agent 配置文件中。请只在可信的个人设备上使用。
set -e
LUMOSWITCH_ROOT="$HOME/.config/lumoswitch/agents/qwen-code"
LUMOSWITCH_ENV="$LUMOSWITCH_ROOT/env.sh"
LUMOSWITCH_LAUNCHER="$HOME/.local/bin/lumoswitch-qwen-code"
mkdir -p "$LUMOSWITCH_ROOT" "$(dirname "$LUMOSWITCH_LAUNCHER")"
umask 077
if [ -f "$LUMOSWITCH_LAUNCHER" ]; then
LUMOSWITCH_BACKUP="$LUMOSWITCH_LAUNCHER.backup.$(date +%Y%m%d-%H%M%S)-$$"
cp "$LUMOSWITCH_LAUNCHER" "$LUMOSWITCH_BACKUP"
chmod 600 "$LUMOSWITCH_BACKUP"
fi
LUMOSWITCH_QWEN_SETTINGS="$LUMOSWITCH_ROOT/settings.json"
printf '%s\n' '{{qwen_settings_json}}' > "$LUMOSWITCH_QWEN_SETTINGS"
cat > "$LUMOSWITCH_ENV" <<'LUMOSWITCH_ENV_EOF'
export QWEN_CODE_SYSTEM_SETTINGS_PATH="$HOME/.config/lumoswitch/agents/qwen-code/settings.json"
export LUMOSWITCH_QWEN_API_KEY="{{access_key}}"
export LUMOSWITCH_QWEN_MODEL="{{model}}"
LUMOSWITCH_ENV_EOF
case "$SHELL" in
*/zsh) LUMOSWITCH_PROFILE="$HOME/.zshrc" ;;
*/bash) LUMOSWITCH_PROFILE="$HOME/.bashrc" ;;
*) LUMOSWITCH_PROFILE="$HOME/.profile" ;;
esac
touch "$LUMOSWITCH_PROFILE"
LUMOSWITCH_PROFILE_MARKER='# Lumoswitch Agent: qwen-code'
LUMOSWITCH_SOURCE_LINE='[ -f "$HOME/.config/lumoswitch/agents/qwen-code/env.sh" ] && . "$HOME/.config/lumoswitch/agents/qwen-code/env.sh"'
if ! grep -Fqx "$LUMOSWITCH_SOURCE_LINE" "$LUMOSWITCH_PROFILE"; then
printf '\n%s\n%s\n' "$LUMOSWITCH_PROFILE_MARKER" "$LUMOSWITCH_SOURCE_LINE" >> "$LUMOSWITCH_PROFILE"
fi
printf '%s\n' "$LUMOSWITCH_PROFILE" > "$LUMOSWITCH_ROOT/profile-path"
cat > "$LUMOSWITCH_LAUNCHER" <<'LUMOSWITCH_LAUNCHER_EOF'
#!/usr/bin/env bash
set -e
LUMOSWITCH_ROOT="$HOME/.config/lumoswitch/agents/qwen-code"
LUMOSWITCH_ENV="$LUMOSWITCH_ROOT/env.sh"
LUMOSWITCH_LAUNCHER="$HOME/.local/bin/lumoswitch-qwen-code"
if [ "$1" = "--lumoswitch-clean" ]; then
if [ -f "$LUMOSWITCH_ROOT/profile-path" ]; then
LUMOSWITCH_PROFILE="$(cat "$LUMOSWITCH_ROOT/profile-path")"
if [ -f "$LUMOSWITCH_PROFILE" ]; then
LUMOSWITCH_PROFILE_MARKER='# Lumoswitch Agent: qwen-code'
LUMOSWITCH_SOURCE_LINE='[ -f "$HOME/.config/lumoswitch/agents/qwen-code/env.sh" ] && . "$HOME/.config/lumoswitch/agents/qwen-code/env.sh"'
LUMOSWITCH_PROFILE_TMP="$LUMOSWITCH_PROFILE.lumoswitch.$$"
awk -v marker="$LUMOSWITCH_PROFILE_MARKER" -v source="$LUMOSWITCH_SOURCE_LINE" '$0 != marker && $0 != source' "$LUMOSWITCH_PROFILE" > "$LUMOSWITCH_PROFILE_TMP"
mv "$LUMOSWITCH_PROFILE_TMP" "$LUMOSWITCH_PROFILE"
fi
fi
if [ -d "$LUMOSWITCH_ROOT" ]; then
find "$LUMOSWITCH_ROOT" -depth \( -type f -o -type l \) -delete
find "$LUMOSWITCH_ROOT" -depth -type d -exec rmdir {} \; 2>/dev/null || true
fi
find "$(dirname "$LUMOSWITCH_LAUNCHER")" -maxdepth 1 -type f -name 'lumoswitch-qwen-code.backup.*' -delete
rm -f "$LUMOSWITCH_LAUNCHER"
printf '%s\n' 'Lumoswitch native setup and optional launcher removed. Open a new terminal to refresh the environment.'
exit 0
fi
if [ -f "$LUMOSWITCH_ENV" ]; then . "$LUMOSWITCH_ENV"; fi
exec qwen "$@"
LUMOSWITCH_LAUNCHER_EOF
chmod 600 "$LUMOSWITCH_ENV"
find "$LUMOSWITCH_ROOT" -type f -exec chmod 600 {} \;
chmod 700 "$LUMOSWITCH_LAUNCHER"
. "$LUMOSWITCH_ENV"
printf '%s\n' 'Native Lumoswitch setup saved. Future command: qwen'
printf '%s\n' 'Optional maintenance launcher: ~/.local/bin/lumoswitch-qwen-code'
qwen以后在任意项目目录运行:
qwen可以在命令末尾继续传入 Qwen Code 参数。更新启动器前会保留一个带时间戳、权限为 0600 的现有启动器备份。
Windows PowerShell 原生导入
以下命令在 Windows PowerShell 中原生运行,不需要 WSL。它们与本页的 macOS/Linux 模板使用同一组连接值。
仅本次使用(Windows)
& {
$ErrorActionPreference = 'Stop'
$lumoswitchConfig = Join-Path ([IO.Path]::GetTempPath()) ('lumoswitch-' + [Guid]::NewGuid().ToString('N') + '.json')
$lumoswitchConfigContent = @'
{{qwen_settings_json}}
'@
[IO.File]::WriteAllText($lumoswitchConfig, $lumoswitchConfigContent, [Text.UTF8Encoding]::new($false))
$lumoswitchEnvironmentNames = @('LUMOSWITCH_QWEN_API_KEY', 'QWEN_CODE_SYSTEM_SETTINGS_PATH')
$lumoswitchPreviousEnvironment = @{}
foreach ($lumoswitchName in $lumoswitchEnvironmentNames) {
$lumoswitchPreviousEnvironment[$lumoswitchName] = [Environment]::GetEnvironmentVariable($lumoswitchName, 'Process')
}
$lumoswitchExitCode = 0
try {
[Environment]::SetEnvironmentVariable('LUMOSWITCH_QWEN_API_KEY', '{{access_key}}', 'Process')
[Environment]::SetEnvironmentVariable('QWEN_CODE_SYSTEM_SETTINGS_PATH', $lumoswitchConfig, 'Process')
$lumoswitchArguments = @('--auth-type', 'openai', '--model', '{{model}}')
$lumoswitchExecutable = Get-Command 'qwen.cmd' -CommandType Application -ErrorAction SilentlyContinue
if ($null -eq $lumoswitchExecutable) { $lumoswitchExecutable = Get-Command 'qwen' -CommandType Application -ErrorAction Stop }
& $lumoswitchExecutable.Path @lumoswitchArguments
if ($null -ne $LASTEXITCODE) { $lumoswitchExitCode = $LASTEXITCODE }
} finally {
foreach ($lumoswitchName in $lumoswitchEnvironmentNames) {
[Environment]::SetEnvironmentVariable($lumoswitchName, $lumoswitchPreviousEnvironment[$lumoswitchName], 'Process')
}
Remove-Item -LiteralPath $lumoswitchConfig -Force -ErrorAction SilentlyContinue
}
if ($lumoswitchExitCode -ne 0) { throw 'qwen exited with code ' + $lumoswitchExitCode }
}永久使用(Windows)
该命令会备份已有的 Lumoswitch 专用文件,并为配置和启动器收紧当前用户的访问权限。
& {
$ErrorActionPreference = 'Stop'
$lumoswitchRoot = Join-Path $env:LOCALAPPDATA 'Lumoswitch\agents\qwen-code'
$lumoswitchLauncher = Join-Path $env:LOCALAPPDATA 'Lumoswitch\bin\lumoswitch-qwen-code.ps1'
$lumoswitchBackupSuffix = (Get-Date -Format 'yyyyMMdd-HHmmss') + '-' + $PID
function Protect-LumoswitchFile([string] $Path) {
$lumoswitchSid = [Security.Principal.WindowsIdentity]::GetCurrent().User.Value
& icacls.exe $Path '/inheritance:r' '/grant:r' ('*' + $lumoswitchSid + ':(F)') '*S-1-5-18:(F)' '*S-1-5-32-544:(F)' | Out-Null
if ($LASTEXITCODE -ne 0) { throw "Could not restrict access to $Path" }
}
function Install-LumoswitchFile([string] $Path, [string] $Content) {
[IO.Directory]::CreateDirectory((Split-Path -Parent $Path)) | Out-Null
if (Test-Path -LiteralPath $Path) {
$lumoswitchItem = Get-Item -LiteralPath $Path -Force
if ($lumoswitchItem.PSIsContainer -or ($lumoswitchItem.Attributes -band [IO.FileAttributes]::ReparsePoint)) {
throw "Lumoswitch refused to replace a directory or link: $Path"
}
$lumoswitchBackup = $Path + '.backup.' + $lumoswitchBackupSuffix
Copy-Item -LiteralPath $Path -Destination $lumoswitchBackup
Protect-LumoswitchFile $lumoswitchBackup
}
$lumoswitchTemporary = $Path + '.' + [Guid]::NewGuid().ToString('N') + '.tmp'
try {
[IO.File]::WriteAllText($lumoswitchTemporary, $Content, [Text.UTF8Encoding]::new($false))
Move-Item -LiteralPath $lumoswitchTemporary -Destination $Path -Force
Protect-LumoswitchFile $Path
} finally {
Remove-Item -LiteralPath $lumoswitchTemporary -Force -ErrorAction SilentlyContinue
}
}
[IO.Directory]::CreateDirectory($lumoswitchRoot) | Out-Null
$lumoswitchQwenSettings = Join-Path $lumoswitchRoot 'settings.json'
Install-LumoswitchFile $lumoswitchQwenSettings '{{qwen_settings_json}}'
$lumoswitchEnvironment = [ordered]@{}
$lumoswitchEnvironment['QWEN_CODE_SYSTEM_SETTINGS_PATH'] = (Join-Path $lumoswitchRoot 'settings.json')
$lumoswitchEnvironment['LUMOSWITCH_QWEN_API_KEY'] = '{{access_key}}'
$lumoswitchEnvironment['LUMOSWITCH_QWEN_MODEL'] = '{{model}}'
foreach ($lumoswitchEntry in $lumoswitchEnvironment.GetEnumerator()) {
[Environment]::SetEnvironmentVariable($lumoswitchEntry.Key, $lumoswitchEntry.Value, 'User')
[Environment]::SetEnvironmentVariable($lumoswitchEntry.Key, $lumoswitchEntry.Value, 'Process')
}
$lumoswitchLauncherContent = @'
param([Parameter(ValueFromRemainingArguments = $true)][string[]] $AgentArgs)
$ErrorActionPreference = 'Stop'
$lumoswitchRoot = Join-Path $env:LOCALAPPDATA 'Lumoswitch\agents\qwen-code'
$lumoswitchLauncher = Join-Path $env:LOCALAPPDATA 'Lumoswitch\bin\lumoswitch-qwen-code.ps1'
function Remove-LumoswitchFile([string] $Path) {
if (-not (Test-Path -LiteralPath $Path)) { return }
$lumoswitchItem = Get-Item -LiteralPath $Path -Force
if ($lumoswitchItem.PSIsContainer -or ($lumoswitchItem.Attributes -band [IO.FileAttributes]::ReparsePoint)) {
throw "Lumoswitch refused to remove a directory or link: $Path"
}
Remove-Item -LiteralPath $Path -Force
}
if ($AgentArgs.Count -gt 0 -and $AgentArgs[0] -eq '--lumoswitch-clean') {
foreach ($lumoswitchName in @('QWEN_CODE_SYSTEM_SETTINGS_PATH', 'LUMOSWITCH_QWEN_API_KEY', 'LUMOSWITCH_QWEN_MODEL')) {
[Environment]::SetEnvironmentVariable($lumoswitchName, $null, 'User')
[Environment]::SetEnvironmentVariable($lumoswitchName, $null, 'Process')
}
if (Test-Path -LiteralPath $lumoswitchRoot -PathType Container) {
$lumoswitchRootItem = Get-Item -LiteralPath $lumoswitchRoot -Force
if ($lumoswitchRootItem.Attributes -band [IO.FileAttributes]::ReparsePoint) { throw 'Lumoswitch refused to clean through a linked directory.' }
foreach ($lumoswitchFile in @(Get-ChildItem -LiteralPath $lumoswitchRoot -File -Recurse -Force)) { Remove-LumoswitchFile $lumoswitchFile.FullName }
foreach ($lumoswitchDirectory in @(Get-ChildItem -LiteralPath $lumoswitchRoot -Directory -Recurse -Force | Sort-Object FullName -Descending)) {
if ($null -eq (Get-ChildItem -LiteralPath $lumoswitchDirectory.FullName -Force | Select-Object -First 1)) { Remove-Item -LiteralPath $lumoswitchDirectory.FullName -Force }
}
if ($null -eq (Get-ChildItem -LiteralPath $lumoswitchRoot -Force | Select-Object -First 1)) { Remove-Item -LiteralPath $lumoswitchRoot -Force }
}
$lumoswitchBin = Split-Path -Parent $lumoswitchLauncher
if (Test-Path -LiteralPath $lumoswitchBin -PathType Container) {
foreach ($lumoswitchBackup in @(Get-ChildItem -LiteralPath $lumoswitchBin -Filter 'lumoswitch-qwen-code.ps1.backup.*' -File -Force)) { Remove-LumoswitchFile $lumoswitchBackup.FullName }
}
Remove-LumoswitchFile $lumoswitchLauncher
Write-Host 'Lumoswitch native setup and optional launcher removed. Open a new terminal to refresh the environment.'
exit 0
}
$lumoswitchEnvironment = [ordered]@{}
$lumoswitchEnvironment['QWEN_CODE_SYSTEM_SETTINGS_PATH'] = (Join-Path $lumoswitchRoot 'settings.json')
$lumoswitchEnvironment['LUMOSWITCH_QWEN_API_KEY'] = '{{access_key}}'
$lumoswitchEnvironment['LUMOSWITCH_QWEN_MODEL'] = '{{model}}'
foreach ($lumoswitchEntry in $lumoswitchEnvironment.GetEnumerator()) {
[Environment]::SetEnvironmentVariable($lumoswitchEntry.Key, $lumoswitchEntry.Value, 'Process')
}
$lumoswitchExecutable = Get-Command 'qwen.cmd' -CommandType Application -ErrorAction SilentlyContinue
if ($null -eq $lumoswitchExecutable) { $lumoswitchExecutable = Get-Command 'qwen.exe' -CommandType Application -ErrorAction SilentlyContinue }
if ($null -eq $lumoswitchExecutable) { $lumoswitchExecutable = Get-Command 'qwen' -CommandType Application -ErrorAction Stop }
$lumoswitchArguments = @()
& $lumoswitchExecutable.Path @lumoswitchArguments @AgentArgs
if ($null -ne $LASTEXITCODE) { exit $LASTEXITCODE }
'@
Install-LumoswitchFile $lumoswitchLauncher $lumoswitchLauncherContent
Write-Host 'Native Lumoswitch setup saved. Future command: qwen'
Write-Host 'Optional maintenance launcher:' $lumoswitchLauncher
$lumoswitchExecutable = Get-Command 'qwen.cmd' -CommandType Application -ErrorAction SilentlyContinue
if ($null -eq $lumoswitchExecutable) { $lumoswitchExecutable = Get-Command 'qwen.exe' -CommandType Application -ErrorAction SilentlyContinue }
if ($null -eq $lumoswitchExecutable) { $lumoswitchExecutable = Get-Command 'qwen' -CommandType Application -ErrorAction Stop }
$lumoswitchArguments = @()
& $lumoswitchExecutable.Path @lumoswitchArguments
if ($null -ne $LASTEXITCODE -and $LASTEXITCODE -ne 0) { throw 'qwen exited with code ' + $LASTEXITCODE }
}导入会写入 Agent 支持的持久化配置,并直接启动 qwen。保存的 Lumoswitch 维护脚本不是启动 Agent 的必需入口;需要恢复或移除此接入时,运行它并追加 --lumoswitch-clean。
清除 CLI 接入
Windows PowerShell
先退出该 Agent 的所有 Lumoswitch 会话,再运行下面的命令。可选维护启动器会删除受管原生配置、恢复已保留的共享文件、清除 Lumoswitch 用户环境变量,并移除自身。
& {
$lumoswitchLauncher = Join-Path $env:LOCALAPPDATA 'Lumoswitch\bin\lumoswitch-qwen-code.ps1'
if (-not (Test-Path -LiteralPath $lumoswitchLauncher -PathType Leaf)) {
throw 'The optional Lumoswitch maintenance launcher is missing. Run persistent import again before cleanup.'
}
& powershell.exe -NoLogo -NoProfile -ExecutionPolicy Bypass -File $lumoswitchLauncher --lumoswitch-clean
}macOS / Linux
下面的命令会删除受管 Qwen 设置、环境接入、可选维护启动器及其备份;它不会删除 ~/.qwen/settings.json、Qwen Code 登录信息、历史记录或其他用户配置。
"$HOME/.local/bin/lumoswitch-qwen-code" --lumoswitch-clean临时命令会在退出时删除临时设置文件,也不会在当前终端留下变量。若曾手动导出过 LUMOSWITCH_QWEN_API_KEY,关闭对应终端窗口即可;不自动 unset 是为了避免影响同一终端中的其他 Lumoswitch 工具。
VS Code 与 IDE Companion
连接当前 CLI
先通过本页命令启动 Qwen Code,再按官方 IDE Integration 流程把 Companion 连接到当前 CLI 进程,即可继续使用当前 Lumoswitch 地址、Key 和模型,无需保存第二份凭证。退出临时 CLI 后,临时接入也随之失效。
VS Code 原生侧边栏
扩展原生侧边栏会自行启动 Qwen Code,不保证调用 ~/.local/bin/lumoswitch-qwen-code。如需从侧边栏直接使用 Lumoswitch,应把以下模型条目合并进用户级 ~/.qwen/settings.json 的 openai 数组,不要覆盖已有模型项或整个设置文件。
{
"modelProviders": {
"openai": [
{
"id": "{{model}}",
"name": "Lumoswitch · {{model}}",
"envKey": "LUMOSWITCH_QWEN_API_KEY",
"baseUrl": "{{api_base_url}}"
}
]
},
"security": {
"auth": {
"selectedType": "openai"
}
},
"model": {
"name": "{{model}}"
}
}再在 Qwen Code 可读取的用户环境或 ~/.qwen/.env 中提供 LUMOSWITCH_QWEN_API_KEY={{access_key}},并完全重启扩展。不要把真实 Key 写入会提交到 Git 的项目文件。
原生侧边栏只有持久接入,没有可靠的“仅本次启动”命令,因为扩展从持久设置和自己的启动环境读取提供方。清除 CLI 启动器也不会修改这份用户配置;需要清除侧边栏接入时,请只从 modelProviders.openai 删除自己添加的 Lumoswitch 条目、删除对应 LUMOSWITCH_QWEN_API_KEY 行,并切换模型。这里不提供自动清除命令,是为了避免脚本误删用户共享的 JSON、.env 或其他提供方。
参见 Qwen Code VS Code 集成、IDE Integration和模型提供方配置。
验证与排查
- 启动后先发送一个简单请求,再测试读取文件与工具调用,并在 Lumoswitch 请求日志中确认模型和 Access Key。
- 返回
404:检查下游地址是否遗漏或重复/v1。 - IDE 使用默认模型:确认 Companion 连接的是当前 CLI;原生侧边栏则需要单独合并用户级提供方配置。
- 项目级
.qwen/settings.json可能覆盖用户级设置,修改后请完全重启扩展。
维护者发布字段
- 平台 ID:
qwen-code - 展示名称:
Qwen Code CLI - 下游协议:
openai-compatible commandTemplate:复制「仅本次启动」代码框的完整内容- 永久策略:
native persistentCommandTemplate:复制「永久使用」中的完整设置命令futureCommand:qwen- 展示顺序:
60 - 最近核验:
2026-08-27