Gemini CLI 非交互模式工具调用问题解析

Gemini CLI 非交互模式工具调用问题解析

问题描述

在使用 gemini -p 非交互模式时,遇到以下错误:

复制代码
Error executing tool write_file: Tool "write_file" not found in registry.
Tools must use the exact names that are registered.
Did you mean one of: "read_file", "write_todos", "glob"?

但是使用 --allowed-tools write_file 后,工具却能正常工作:

bash 复制代码
# ❌ 不工作
gemini -p "生成一个md文件123写入123"

# ✅ 工作
gemini -p "生成一个md文件123写入123" --allowed-tools write_file

根本原因

工具注册正常

通过检查发现,工具确实已经正确注册:

javascript 复制代码
// 已注册的工具数量: 12
工具列表:
  01. list_directory
  02. read_file
  03. search_file_content
  04. glob
  05. replace
  06. write_file          // ✅ 已注册
  07. web_fetch
  08. run_shell_command   // ✅ 已注册
  09. save_memory
  10. google_web_search
  11. write_todos
  12. delegate_to_agent

真正的问题:策略系统限制

文件 : packages/core/src/policy/policies/write.toml

toml 复制代码
# Priority 10: Write tools default to ASK_USER
[[rule]]
toolName = "run_shell_command"
decision = "ask_user"  # ← 默认需要用户确认!
priority = 10

[[rule]]
toolName = "write_file"
decision = "ask_user"  # ← 默认需要用户确认!
priority = 10

[[rule]]
toolName = "web_fetch"
decision = "ask_user"
priority = 10

这些危险工具默认被设置为 ask_user(需要用户确认)。

为什么非交互模式会失败

  1. 策略系统 要求这些工具需要用户确认
  2. 非交互模式(-p 无法请求用户确认
  3. 工具调用被拒绝,返回 "Tool not found" 错误
  4. 当使用 --allowed-tools 时,命令行参数(优先级 2.3)会覆盖默认策略(优先级 1.010)

优先级系统

根据 write.toml 的注释:

复制代码
# Priority bands (tiers):
# - Default policies (TOML): 1 + priority/1000 (e.g., priority 100 → 1.100)
# - User policies (TOML): 2 + priority/1000 (e.g., priority 100 → 2.100)
# - Admin policies (TOML): 3 + priority/1000 (e.g., priority 100 → 3.100)
#
# Settings-based and dynamic rules (all in user tier 2.x):
#   2.95: Tools that the user has selected as "Always Allow" in the interactive UI
#   2.9:  MCP servers excluded list (security: persistent server blocks)
#   2.4:  Command line flag --exclude-tools (explicit temporary blocks)
#   2.3:  Command line flag --allowed-tools (explicit temporary allows)  ← 这里
#   2.2:  MCP servers with trust=true (persistent trusted servers)
#   2.1:  MCP servers allowed list (persistent general server allows)

优先级顺序

  1. ask_user 策略(优先级 1.010)
  2. --allowed-tools 命令行参数(优先级 2.3)

所以 --allowed-tools 会覆盖默认策略!


解决方案

方案 1: 使用 --allowed-tools 参数(推荐用于临时使用)

bash 复制代码
# 允许特定工具
gemini -p "生成文件" --allowed-tools write_file,run_shell_command

# 允许所有危险工具
gemini -p "执行任务" --allowed-tools write_file,run_shell_command,web_fetch,replace

优点

  • ✅ 临时性,不影响全局配置
  • ✅ 灵活,可以按需指定工具
  • ✅ 安全,明确知道哪些工具被允许

缺点

  • ⚠️ 每次都需要输入
  • ⚠️ 需要记住工具名称

方案 2: 使用 YOLO 模式(推荐用于开发环境)

bash 复制代码
# -y 参数自动批准所有工具
gemini -y -p "生成文件"

优点

  • ✅ 简单,只需加一个 -y 参数
  • ✅ 所有工具自动批准
  • ✅ 适合开发环境

缺点

  • ⚠️ 会批准所有工具,包括危险操作
  • ⚠️ 不适合生产环境

方案 3: 修改策略文件(推荐用于生产环境)

文件 : packages/core/src/policy/policies/write.toml

toml 复制代码
# 将 ask_user 改为 allow
[[rule]]
toolName = "write_file"
decision = "allow"  # ← 从 "ask_user" 改为 "allow"
priority = 10

[[rule]]
toolName = "run_shell_command"
decision = "allow"  # ← 从 "ask_user" 改为 "allow"
priority = 10

然后重新构建:

bash 复制代码
cd gemini-cli
npm run build
npm run build:packages

优点

  • ✅ 永久性修改
  • ✅ 适合生产环境
  • ✅ 无需每次指定参数

缺点

  • ⚠️ 安全风险:这些工具可以不经确认执行
  • ⚠️ 需要重新构建 CLI
  • ⚠️ 更新代码后需要重新应用修改

方案 4: 创建用户策略文件(最佳方案)

位置 : ~/.gemini/policies/user-tools.toml(用户主目录)

toml 复制代码
# 用户自定义工具策略
# Priority 100: High priority user overrides

[[rule]]
toolName = "write_file"
decision = "allow"
priority = 100

[[rule]]
toolName = "run_shell_command"
decision = "allow"
priority = 100

[[rule]]
toolName = "web_fetch"
decision = "allow"
priority = 100

优先级: 2 + 100/1000 = 2.100(高于默认策略的 1.010)

优点

  • ✅ 永久性修改
  • ✅ 不影响源代码,更新时不会丢失
  • ✅ 可以版本控制
  • ✅ 清晰明确

缺点

  • ⚠️ 安全风险:需要谨慎配置

完整示例

交互模式(默认)

bash 复制代码
# 交互模式下,工具会请求确认
gemini "创建一个 test.txt 文件"

# 输出:
# ⚠️  Tool "write_file" requires confirmation
# Allow this tool call? [y/n]

非交互模式(失败)

bash 复制代码
# 非交互模式无法请求确认,工具被拒绝
gemini -p "创建一个 test.txt 文件"

# 输出:
# Error executing tool write_file: Tool "write_file" not found in registry.

非交互模式 + allowed-tools(成功)

bash 复制代码
# 使用 --allowed-tools 覆盖策略
gemini -p "创建一个 test.txt 文件" --allowed-tools write_file

# 输出:
# ✅ 文件创建成功

非交互模式 + YOLO(成功)

bash 复制代码
# 使用 -y 自动批准所有工具
gemini -y -p "创建一个 test.txt 文件"

# 输出:
# ✅ 文件创建成功

SDK 集成注意事项

SDK 启动 Gemini CLI 时的建议

python 复制代码
import subprocess
import json

# ❌ 错误:工具会被拒绝
proc = subprocess.Popen(
    ["gemini", "-p", "创建文件"],
    stdin=subprocess.PIPE,
    stdout=subprocess.PIPE,
    stderr=subprocess.PIPE
)

# ✅ 方案 1: 使用 --allowed-tools
proc = subprocess.Popen(
    ["gemini", "-p", "创建文件",
     "--allowed-tools", "write_file,run_shell_command,read_file"],
    stdin=subprocess.PIPE,
    stdout=subprocess.PIPE,
    stderr=subprocess.PIPE
)

# ✅ 方案 2: 使用 YOLO 模式(开发环境)
proc = subprocess.Popen(
    ["gemini", "-y", "-p", "创建文件"],
    stdin=subprocess.PIPE,
    stdout=subprocess.PIPE,
    stderr=subprocess.PIPE
)

推荐配置

python 复制代码
# SDK 启动参数
SDK_GEMINI_ARGS = [
    "gemini",
    "-y",  # YOLO 模式(开发)或 "--allowed-tools" (生产)
    "-p",  # 非交互模式
    "--input-format", "stream-json",  # SDK 模式
    "--channel", "SDK"
]

# 或者更安全的配置
SDK_GEMINI_ARGS = [
    "gemini",
    "--allowed-tools", "write_file,run_shell_command,read_file,search_files",
    "-p",
    "--input-format", "stream-json",
    "--channel", "SDK"
]

技术细节

策略检查流程

复制代码
工具调用请求
    ↓
CoreToolScheduler.isAutoApproved()
    ↓
检查 ApprovalMode
    ├─ YOLO → 自动批准
    └─ DEFAULT → 继续
    ↓
检查 allowedTools
    ├─ 匹配 → 自动批准
    └─ 不匹配 → 继续
    ↓
策略系统检查(write.toml)
    ├─ decision = "allow" → 自动批准
    ├─ decision = "ask_user" → 请求确认
    │   ├─ 交互模式 → 显示确认对话框
    │   └─ 非交互模式 → ❌ 拒绝(抛出错误)
    └─ decision = "deny" → ❌ 拒绝

优先级计算

typescript 复制代码
// Default policies (TOML): 1 + priority/1000
priority = 10 → 1.010

// User policies (TOML): 2 + priority/1000
priority = 100 → 2.100

// Command line flags (dynamic): 2.x
--allowed-tools → 2.3
--exclude-tools → 2.4

// 结果:2.3 > 2.100 > 1.010
// 所以 --allowed-tools > 用户策略 > 默认策略

总结

问题 原因 解决方案
非交互模式下工具找不到 策略系统要求用户确认,但非交互模式无法确认 使用 --allowed-tools-y
交互模式下能正常工作 可以请求用户确认 无需修改
--allowed-tools 能工作 命令行参数优先级高于默认策略 推荐用于临时使用

推荐做法

  1. 开发环境 :使用 -y 参数方便开发
  2. 生产环境 :使用 --allowed-tools 明确指定需要的工具
  3. 长期使用 :创建用户策略文件 ~/.gemini/policies/user-tools.toml

安全建议

  • ⚠️ 谨慎使用 YOLO 模式:会批准所有工具,包括危险操作
  • 明确指定工具 :使用 --allowed-tools 只允许需要的工具
  • 审查策略文件 :定期检查 write.toml 和用户策略配置
  • 版本控制策略:将用户策略文件纳入版本控制

文档版本 : 1.0
最后更新 : 2025-01-02
作者: 基于 Gemini CLI 源码分析和问题排查

相关推荐
染指11102 小时前
25.实现过TP保护ACE保护NP保护BE保护EAC保护-内存读写检测(私有句柄表和全局句柄表的句柄提权)-Windows驱动
windows·驱动开发·windows驱动·句柄提权
企鹅侠客2 小时前
第07章—实战应用篇:List命令详解与实战(下)
windows·redis·log4j·list
Huazzi.2 小时前
PowerShell 配置以及使用指南
windows·git·编辑器·shell·powershell·效率
じ☆冷颜〃3 小时前
二分查找的推广及其在排序与链表结构中的关联
网络·windows·经验分享·笔记·算法·链表
古城小栈3 小时前
AI直连Windows:Windows MCP开源,开启无视觉操控新时代
人工智能·windows
冷雨夜中漫步3 小时前
Kubernetes入门笔记 ——(4)Windows搭建k8s测试集群
windows·笔记·kubernetes
星空椰4 小时前
Windows 安装 Oracle 19c Instant Client
数据库·windows·oracle
蒜丶13 小时前
Windows 11 22H2 跳过联网激活
windows
摘星编程16 小时前
Elasticsearch(es)在Windows系统上的安装与部署(含Kibana)
windows·elasticsearch·kibana