ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

GSD Headless 答案注入完全指南:用 `--answers` 预置答案与密钥,实现零交互的全自动软件构建

GSD Headless 答案注入完全指南:用 `--answers` 预置答案与密钥,实现零交互的全自动软件构建 人工智能AI Agent代码智能体Agent 编排CLIAI 应用【免费下载链接】gsd-2A powerful meta-prompting, context engineering and spec-driven development system that enables agents to work for long periods of time autonomously without losing track of the big picture项目地址https://gitcode.com/gh_mirrors/gs/gsd-2点击查看免费下载导读本文围绕 GSDgsd-2开源仓库中 gsd-orchestrator/references/answer-injection.md 所定义的Answer Injection答案注入机制展开系统讲解在 headless无头执行模式下如何通过--answers参数预置问题答案与敏感密钥从而消除交互式提示让 Agent 可以长时间无人值守地自主完成从 spec 到可运行软件的完整构建流程。读完本文你将掌握答案文件的完整 JSON Schema 与校验约束、secrets 注入的环境变量链路、两阶段问题关联的底层实现以及它如何与--supervised监督模式分层协作。为什么需要答案注入headless 模式的最后一公里问题GSD 的 headless 模式面向的是完全自主的软件交付场景Agent 以子进程方式调用gsd headlessGSD 在内部负责规划、编码、测试、提交的全流程见 gsd-orchestrator/SKILL.md 的 mental model。但构建过程中 Agent 不可避免地会遇到需要人来拍板的时刻——比如 LLM 调用ask_user_questions工具向用户询问部署目标、技术选型或者secure_env_collect工具请求用户输入 API Key。在无人值守的 CI 或长时运行场景里任何一次交互式弹窗都可能让整个流程卡死。Answer Injection 正是为解决这一问题而设计在启动 headless 会话之前把所有可能被问到的答案和需要用到的密钥写进一个 JSON 文件通过--answers参数预置GSD 在运行中自动代答让整个构建过程零人工介入。从源码结构看该能力由 src/headless-answers.ts 独立模块实现并由 src/headless.ts 的 headless 主流程集成。它同时被打包进 GSD 扩展技能文档 src/resources/extensions/gsd/skills/gsd-headless/references/answer-injection.md说明这套机制既服务 CLI 用户也面向使用该技能的自主 Agent。CLI 用法--answers与命令的组合方式答案注入通过 headless 的--answers标志启用其值指向一个包含预置答案与密钥的 JSON 文件路径# 直接进入 auto 模式自动执行全部排队的单元直至里程碑完成 gsd headless --answers answers.json auto # 从 spec 文件创建里程碑并链式进入 auto 模式 gsd headless --answers answers.json new-milestone --context spec.md --auto两条命令展示了两种典型场景前者用于在已初始化的项目上继续/恢复自动构建后者用于写 spec → 建里程碑 → 立即自动执行的全新构建链路。注意一个细节new-milestone --auto会在里程碑创建成功后自动链入 auto 阶段此时--answers文件会在两个阶段都持续生效详见后文 headless.ts 的milestoneReady链式逻辑。从 src/headless.ts 可以看到启动时的加载逻辑headless 入口解析options.answers路径后调用loadAndValidateAnswerFile若文件不存在、JSON 非法或 schema 不满足约束会在启动阶段直接向 stderr 输出错误并以退出码 1 终止——答案文件的问题会被快速失败而不是等构建跑到一半才暴露。另外需要注意 headless 的一个通用约束标志必须放在命令之前gsd headless [--flags] [command] [args]放在命令之后的标志会被忽略见 gsd-orchestrator/SKILL.md 的 critical rules。答案文件 Schema 详解答案文件是一个顶层 JSON 对象包含questions、secrets、defaults三个可选字段{ questions: { question_id: selected_option_label, multi_select_question: [option_a, option_b] }, secrets: { API_KEY: sk-..., DATABASE_URL: postgres://... }, defaults: { strategy: first_option } }各字段语义如下字段类型说明questionsRecordstring, string \| string[]问题 ID → 答案的映射。单选框用字符串选项 label多选框用字符串数组多个选项 label。secretsRecordstring, string环境变量名 → 值的映射。会被注入到子进程的环境变量中。defaults.strategyfirst_option \| cancel未匹配问题的兜底策略。first_option为默认值自动选择第一个可用选项cancel表示直接取消该请求。其中questions的 key 是问题的稳定标识符question ID。这个 ID 由调用ask_user_questions工具的 LLM 生成规范要求使用 snake_case见 src/resources/extensions/ask-user-questions.ts 中QuestionSchema对id的约束Stable identifier for mapping answers (snake_case)。要精确命中某个问题ID 必须与运行中实际出现的一致。从源码看 Schema 的严格校验loadAndValidateAnswerFilesrc/headless-answers.ts对答案文件执行逐字段校验任何一项不满足都会抛出明确错误并终止启动文件内容必须是合法 JSON否则报Invalid JSON in answer file: path顶层必须是纯对象非数组、非 null否则报Answer file must be a JSON objectquestions必须是对象且每个值必须是字符串或全部为字符串的数组否则报Answer file questions.key must be a string or string[]secrets必须是对象且每个值必须是字符串否则报Answer file secrets.key must be a stringdefaults.strategy只能是first_option或cancel否则报对应错误。这些校验规则与 src/resources/extensions/gsd/tests/headless-answers.test.ts 中的测试一一对应如invalid JSON、wrong types用例说明这是一条被测试覆盖的稳定契约。Secrets 注入机制密钥如何直达子进程答案文件中secrets字段的作用是在构建开始前把密钥预灌进子进程的环境变量。文档给出了完整链路Orchestrator或用户通过--answers传递答案文件GSD 读取文件将 secret 值设为子进程的环境变量Agent 内部运行secure_env_collect时checkExistingEnvKeys()发现 key 已存在于process.env该工具跳过交互式输入将 key 报告为 already configured已配置。源码级链路验证在 src/headless.ts 中headless 入口创建 RPC 客户端时把 secrets 作为env选项传入if (injector) { clientOptions.env injector.getSecretEnvVars() } // 同时注入 headless 模式标记 clientOptions.env { ...(clientOptions.env || {}), GSD_HEADLESS: 1 }getSecretEnvVars()src/headless-answers.ts直接返回answerFile.secrets ?? {}即答案文件中的全部 secrets 原样并入子进程环境。在子进程一侧secure_env_collect工具src/resources/extensions/get-secrets-from-user.ts执行时会调用checkExistingEnvKeys(allKeys, envPath)检测 key 是否已存在对已存在的 key汇总界面会标注already set且不会进入逐页掩码输入流程。这正是skip the interactive prompt的实现来源。安全特性文档明确强调 secrets 从不被记录日志、也不进入事件流。这一点与secure_env_collect的 promptGuidelines 一致——工具在输出中只报告 key 名与 applied/skipped 状态绝不回显值src/resources/extensions/get-secrets-from-user.ts。因此在答案文件中写入真实密钥时务必确保该文件本身不被纳入版本控制、不被事件流捕获。问题匹配的两阶段关联机制Answer Injection 的核心难点在于headless 进程以事件流方式工作问题不是预先知道的而是运行中动态出现的。因此注入器采用两阶段关联Observe观察— GSD 监听tool_execution_start事件中工具名为ask_user_questions的调用从中提取问题元数据ID、选项列表、allowMultiple标志Match匹配— 后续到达的extension_ui_request事件被关联到对应元数据并以预置答案回复。实现细节以 title 为关联键在 src/headless-answers.ts 的observeEvent中注入器从event.input?.questions或event.args?.questions解析每个问题把header与question拼接成header: question形式的 title连同id、options、allowMultiple一起存入questionMetaByTitleMap。而在tryHandlesrc/headless-answers.ts中extension_ui_request事件通过其title字段反查元数据——与 src/resources/extensions/ask-user-questions.ts 中ctx.ui.select(\${q.header}: ${q.question}, ...) 的拼装方式保持一致这就是问题 ID → 答案得以匹配的底层桥梁。乱序事件与 500ms 延迟队列在 RPC 模式下事件顺序并不总是严格extension_ui_request可能先于tool_execution_start到达。此时元数据尚未建立注入器无法立即匹配。处理方式是延迟处理队列若查不到元数据事件先被放入deferredEvents队列并设置 500ms 定时器若在 500ms 内observeEvent带入了对应元数据定时器被清除事件立即按预置答案处理processWithMeta若 500ms 内仍无元数据则按defaults.strategy兜底first_option回复第一个选项cancel发送取消响应。src/resources/extensions/gsd/tests/headless-answers.test.ts 中的tryHandle deferred resolution — observeEvent after tryHandle用例专门验证了先收到 UI 请求、后收到元数据的乱序场景事件先被延迟observeEvent到达后立刻同步解析并发出正确应答。匹配与校验逻辑答案必须落在选项内processWithMetasrc/headless-answers.ts是最终应答的决策点单选allowMultiple为假答案取字符串若配置成数组则取首元素且必须存在于事件的 options 列表中才被接受否则走兜底策略多选答案必须是数组且每个值都必须存在于 options 中才会以values字段整体回复兜底策略为first_option且答案无效时processWithMeta返回false把处理权交还给内置自动应答器见下文。这保证了注入器不会发送一个不在选项中的非法答案——预置答案与运行时选项不一致时系统会优雅降级而不是中断。与--supervised监督模式的共存优先级答案注入不是唯一的自动应答手段。headless 还支持--supervised模式把交互式 UI 请求通过 stdout/stdin 转发给外部 orchestrator 处理。两者可以同时启用构成三层优先级Answer injector 先尝试— 若有匹配的预置答案直接回复若无答案交给 supervised 模式— 转发给 orchestrator 等待其响应若超过--response-timeout仍未收到 orchestrator 响应内置自动应答器接管。在 src/headless.ts 的事件处理中可以看到这一顺序的实现extension_ui_request到达后先调用injector.tryHandle(...)只有返回false未处理且处于 supervised 模式时才设置responseTimeout定时器等待外部响应超时后回落到handleExtensionUIRequest内置自动应答器。--response-timeout的默认值为 30000ms见 gsd-orchestrator/SKILL.md 的 flags 表。另外注入器只会处理method select的事件confirm、input、editor等方法直接交给自动应答器或 supervised 链路处理。无答案注入时的内置自动应答即使完全不使用--answersheadless 模式也内置了针对所有提示类型的自动应答器保证流程不会卡死提示类型默认行为Select选择第一个选项Confirm自动确认Input返回空字符串Editor返回预填内容或空答案注入的价值在于当自动选择第一个选项这种默认行为不够精确时例如部署目标必须是 GCP 而不是列表首位的 AWS用具体答案覆盖默认行为实现精确决策。二者是默认兜底 精准覆盖的关系。诊断统计与未使用警告为了便于排查注入器会跟踪三类统计信息并打印在会话结束的摘要中统计项说明questionsAnswered从答案文件中命中的问题数questionsDefaulted由兜底策略处理的问题数secretsProvided注入的密钥数量在 src/headless.ts 中会话收尾时会输出[headless] Answers: 3 answered, 1 defaulted, 2 secrets此外未使用的 question ID 与 secret key 会在退出时给出警告。getUnusedWarnings()src/headless-answers.ts会逐一检查答案文件中配置的每个问题 ID 与密钥是否实际被消费未匹配的生成类似以下警告[answers] Warning: question ID deploy_target was never matched [answers] Warning: secret OPENAI_API_KEY was provided but never requested这套机制非常实用它能在运行结束后帮你发现答案文件写错了 ID/键名或多余的密钥配置避免长期带病运行。对应测试getUnusedWarnings reports unused question IDs and secret keyssrc/resources/extensions/gsd/tests/headless-answers.test.ts验证了已用项不告警、未用项必告警的行为。实战示例Orchestrator 全自动构建 结果解析将以上所有机制组合起来就是一个完整的答案注入 JSON 输出 结果解析实战流程。文档给出了可直接运行的示例# 创建答案文件 cat answers.json EOF { questions: { test_framework: vitest, package_manager: pnpm }, secrets: { OPENAI_API_KEY: sk-..., DATABASE_URL: postgres://localhost:5432/mydb }, defaults: { strategy: first_option } } EOF # 使用预置答案运行--output-format json 下结构化结果走 stdout进度走 stderr gsd headless --answers answers.json --output-format json auto 2/dev/null # 解析结果 RESULT$(gsd headless --answers answers.json --output-format json next 2/dev/null) echo $RESULT | jq {status: .status, cost: .cost.total}几个实践要点2/dev/null是必须的JSON 结构化结果输出到 stdout而进度、统计、警告都输出到 stderr解析 JSON 时务必重定向 stderr否则会污染管道这是 gsd-orchestrator/SKILL.md 的 critical rules 之一。配合query轮询运行auto后用gsd headless query约 50ms、无 LLM 成本检查状态而不是反复调用auto。配合退出码判断0成功1错误/超时10阻塞需要介入11取消。当构建以 10 阻塞时检查.gsd/STATE.md与最后的阻塞通知决定是补充答案还是人工介入。next单步执行--answers同样适用于next单步命令适合编排者逐步推进并逐次解析结果。关于构建状态的完整字段说明可参考 gsd-orchestrator/references/json-result.md完整命令与标志参考见 gsd-orchestrator/references/commands.mdOrchestrator 的轮询与分步工作流见 gsd-orchestrator/workflows/monitor-and-poll.md 与 gsd-orchestrator/workflows/step-by-step.md。小结Answer Injection 是 GSD headless 自主构建体系中的关键拼图questions解决决策的自动化secrets解决凭证的自动化defaults.strategy解决未知情况的兜底而严格的 schema 校验、两阶段事件关联、500ms 乱序补偿、统计与未使用警告共同保证了这套机制在无人值守环境下的可靠性与可诊断性。对任何希望把 GSD 接入 CI、或由外部 Agent 长时间自主编排构建的团队而言--answers都是最值得优先掌握的 headless 能力之一。赞分享人工智能AI Agent代码智能体Agent 编排CLIAI 应用【免费下载链接】gsd-2A powerful meta-prompting, context engineering and spec-driven development system that enables agents to work for long periods of time autonomously without losing track of the big picture项目地址https://gitcode.com/gh_mirrors/gs/gsd-2点击查看免费下载相关推荐GSD 命令参考全指南从交互式会话到 Headless 自动化GSD 命令参考全指南从交互式会话到 Headless 自动化 这篇技术指南以 GSDGitHub 加速计划 / gsd 2的命令体系为主线完整梳理会话人工智能AI Agent代码智能体Agent 编排CLIAI 应用GSD 远程问答Remote Questions全指南在 Slack、Discord、Telegram 上驱动 Headless Auto-ModeGSD 远程问答Remote Questions全指南在 Slack、Discord、Telegram 上驱动 Headless Auto Mode 远程人工智能AI Agent代码智能体Agent 编排CLIAI 应用GSD 命令完全参考从 /gsd auto 自主模式到 Headless 自动化的实战指南GSD 命令完全参考从 /gsd auto 自主模式到 Headless 自动化的实战指南 GSDGet Shit Done是一套基于 meta prom人工智能AI Agent代码智能体Agent 编排CLIAI 应用上一篇check-if-email-exists 的 is_reachable 字段完全解读从四种投递状态到完整响应 JSON下一篇devops-exercises 实战指南AWS EC2 Elastic IP 静态公网 IP 分配、关联与最佳实践创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表