S
Codex SDK 教程 TypeScript
第 06 章

高级特性

高级特性

这章把 SDK 剩下的高级功能一网打尽:全局配置、线程配置、线程恢复、多模态输入、取消控制、实用技巧。

CodexOptions — 全局配置

创建 Codex 实例时,可以传入全局配置:

typescriptimport { Codex } from "@openai/codex-sdk";

const codex = new Codex({
  // API 端点(默认用 OpenAI 官方,换成兼容接口也行)
  baseUrl: "https://api.openai.com/v1",

  // API Key(默认读 OPENAI_API_KEY 环境变量,这里可以覆盖)
  apiKey: "sk-...",

  // 传给 CLI 的 --config 参数(SDK 会自动转成 TOML 格式)
  config: {
    show_raw_agent_reasoning: true,
    sandbox_workspace_write: { network_access: true },
    retry_budget: 3,
  },

  // 完全控制 CLI 子进程的环境变量
  // ⚠️ 一旦设了这个,就不会继承 process.env
  env: {
    PATH: "/usr/local/bin:/usr/bin",
    HOME: process.env.HOME!,
  },
});

各字段说明

字段 类型 作用 默认值
baseUrl string API 端点 URL 环境变量 OPENAI_BASE_URL
apiKey string API 密钥 环境变量 OPENAI_API_KEY
config object CLI 的 --config 覆盖
env Record<string, string> CLI 子进程环境变量 继承 process.env
codexPathOverride string 手动指定 CLI 二进制路径 自动查找

config 对象怎么工作

config 对象会被 SDK 自动"扁平化"成 CLI 的 --config key=value 参数。比如:

typescriptconfig: {
  sandbox_workspace_write: { network_access: true },
}

等价于命令行:

bashcodex exec --config 'sandbox_workspace_write.network_access=true'

你不用关心转换细节,直接写 JavaScript 对象就行。

ThreadOptions — 线程级配置

每个 Thread 可以单独配置:

typescriptconst thread = codex.startThread({
  model: "o4-mini",
  sandboxMode: "workspace-write",
  workingDirectory: "/path/to/project",
  skipGitRepoCheck: false,
  modelReasoningEffort: "high",
  networkAccessEnabled: true,
  webSearchMode: "live",
  approvalPolicy: "never",
  additionalDirectories: ["../shared-lib", "/tmp/data"],
});

配置项详解

选项 类型 作用 可选值
model string 使用的模型 任意模型名,如 "o4-mini", "gpt-4"
sandboxMode SandboxMode 沙箱权限级别 "read-only" / "workspace-write" / "danger-full-access"
workingDirectory string AI 的工作目录 绝对路径
skipGitRepoCheck boolean 跳过 Git 仓库检查 默认 false
modelReasoningEffort ModelReasoningEffort 思考深度 "minimal" / "low" / "medium" / "high" / "xhigh"
networkAccessEnabled boolean 允许网络访问 默认 false
webSearchMode WebSearchMode Web 搜索模式 "disabled" / "cached" / "live"
approvalPolicy ApprovalMode 命令批准策略 "never" / "on-request" / "on-failure" / "untrusted"
additionalDirectories string[] 额外可访问的目录 路径数组

沙箱模式怎么选

模式 权限 适用场景
read-only 只能读文件,不能写、不能执行危险命令 代码分析、审查(最安全)
workspace-write 能读写工作目录内的文件 写代码、改文件(推荐日常用)
danger-full-access 啥都能干 系统管理任务(谨慎使用)

推理深度怎么选

级别 Token 消耗 适用场景
minimal / low 简单问题、快速回复
medium 中等 一般任务(默认)
high / xhigh 复杂推理、代码分析、架构设计

线程恢复 — 保存和恢复对话

线程数据保存在 ~/.codex/sessions/ 目录。只要拿到 thread.id,随时可以恢复对话。

保存线程 ID

typescriptconst codex = new Codex();
const thread = codex.startThread();

// ⚠️ thread.id 在第一次 run() 之后才有值
const turn = await thread.run("帮我分析这个项目");
console.log("Thread ID:", thread.id);

// 保存到文件/数据库
const threadId = thread.id!;

恢复线程

typescript// 之后的程序里
const savedId = "之前保存的 thread id";
const codex = new Codex();
const thread = codex.resumeThread(savedId);

// 继续对话,AI 记得之前聊了什么
const turn = await thread.run("继续上次的工作,帮我把那个 bug 修了");

实用场景

  • 程序崩了:重启后用保存的 ID 恢复,不用重新开始
  • 分阶段执行:第一天分析,第二天改代码,用同一个线程
  • 持久化对话:给每个用户/频道分配一个线程 ID,实现长期记忆

多模态输入 — 文字 + 图片

run() 的 input 参数不只能传字符串,还能传一个数组,混合文字和图片:

typescriptconst turn = await thread.run([
  { type: "text", text: "看看这个 UI 截图有什么问题,给出改进建议" },
  { type: "local_image", path: "./screenshot.png" },
]);

console.log(turn.finalResponse);

传多张图片也行:

typescriptconst turn = await thread.run([
  { type: "text", text: "对比这两个版本的界面设计" },
  { type: "local_image", path: "./v1.png" },
  { type: "local_image", path: "./v2.png" },
]);

注意

  • 图片只支持本地文件路径(local_image),不支持 URL
  • 支持常见图片格式:PNG、JPG、WebP 等

AbortSignal — 优雅取消

如果 AI 跑太久了,你想取消怎么办?用 AbortSignal

超时取消

typescriptconst controller = new AbortController();

// 30 秒后自动取消
setTimeout(() => controller.abort(), 30_000);

try {
  const turn = await thread.run("分析这个超大项目", {
    signal: controller.signal,
  });
  console.log(turn.finalResponse);
} catch (err) {
  if (err instanceof Error && err.name === "AbortError") {
    console.log("⏰ 超时了,已取消");
  } else {
    throw err;
  }
}

手动取消

typescriptconst controller = new AbortController();

// 在流式模式下,收到某个条件就取消
const { events } = await thread.runStreamed("执行任务", {
  signal: controller.signal,
});

for await (const event of events) {
  if (event.type === "item.completed" && event.item.type === "command_execution") {
    if (event.item.exit_code !== 0) {
      console.log("命令失败了,取消后续操作");
      controller.abort();
      break;
    }
  }
}

实用技巧集锦

1. 多项目批量处理

typescriptconst projects = ["/path/to/project-a", "/path/to/project-b", "/path/to/project-c"];

for (const dir of projects) {
  const thread = codex.startThread({
    workingDirectory: dir,
    sandboxMode: "read-only",
  });

  const turn = await thread.run("用一句话总结这个项目是做什么的");
  console.log(`${dir}: ${turn.finalResponse}`);
}

2. 链式任务

typescriptconst thread = codex.startThread({ sandboxMode: "workspace-write" });

// 先分析
const analysis = await thread.run("分析项目结构,找出主要问题");
console.log("分析结果:", analysis.finalResponse);

// 再修复(AI 记得上一轮的分析结果)
const fix = await thread.run("修复你刚才发现的最严重的问题");
console.log("修复结果:", fix.finalResponse);

// 再验证
const verify = await thread.run("跑一下测试,确认修复没有引入新问题");
console.log("验证结果:", verify.finalResponse);

3. 成本监控

typescriptlet totalInputTokens = 0;
let totalOutputTokens = 0;

async function trackedRun(thread: Thread, prompt: string) {
  const turn = await thread.run(prompt);
  if (turn.usage) {
    totalInputTokens += turn.usage.input_tokens;
    totalOutputTokens += turn.usage.output_tokens;
  }
  return turn;
}

// 用完后查看总消耗
console.log(`总消耗: 输入 ${totalInputTokens} + 输出 ${totalOutputTokens} tokens`);

4. 并行执行多个线程

typescriptconst tasks = [
  { dir: "/project-a", prompt: "分析代码质量" },
  { dir: "/project-b", prompt: "检查安全漏洞" },
  { dir: "/project-c", prompt: "生成文档" },
];

const results = await Promise.all(
  tasks.map(async ({ dir, prompt }) => {
    const thread = codex.startThread({ workingDirectory: dir });
    const turn = await thread.run(prompt);
    return { dir, response: turn.finalResponse };
  })
);

results.forEach(({ dir, response }) => {
  console.log(`\n📁 ${dir}:\n${response}`);
});

小结

  • CodexOptions 控制全局(API Key、端点、环境变量、config 覆盖)
  • ThreadOptions 控制线程(模型、沙箱、推理深度、网络、批准策略)
  • 线程恢复:thread.id + resumeThread(id) 实现对话持久化
  • 多模态输入:[{ type: "text", ... }, { type: "local_image", ... }]
  • AbortSignal 实现超时和手动取消
  • 批量、链式、并行 — 灵活组合满足各种场景

下一章实战:AI 代码审查机器人 — 综合运用所有知识,构建一个真正有用的工具。