Appearance
非交互模式 — 练习
练习 1:使用 Exec 模式执行指令
尝试使用 codex exec 命令执行一个简单的代码生成任务,观察输出格式。
参考答案
使用 codex exec "创建一个 hello world Python 程序" 执行,流程如下:
CLI 解析:
exec::run_main()解析Cli参数,command字段为"创建一个 hello world Python 程序"初始化:加载配置、认证,创建 in-process app-server client
执行:构造
InitialOperation::UserTurn { items, output_schema: None },提交到 thread事件流(JSON 模式
--experimental-json):json{"type": "TurnStartedEvent", "thread_id": "..."} {"type": "AgentMessageItem", "content": "我来为你创建一个 hello world 程序"} {"type": "CommandExecutionItem", "command": "echo 'print(\"hello world\")' > hello.py", "stdout": "", "exit_code": 0} {"type": "FileChangeItem", "path": "hello.py", "change": "created"} {"type": "TurnCompletedEvent", "usage": {"input_tokens": 1234, "output_tokens": 567}}退出:turn 完成后,程序以
CodexStatus::Success退出,退出码 0
文本模式下的输出是彩色的人类可读格式,包含相同的操作信息但以更友好的方式呈现。
练习 2:分析 Exec 模式执行流程
追踪 Exec 模式从接收指令到输出结果的完整执行流程。
参考答案
Exec 模式的完整执行流程(exec/src/lib.rs):
run_main(cli, paths)— 主入口:- 解析 CLI 参数(
Clistruct) - 确定
codex_home和配置路径 - 加载
Config和CloudConfigBundle
- 解析 CLI 参数(
初始化 App Server:
- 创建
ExecRunArgs,包含in_process_start_args - 启动 in-process app-server client(无需外部守护进程)
- 初始化
StateDbHandle用于状态持久化
- 创建
解析 Prompt:
- 从
command字段获取命令行 prompt - 若
command为空,从 stdin 读取 - 构造
InitialOperation::UserTurn { items, output_schema }
- 从
启动/恢复 Thread:
- 新建 thread:调用 app-server 的
start_thread请求 - 恢复 thread:使用
--resume参数指定 thread ID
- 新建 thread:调用 app-server 的
事件循环(
EventProcessor):- 从
rx_event接收Event - 根据事件类型映射为
ThreadEvent - JSON 模式:每个事件序列化为一行 JSON
- 文本模式:格式化为人类可读的彩色文本
- 从
交互请求处理:
- 所有
ServerRequest自动生成拒绝响应 - 不等待用户输入,保持无交互执行
- 所有
终止:
- Turn 完成或失败后退出事件循环
- 返回
CodexStatus(Success/Failed) - 清理资源(关闭连接、释放 state_db)
练习 3:对比 TUI 和 Exec 的安全策略
对比两种模式下的沙箱策略和权限差异。
参考答案
TUI 和 Exec 模式共享同一套沙箱基础设施(SandboxManager、ExecPolicy),但安全策略的应用方式有显著差异:
共同基础:
关键差异:
| 安全维度 | TUI 模式 | Exec 模式 |
|---|---|---|
| 审批处理 | 用户实时审批/拒绝 | 所有请求自动拒绝 |
| 权限提升 | 用户可临时授权 | 无法提升权限 |
| ExecPolicy | Allow + Prompt 都可执行 | 仅 Allow 可执行 |
| 沙箱配置 | 标准配置 | 可配置更严格 |
| 失败处理 | 用户可重试/调整 | 直接失败退出 |
| 网络策略 | 用户可审批网络请求 | 遵循预配置规则 |
Exec 模式的安全含义:
- 由于所有交互请求自动拒绝,只有
Decision::Allow的命令能成功执行 - 这意味着 Exec 模式的
ExecPolicy必须预先配置好所有需要的命令权限 - 不适合需要高权限操作的场景(如系统包安装、全局配置修改)
- 最适合预定义任务(如代码生成、测试运行、文件操作)
最佳实践:
- 为 Exec 模式配置专门的
ExecPolicyprofile,只允许必要的命令 - 使用
output_schema_path约束输出结构,减少意外行为 - 在 CI/CD 中使用最小权限原则配置沙箱
拓展挑战
- 分析
EventProcessorWithJsonOutput的 JSON 序列化实现 - 阅读
ExecRunArgs的所有字段,理解每个参数的作用 - 追踪
--resume模式下 thread 恢复的完整流程 - 分析
CodexStatus的所有变体和对应的退出码