Continue CLI 首次使用引导(Onboarding):交互式配置、AWS Bedrock 绕过与正常加载流程全解析
【免费下载链接】continueopen-source coding agent项目地址: https://gitcode.com/GitHub_Trending/co/continue
本文以 Continue 开源仓库中 onboarding 规范文档 为核心骨架,结合 onboarding.ts 源码实现与 onboarding.test.ts 测试用例,完整解析 Continue CLI(cn)的首次使用引导机制:它何时触发、交互式流程如何一步步引导用户完成模型配置、如何通过CONTINUE_USE_BEDROCK环境变量无交互地接入 AWS Bedrock,以及完成引导后正常配置加载的优先级规则。读完本文,你将掌握 Continue CLI 配置的完整生命周期,并能在无人值守/CI 场景下正确跳过引导、直接运行cn命令。
什么是 Onboarding?何时触发
在 Continue CLI 中,onboarding(首次使用引导)是用户第一次以交互模式运行cn时经历的一套初始化流程,目的是帮助用户完成最基本的模型配置(登录 Continue 账号或填入 Anthropic API Key),从而让 CLI 可以立即开始工作。
触发条件:只看标志文件,不看 config.yaml
与直觉不同,引导流程的运行与否与是否存在config.yaml无关。规范文档明确强调:
The onboarding flow runs when the user hasn't completed onboarding before, regardless of whether they have a valid config.yaml file.
即判断依据只有一个:用户是否完成过引导。在源码中,这个状态由 Continue 主目录下的一个标志文件记录,见 onboarding.ts:
export async function isFirstTime(): Promise<boolean> { return !fs.existsSync(path.join(env.continueHome, ".onboarding_complete")); }- 若
~/.continue/.onboarding_complete不存在,isFirstTime()返回true,进入引导流程; - 若存在,则走正常配置加载流程。
这也意味着:即使你手工写好了一个完全合法的config.yaml,只要标志文件缺失,首次运行时仍会触发引导(唯一例外是下文提到的--config参数与CONTINUE_USE_BEDROCK=1环境变量)。
完成标记的写入
当引导流程成功完成后,CLI 会调用markOnboardingComplete()在~/.continue/.onboarding_complete写入当前时间戳,见 onboarding.ts:
export async function markOnboardingComplete(): Promise<void> { const flagPath = path.join(env.continueHome, ".onboarding_complete"); const flagDir = path.dirname(flagPath); if (!fs.existsSync(flagDir)) { fs.mkdirSync(flagDir, { recursive: true }); } fs.writeFileSync(flagPath, new Date().toISOString()); }标志文件本身只是一个 ISO 时间戳字符串,其存在即表示“已完成引导”。
首次引导流程(Onboarding Flow)逐步拆解
按 onboarding 规范 的定义,首次引导流程共分三个步骤,对应源码 runOnboardingFlow() 的逐步判断:
Step 1:--config参数优先
如果在启动命令中显式提供了--config参数,CLI直接跳过整个引导流程,改用该参数指定的配置加载。对应源码:
// Step 1: Check if --config flag is provided if (configPath !== undefined) { return false; }--config参数支持两类取值(详见 config-loader 规范 与 configLoader.ts):
- 本地文件路径:以
.、/、~开头的路径,直接解析本地 YAML 文件; - Assistant slug(如
owner/package):从 Continue 平台拉取配置。
注意一个重要的错误处理细节:当显式指定--config指向不存在的文件或非法 YAML 时,CLI不会静默回退到默认配置,而是立即抛出带路径的错误并退出。这一点在测试 onboarding.test.ts 中被重点验证,例如测试明确断言错误消息必须形如Failed to load config from "..."且不得包含~/.continue/config.yaml或default config之类的回退字样(should not fall back to default config when explicit config fails用例)。
Step 2:CONTINUE_USE_BEDROCK=1环境变量
若检测到环境变量CONTINUE_USE_BEDROCK的值为字符串"1",则自动采用 AWS Bedrock 配置并跳过全部交互式提示,同时打印确认消息。见 onboarding.ts:
// Step 2: Check for CONTINUE_USE_BEDROCK environment variable first (before test env check) if (process.env.CONTINUE_USE_BEDROCK === "1") { console.log( chalk.blue("✓ Using AWS Bedrock (CONTINUE_USE_BEDROCK detected)"), ); return true; }使用方式(规范文档原文):
export CONTINUE_USE_BEDROCK=1 cn <command>设置该变量后会发生以下行为:
- 跳过交互式引导菜单;
- 自动配置 CLI 使用 AWS Bedrock;
- 前提:用户必须已通过标准 AWS 凭证链(AWS CLI、环境变量、IAM 角色等)配置好 AWS 凭证;
- 向用户显示确认消息;
- 将引导标记为已完成。
值得注意的边界语义:判断条件是process.env.CONTINUE_USE_BEDROCK === "1",即只有字符串"1"能触发;设置成"0"、"true"或其他值都不会生效。测试 onboarding.test.ts 专门验证了CONTINUE_USE_BEDROCK=0时不会打印 Bedrock 消息、不会绕过交互流程。
Step 3:向用户呈现可用选项
正常情况下(未提供--config、未设置 Bedrock 变量),CLI 进入交互式引导,向用户提供两个选项:
选项 A:使用 Continue 登录(Log in with Continue)
登录成功后,CLI 会自动为用户创建 assistant,随后从用户所属的第一个 org 中加载第一个 assistant 作为配置来源。
选项 B:输入 Anthropic API Key
让用户手动输入 API Key,然后 CLI 会:
- 若
~/.continue/config.yaml不存在,则创建它; - 若已存在,则更新它以追加该模型。
规范文档给出的目标配置内容为:
name: Local Config version: 1.0.0 schema: v1 models: - uses: anthropic/claude-4-sonnet with: ANTHROPIC_API_KEY: <THEIR_ANTHROPIC_API_KEY>需要说明的是,这是规范文档描述的"概念形态"。从当前仓库源码看,由于 Hub/slug 解析机制已被移除,实际写入config.yaml的是显式展开的模型配置(不再依赖uses:slug)。见 yamlConfigUpdater.ts,onboarding 实际写入的模型为两个显式 Anthropic 模型:
function getAnthropicModels(apiKey: string): ModelConfig[] { return [ { name: "Claude Sonnet 4.6", provider: "anthropic", model: "claude-sonnet-4-6", apiKey, roles: ["chat", "edit", "apply"], defaultCompletionOptions: { contextLength: 200000, maxTokens: 64000 }, capabilities: ["tool_use", "image_input"], }, { name: "Claude Opus 4.6", provider: "anthropic", model: "claude-opus-4-6", apiKey, roles: ["chat", "edit", "apply"], defaultCompletionOptions: { contextLength: 200000, maxTokens: 64000 }, capabilities: ["tool_use", "image_input"], }, ]; }即实际落盘的 YAML 大致为:
name: Main Config version: 1.0.0 schema: v1 models: - name: Claude Sonnet 4.6 provider: anthropic model: claude-sonnet-4-6 apiKey: sk-ant-xxxxxxxx roles: [chat, edit, apply] defaultCompletionOptions: contextLength: 200000 maxTokens: 64000 capabilities: [tool_use, image_input] - name: Claude Opus 4.6 provider: anthropic model: claude-opus-4-6 apiKey: sk-ant-xxxxxxxx roles: [chat, edit, apply] defaultCompletionOptions: contextLength: 200000 maxTokens: 64000 capabilities: [tool_use, image_input]源码注释明确指出:这些模型定义是原先 Continue Hub 中anthropic/claude-sonnet-4-6等块的内联副本,由于 slug 解析已移除,改为直接内联并在写入时以apiKey替换原${{ inputs.*_API_KEY }}占位符。可见规范文档中的uses:写法是旧机制的遗留描述,实际实现已演进为显式模型配置,读者在阅读旧文档与源码时需留意这一差异。
交互之外的自动场景:测试/CI 环境
源码在 Bedrock 检查之后、交互式提问之前,还有一步隐蔽但重要的判断:若处于测试/CI 环境(NODE_ENV=test、CI=true、VITEST=true、GITHUB_ACTIONS=true或stdin非 TTY),则不会弹出交互提示,而是优先读取环境变量ANTHROPIC_API_KEY并自动写入配置,见 onboarding.ts:
const isTestEnv = process.env.NODE_ENV === "test" || process.env.CI === "true" || process.env.VITEST === "true" || process.env.GITHUB_ACTIONS === "true" || !process.stdin.isTTY; if (isTestEnv) { if (process.env.ANTHROPIC_API_KEY) { console.log(chalk.blue("✓ Using ANTHROPIC_API_KEY from environment")); await createOrUpdateConfig(process.env.ANTHROPIC_API_KEY); console.log(chalk.gray(` Config saved to: ${CONFIG_PATH}`)); return false; } return false; }这意味着在 CI 流水线或任何非 TTY 的无人值守场景中,只需设置ANTHROPIC_API_KEY即可自动完成配置落盘,无需任何交互。e2e 测试 headless-anthropic-api-key.test.ts 即验证了此类 headless 场景(测试通过预写.onboarding_complete标志跳过引导,以-pheadless 模式与--config参数组合运行)。
交互提问与 API Key 校验
在真实终端(TTY)中,CLI 才会打印提示并提问:
console.log(chalk.yellow("To get started, enter your Anthropic API key.")); const apiKey = await question( chalk.white("\nEnter your Anthropic API key: "), );输入后会对 Key 做格式校验,见 apiKeyValidation.ts:
export function isValidAnthropicApiKey( apiKey: string | null | undefined, ): boolean { if (!apiKey || typeof apiKey !== "string") { return false; } // Anthropic API keys must start with "sk-ant-" and have additional characters return apiKey.startsWith("sk-ant-") && apiKey.length > "sk-ant-".length; }即 Anthropic API Key 必须以sk-ant-开头且长度大于该前缀。校验失败会抛出带具体原因的错误(如"API key must start with "sk-ant-""、"API key is too short")。校验通过后调用createOrUpdateConfig(apiKey)落盘,并打印✓ Config file updated successfully at ~/.continue/config.yaml。
配置写入的细节:保留注释与权限收紧
createOrUpdateConfig()完成两件关键工作,见 onboarding.ts:
- 目录与文件准备:确保
~/.continue目录存在(mkdirSync(..., { recursive: true })),读取已有内容(若文件不存在则为空字符串); - YAML 更新:调用
updateAnthropicModelInYaml(existingContent, apiKey)生成新内容并写回,最后调用setConfigFilePermissions(CONFIG_PATH)收紧文件权限。
updateAnthropicModelInYaml的实现(yamlConfigUpdater.ts)有几个值得注意的设计:
- 使用
yaml库的parseDocument以AST 级操作修改 YAML,保留原有注释和格式,而非粗暴的字符串替换; - 若文件为空/不存在,则生成一个全新的
Main Config(name: Main Config、version: 1.0.0、schema: v1); - 若文件已存在,会先过滤掉所有旧版 Anthropic 模型再追加新模型——过滤规则同时覆盖两类:以
uses: anthropic/开头的旧 slug 块,以及 provider 为anthropic且模型为claude-sonnet-4-6/claude-opus-4-6的显式模型(见isManagedAnthropicModel),避免重复写入; - 即使整个 YAML 解析失败,也会兜底生成全新配置而非抛错。
引导完成后的正常流程(Normal Flow)
当用户已经完成过引导(.onboarding_complete标志存在),后续每次运行cn都走正常配置加载流程,规范文档定义的顺序为:
- 若提供
--config参数,加载该配置(最高优先级); - 若用户已登录,在所选 org 中查找第一个 assistant;
- 若该 org 没有 assistant,则查找本地
~/.continue/config.yaml; - 若仍没有
config.yaml,则查找环境变量ANTHROPIC_API_KEY,并手工构造仅含该 Key 的 claude-4-sonnet 模型配置; - 若以上全部不满足,则把用户带回到引导流程的 Step 3(即交互式选项页)。
这套"降级链"与配置加载规范 config-loading.md 中的优先级规则一致:--configflag > 已保存的配置 URI > 默认解析(已登录用户取第一个 assistant / 本地 config.yaml / 未登录回退默认配置)。实际加载逻辑在 configLoader.ts 中实现,其determineConfigSource依次判断 CLI flag 与本地config.yaml的存在性。
引导与正常流程的分发入口
引导与正常流程的切换在initializeWithOnboarding()中完成,它被服务层调用,见 services/index.ts 与 onboarding.ts:
export async function initializeWithOnboarding( authConfig: AuthConfig, configPath: string | undefined, ) { const firstTime = await isFirstTime(); if (configPath !== undefined) { // throw an early error is configPath is invalid or has errors try { await loadConfiguration( authConfig, configPath, getApiClient(undefined), [], false, ); } catch (errorMessage) { throw new Error( `Failed to load config from "${configPath}": ${errorMessage}`, ); } } if (!firstTime) return; const wasOnboarded = await runOnboardingFlow(configPath); if (wasOnboarded) { await markOnboardingComplete(); } }这段代码清晰展示了三条路径:
- 显式
--config:先立即预加载配置以尽早暴露错误(文件不存在、YAML 非法、缺少必填字段都会在这里抛出带路径的明确错误),且无论是否首次都不再进入引导; - 首次运行:进入
runOnboardingFlow,若其返回true(例如走了 Bedrock 分支或成功写入 API Key),则写入完成标志; - 非首次运行:直接跳过,交给正常配置加载。
实践建议与常见场景
综合规范与源码,针对不同使用场景给出如下操作建议:
| 场景 | 推荐做法 |
|---|---|
| 桌面终端首次使用 | 直接运行cn,在交互引导中选择"登录 Continue"或"输入 Anthropic API Key" |
| 使用 AWS Bedrock 且已配好 AWS 凭证 | export CONTINUE_USE_BEDROCK=1后运行cn,自动跳过交互并打印✓ Using AWS Bedrock |
| CI / 无 TTY 环境 | 设置ANTHROPIC_API_KEY环境变量后以 headless 模式运行(如cn -p "prompt"),或直接用--config指向预置的 YAML |
| 已写好配置文件想跳过引导 | 使用--config参数显式指定配置;或手工创建~/.continue/.onboarding_complete标志文件 |
显式--config指向的文件损坏 | CLI 会立即报错退出并给出文件路径,不会静默回退,便于在流水线中尽早发现配置问题 |
小结
Continue CLI 的 onboarding 机制围绕一个简单的事实抽象展开:用.onboarding_complete标志区分"首次"与"常态"。首次运行通过--config、CONTINUE_USE_BEDROCK、CI 环境变量、交互提问这四条路径收敛到一个可用的模型配置;完成标记写入后,后续运行进入以--config> 已登录 assistant > 本地 config.yaml > 环境变量 API Key 为序的正常加载链。理解这套流程,既能帮助你在首次使用时顺利配置模型,也能让 CI、容器、无头服务器等无人值守场景稳定地跳过交互、直连目标模型。
对实现细节感兴趣的读者,可继续研读以下仓库文件:onboarding 规范、onboarding 源码、onboarding 测试、配置加载规范、配置加载实现、YAML 更新工具、API Key 校验。
【免费下载链接】continueopen-source coding agent项目地址: https://gitcode.com/GitHub_Trending/co/continue
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考