尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

gemini-cli Headless 模式实战:以 JSON/JSONL 输出与退出码构建可靠的终端自动化管道

gemini-cli Headless 模式实战:以 JSON/JSONL 输出与退出码构建可靠的终端自动化管道 gemini-cli Headless 模式实战以 JSON/JSONL 输出与退出码构建可靠的终端自动化管道【免费下载链接】gemini-cliAn open-source AI agent that brings the power of Gemini directly into your terminal.项目地址: https://gitcode.com/GitHub_Trending/gemi/gemini-cli本文围绕 Gemini CLI 的 Headless无头模式展开介绍其触发方式、--output-format的三种输出格式与完整 JSON 事件 Schema、全部退出码语义并结合开源仓库中的格式化器源码、非交互执行主循环与集成测试说明如何把 gemini-cli 作为可编程组件嵌入 CI/CD、批处理脚本和自定义 AI 工具中最终让读者具备从命令构造、结构化数据提取到错误处理的完整自动化能力。什么是 Headless 模式Headless 模式为 gemini-cli 提供了一个程序化接口模型响应以结构化的纯文本或 JSON 输出不启动任何交互式终端 UITUI执行完一次查询后立即退出。这是把 CLI 当作管道中的一个命令来使用的基础。根据 Headless 模式参考文档Headless 模式在以下任一条件满足时被触发非 TTY 环境当 CLI 的 stdin 或 stdout 被重定向/管道例如在 CI 任务中运行它会自动以无头方式执行显式提供-p/--prompt标志gemini -p ...强制进入非交互模式。位置参数不带-p的gemini query在 TTY 中默认进入交互模式除非输入或输出被管道或重定向捕获——这一点在 CLI 速查表 的 Positional arguments 部分有明确说明。典型适用场景见 自动化教程CI/CD自动分析 Pull Request批处理批量摘要日志文件构建工具编写自己的 AI wrapper 脚本。最简用法gemini -p Write a poem about TypeScript底层实现非交互执行主循环从源码结构看非交互模式的核心实现位于 runNonInteractive。入口函数首先检查是否启用了 Agent 会话新链路config.getAgentSessionNoninteractiveEnabled()若启用则委托给 nonInteractiveCliAgentSession否则走经典循环根据config.getOutputFormat()决定是否创建StreamJsonFormatter若输入是斜杠命令则先由handleSlashCommand处理随后经handleAtCommand展开file引用展开失败会抛出FatalInputError这正是退出码 42 的来源之一进入while循环调用geminiClient.sendMessageStream逐事件消费模型响应Content事件文本模式下直接写 stdoutJSON 模式下累积到responseTextstream-json 模式下逐片段delta: true发出message事件ToolCallRequest事件交给Scheduler调度执行工具结果回传模型继续下一轮AgentExecutionStopped/AgentExecutionBlocked等事件写出最终结果并终止。值得注意的工程细节ANSI 清理程序化输出格式JSON、STREAM_JSON会对消息做宽松 sanitization通过stripAnsi剥离 ANSI 转义序列保证下游jq等工具拿到的是干净可解析的文本见 runNonInteractive 的注释与 L343 的实现EPIPE 处理当输出管道被下游提前关闭例如gemini -p ... | head -1进程捕获 stdout 的EPIPE错误并优雅退出避免脚本因管道破裂而报错非交互主循环CtrlC 支持即便在非交互模式若 stdin 是 TTY 也会监听 CtrlC 触发abortController.abort()取消流程最终以标准退出码收尾。输出格式--output-format通过--output-format别名-o指定输出格式取值text、json、stream-json默认text。三个值的定义见 OutputFormat 枚举export enum OutputFormat { TEXT text, JSON json, STREAM_JSON stream-json, }JSON 输出--output-format json返回单个 JSON 对象包含响应与使用统计。结合 JsonFormatter 源码 与 JsonOutput 类型定义完整 Schema 如下字段类型说明session_idstring本次会话 ID可用于--resume session-id续接responsestring模型最终答案已剥离 ANSI 序列statsobjectToken 用量与 API 延迟指标SessionMetricserrorobject, 可选请求失败时的错误详情{ type, message, code? }warningsstring[], 可选非致命警告如检测到循环、达到最大轮数等失败路径由 handleError 统一处理JSON 模式下调用formatter.formatError生成{ session_id, error: { type, message, code } }结构打印后以对应退出码退出。实际脚本中最常用的组合是与jq提取response字段。例如引自 自动化教程gemini --output-format json Return a raw JSON object with keys version and deps from package.json | jq -r .response data.json该输出结构并非文档推断——仓库中的集成测试 json-output.test.ts 验证了返回包含 response 与 stats 的合法 JSON返回带 session ID 的 JSONJSON 模式下工具错误允许模型自我修正而不立即退出等关键行为配套录制响应位于 json-output.france.responses 等 fixture。Streaming JSON 输出stream-json--output-format stream-json返回换行分隔的 JSON 事件流JSONL每个事件一行、实时写入 stdout适合构建需要观察中间过程工具调用、增量文本的编排器。实现见 StreamJsonFormatterformatEvent对每个事件执行JSON.stringify(event) \n后直接process.stdout.write。事件类型定义在 JsonStreamEventType 枚举共 6 种事件type载荷关键字段说明initsession_id,model会话元数据会话 ID、模型messageroleuser/assistant,content,delta?用户与助手消息助手侧为增量 chunkdelta: truetool_usetool_name,tool_id,parameters工具调用请求及其参数tool_resulttool_id,statussuccess/error,output?,error?已执行工具的产出errorseveritywarning/error,message非致命警告与系统错误如 LoopDetected、安全拦截、InvalidStreamresultstatussuccess/error,stats,error?最终结果含聚合统计与按模型拆分的 token 用量所有事件共享基础字段type与 ISO 时间戳timestamp见 BaseJsonStreamEvent。result事件的stats由 convertToStreamStats 从遥测指标聚合而来包含total_tokens/input_tokens/output_tokens跨模型汇总cached/input缓存 token 统计duration_ms会话总耗时tool_calls工具调用总次数modelsRecordmodelName, { total_tokens, input_tokens, output_tokens, cached, input }即文档所说的 per-model token usage breakdowns——当一次会话中发生模型路由切换时每个模型各自消耗一目了然。init、message、tool_use、tool_result各事件的发射时机可直接在 非交互主循环 中对照阅读init在恢复会话后立刻发出L253-L260message先回显用户输入L302-L309工具结果在Scheduler.schedule完成后逐条发出L494-L512。管道输入把数据喂给 GeminiHeadless 模式完整支持 Unix 管道——CLI 读取 stdin 作为上下文答案写入 stdout引自 自动化教程# 管道一个文件macOS/Linux cat error.log | gemini -p Explain why this failed # Windows PowerShell Get-Content error.log | gemini -p Explain why this failed # 管道一个命令 git diff | gemini -p Write a commit message for these changes一个完整的批处理示例——为目录下所有 Python 文件生成 Markdown 文档#!/bin/bash # generate_docs.sh for file in *.py; do echo Generating docs for $file... gemini -p Generate a Markdown documentation summary for $file. Print the result to standard output. ${file%.py}.md done注意其中$file的 文件引用语法由 atCommandProcessor 处理若文件不存在会报错并触发退出码 42输入错误。退出码Exit codesHeadless 执行结束时CLI 返回标准退出码以指示结果。文档定义的四个基本码为退出码含义0成功1一般错误或 API 失败42输入错误无效的 prompt 或参数53超过最大轮数turn limit exceeded源码中的 FatalError 体系 给出了更完整的退出码表可视为文档的超集退出码错误类触发场景41FatalAuthenticationError认证失败42FatalInputError输入错误如file展开失败、无效 prompt44FatalSandboxError沙箱错误52FatalConfigError配置错误53FatalTurnLimitedError达到maxSessionTurns上限54FatalToolExecutionError致命工具执行错误如磁盘写满 NO_SPACE_LEFT55FatalUntrustedWorkspaceError工作区未被信任130FatalCancellationError操作被取消SIGINT 标准码错误码的提取逻辑见 extractErrorCode / getNumericExitCode优先读取FatalError上的exitCode其次code/status其余情况回落到默认值 1。其中 53 与配置的关联值得说明轮数上限由 settings.json 的maxSessionTurns控制设置 Schema 中默认-1表示不限制Config 在未提供该配置时同样回落为-1。超限时的错误处理统一走 handleMaxTurnsExceededError提示信息也直接指向该配置项Reached max session turns for this session. Increase the number of turns by specifying maxSessionTurns in settings.json. 在stream-json模式下超限还会先以status: error的result事件收尾再退出。在 CI 脚本中即可据此分支gemini -p Run the checks --output-format json case $? in 0) echo OK ;; 42) echo Fix your prompt/arguments ;; 53) echo Agent hit maxSessionTurns - raise the limit ;; *) echo General failure ;; esac实战构建自己的 AI 工具以下三个场景全部来自 自动化教程展示了 Headless 模式 JSON 输出 管道在实际工作中的组合拳。场景一批量文档生成器上文的generate_docs.sh即为此场景循环调用gemini -p利用 stdout 重定向为每个*.py生成同名.md文档。执行方式chmod x generate_docs.sh ./generate_docs.sh场景二提取结构化 JSON 数据#!/bin/bash # generate_json.sh if [ ! -f package.json ]; then echo Error: package.json not found. exit 1 fi # Extract data gemini --output-format json Return a raw JSON object with keys version and deps from package.json | jq -r .response data.jsondata.json预期形如{ version: 1.0.0, deps: { react: ^18.2.0 } }场景三Smart Commitgcommit在 shell 配置中添加一个git commit包装函数function gcommit() { # Get the diff of staged changes diff$(git diff --staged) if [ -z $diff ]; then echo No staged changes to commit. return 1 fi # Ask Gemini to write the message echo Generating commit message... msg$(echo $diff | gemini -p Write a concise Conventional Commit message for this diff. Output ONLY the message.) # Commit with the generated message git commit -m $msg }PowerShell 等价实现见 教程原文。小结与延伸阅读Headless 模式 非 TTY 或-p/--prompt触发--output-format三选text/json/stream-jsonJSON 输出适合一问一答式集成session_idresponsestatsstream-json 适合需要观测工具调用全过程的编排器6 种 JSONL 事件 按模型的 token 统计退出码是自动化可靠性的关键契约0/1/42/53之外FatalError 源码 还定义了 41/44/52/54/55/130 等扩展码相关资源Headless 模式参考文档、自动化教程、CLI 速查表、非交互主循环实现、JSON 格式化器、流式 JSON 格式化器、JSON 输出集成测试。【免费下载链接】gemini-cliAn open-source AI agent that brings the power of Gemini directly into your terminal.项目地址: https://gitcode.com/GitHub_Trending/gemi/gemini-cli创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表