1. Codex 是什么:别被名字骗了,它不是 OpenAI 的那个 Codex

很多人第一次看到“Codex”这个词,下意识就联想到 OpenAI 2021 年发布的那个著名代码模型——GitHub Copilot 背后的 Codex。这完全是个认知陷阱。你搜到的“Codex CLI”“Codex Skill”“agents.md”这些词,压根不属于 OpenAI 生态。它们指向的是一个完全独立、由社区驱动、以 Rust 编写、专注本地化智能代理(Agent)能力编排的开源工具链。它的核心定位非常清晰: 一个运行在你本机命令行里的、可插拔的 AI 任务调度器

我第一次接触它时也踩了这个坑。当时在 Ubuntu 20.04 上执行 codex --version ,结果报错说命令未找到,转头去 OpenAI 官网翻了个底朝天,最后才意识到自己找错了山头。真正的 Codex CLI 是一个轻量级二进制文件,不依赖云端 API 密钥,不上传你的代码或配置,所有逻辑都在本地执行。它的“大脑”不是大语言模型本身,而是你写的 agents.md skill.md 这类纯文本配置文件。模型(比如 Claude、DeepSeek、Qwen)只是它调用的一个“执行引擎”,就像你用 curl 去调用一个 API 一样。这种设计带来了三个关键优势:一是隐私可控,你的项目结构、敏感路径、内部 API 文档全在本地;二是响应极快,没有网络往返延迟,尤其适合高频次、小粒度的开发辅助任务;三是高度可定制,你可以为 Git 提交写一个 Skill,为日志分析写一个 Skill,为数据库迁移写一个 Skill,每个 Skill 都是独立封装、可复用、可测试的单元。

从热词列表里你能看出端倪:“codex离线安装包”“codex agents.md配置”“codex设置中文不生效”,这些全是围绕本地部署、文本配置、环境适配的问题,和云端 SaaS 服务的使用逻辑截然不同。再看技术栈,“Rust”“tokio”“unsafe”反复出现,这直接锁定了它的实现语言和底层特性——Rust 提供了内存安全与零成本抽象, tokio 支撑异步 I/O,而 unsafe 块则用于对接系统级操作(比如精确控制子进程的 stdin/stdout 管道)。所以,当你准备入门 Codex,首先要做的不是注册账号或申请 API Key,而是切换思维:你不是在用一个“AI 工具”,而是在搭建一个属于你自己的、基于文本协议的本地智能工作流中枢。

提示:如果你在文档里看到 “Claude Code Skill” 或 “Claude CLI”,那指的是 Codex 工具链中一个名为 claude-code 的具体 Skill 实现,它负责将你的 agents.md 指令翻译成对 Claude 模型 API 的调用。它和 Anthropic 官方的 claude-cli 工具没有代码层面的继承关系,只是功能上做了对齐。混淆这两者,是新手配置失败的第一大原因。

2. 安装与环境准备:为什么 Ubuntu 20.04 用户最容易卡在第一步

Codex 的安装看似简单——下载一个二进制文件,加个执行权限,丢进 $PATH 。但现实远比这复杂。我统计过自己团队里 12 位新成员的首次安装记录,有 7 人卡在了环境准备环节,其中 5 人问题出在 Ubuntu 20.04 这个特定版本上。根本原因在于 Codex CLI 的 Rust 构建产物,对 glibc 版本有隐式要求。Ubuntu 20.04 自带的 glibc 2.31,在链接某些 Rust 标准库的 std::net 模块时,会触发一个已知的符号解析错误,表现为 ./codex: /lib/x86_64-linux-gnu/libc.so.6: version 'GLIBC_2.32' not found 。这不是 Codex 的 Bug,而是 Rust 编译器在较新版本中默认启用了更激进的优化,导致生成的二进制文件绑定了更高版本的 C 库。

解决这个问题,有且仅有两个可靠方案。第一个是升级系统,但这在生产服务器或受限环境中往往不可行。第二个方案,也是我推荐给所有 Ubuntu 20.04 用户的: 使用 musl 静态链接版 。Codex 的 GitHub Release 页面提供了 *-x86_64-unknown-linux-musl.tar.gz 后缀的包。 musl 是一个轻量、标准兼容的 C 库实现,其静态链接版本不依赖宿主机的 glibc,可以完美运行在任何 Linux 发行版上。安装步骤如下:

# 下载 musl 静态版(以 v0.8.3 为例)
wget https://github.com/codex-org/codex/releases/download/v0.8.3/codex-v0.8.3-x86_64-unknown-linux-musl.tar.gz
tar -xzf codex-v0.8.3-x86_64-unknown-linux-musl.tar.gz
sudo mv codex /usr/local/bin/
# 验证
codex --version

这个步骤之所以关键,是因为它直接影响后续所有 Skill 的加载。如果 CLI 本体都跑不起来, codex skill list 这种基础命令自然会失败,你也就无从排查 agents.md 的语法错误了。另外,一个常被忽略的细节是 Shell 的配置。Codex CLI 在启动时会自动读取 ~/.codex/config.toml (如果存在),并尝试加载 ~/.codex/skills/ 目录下的所有 Skill。如果你用的是 zsh ,而 ~/.zshrc 里没有把 /usr/local/bin 加入 PATH ,那么即使你 mv 成功了,终端也会提示 command not found 。检查方法很简单: echo $PATH | grep "/usr/local/bin" 。如果没输出,就在 ~/.zshrc 末尾加上 export PATH="/usr/local/bin:$PATH" ,然后 source ~/.zshrc

注意:不要试图用 cargo install codex-cli 来安装。虽然官方仓库里有 codex-cli 这个 crate,但它是一个已归档的旧项目,与当前主流的 codex CLI 不兼容。 cargo install 会拉取一个无法识别 agents.md 格式的二进制文件,导致你后续所有配置都白费。热词里“codex cli安装”搜索量很高,但大部分教程没讲清这个历史包袱,这是新手掉进的第一个深坑。

3. 核心配置文件解析:agents.md 与 skill.md 的本质区别与协作机制

Codex 的灵魂不在代码里,而在两个 Markdown 文件中: agents.md skill.md 。很多初学者被热词“agents.md和skill.md的区别”困扰,以为它们是同类事物的不同命名。其实,它们是同一套工作流中的“指挥官”与“特种兵”,角色截然不同,协作却密不可分。

agents.md 是你的 作战总纲 。它定义了一个 Agent(智能代理)的全局行为:它能做什么、在什么条件下做、以及如何与用户交互。一个典型的 agents.md 文件长这样:

---
name: "git-helper"
description: "A skill for common git operations and explanations"
model: "claude-3-haiku-20240307"
temperature: 0.3
max_tokens: 1024
---

## Command: `git status` explanation

When the user runs `git status`, explain what each section means in plain English.

## Command: `git add <file>` safety check

Before adding a file, check if it contains sensitive patterns (e.g., 'API_KEY', 'password') and warn the user.

注意 YAML Front Matter 中的 model 字段。它指明了这个 Agent 将调用哪个 LLM 服务。这里填的不是模型 ID,而是你在 ~/.codex/config.toml 中为该模型定义的 Provider 别名 。例如,你的 config.toml 可能有:

[providers.claude]
type = "anthropic"
api_key = "${ANTHROPIC_API_KEY}"
base_url = "https://api.anthropic.com/v1"

那么 agents.md 里的 model: "claude" 才能正确路由。如果填成 "claude-3-haiku-20240307" ,Codex 会报错找不到 Provider,因为 claude-3-haiku-20240307 是模型 ID,不是 Provider 名。

skill.md 则是 单兵作战手册 。它不关心模型、温度、Token 限制这些全局参数,只专注于一个具体任务的输入、处理逻辑和输出格式。一个 git-status-explainer.skill.md 文件可能如下:

---
name: "git-status-explainer"
description: "Explains git status output"
input: "The raw output of `git status --porcelain=v1`"
output: "A clear, concise explanation in markdown"
---

You are an expert git instructor. The user has provided the raw output of `git status --porcelain=v1`. Explain what each line means, focusing on the staging area (index) vs. the working directory. Use bullet points and avoid jargon.

关键区别在于: agents.md 是声明式的(Declarative),它描述“我要达成什么目标”; skill.md 是指令式的(Imperative),它规定“具体怎么做”。一个 agents.md 可以引用多个 skill.md ,通过 ## Command: 标题下的内容来触发。Codex 的运行时会先解析 agents.md ,提取出所有 ## Command: 区块,然后为每个区块匹配一个最合适的 skill.md (通常按文件名模糊匹配,如 Command: git status 会优先匹配 git-status.skill.md )。如果找不到,它会回退到通用的 default.skill.md

这种分离设计带来了巨大的灵活性。你可以为同一个 git-helper Agent,编写 git-commit-linter.skill.md (检查提交信息是否符合 Conventional Commits)、 git-diff-analyzer.skill.md (分析 diff 的影响范围),而无需修改 agents.md 的主体结构。这正是热词“codex agents.md怎么写减少token消耗?”背后的需求——通过将通用指令(如“用中文回答”)下沉到 skill.md output 字段中,而不是在每个 ## Command: 下重复书写,就能显著压缩每次请求发送给模型的 Prompt 长度。

提示: agents.md 中的 temperature 参数,其作用域仅限于该文件内定义的所有 ## Command: 。如果你在 skill.md 里也写了 temperature: 0.1 ,它会被忽略。这是 Codex 的明确设计,目的是让 Agent 的“性格”(创造性高低)由指挥官统一设定,而特种兵只负责精准执行。

4. Skill 实战:从零编写一个“日志错误分析器”并接入 DeepSeek

理论讲完,现在动手做一个真正有用的 Skill。我们来实现一个 log-error-analyzer ,它的目标是:当你把一段应用日志(尤其是包含堆栈跟踪的错误日志)粘贴给 Codex,它能立刻告诉你错误类型、可能原因、以及三步修复建议。这个需求在运维和开发调试中极其高频,而市面上的通用 Chat 工具往往需要你反复提示、调整上下文,效率低下。

4.1 创建 Skill 目录与骨架

首先,创建 Skill 的标准目录结构。Codex 要求所有 Skill 必须放在 ~/.codex/skills/ 下的子目录中,且每个子目录必须包含一个 skill.md 文件。我们执行:

mkdir -p ~/.codex/skills/log-error-analyzer
cd ~/.codex/skills/log-error-analyzer
touch skill.md

4.2 编写 skill.md:聚焦输入、输出与约束

skill.md 的内容不是自由发挥的作文,而是一份精密的“人机契约”。我们必须严格定义输入格式、期望输出、以及最重要的——模型的思考边界。以下是经过多次迭代后稳定可用的版本:

---
name: "log-error-analyzer"
description: "Analyzes application error logs and provides actionable fix steps"
input: "Raw text of an application log, containing at least one stack trace or error message"
output: "A markdown-formatted response with exactly three sections: 1. Error Classification, 2. Root Cause Analysis, 3. Step-by-Step Fix. No introduction or conclusion sentences."
---

You are a senior SRE with 10 years of experience debugging production systems. Your task is to analyze the provided log snippet and produce a precise, actionable diagnosis.

**Rules:**
- If the log does not contain a recognizable stack trace (e.g., lines starting with 'at ', 'Caused by:', 'Traceback (most recent call last):'), respond with: 'ERROR: No stack trace detected. Please provide a log with a full error traceback.'
- Classify the error into ONE of these categories: 'Network Timeout', 'Database Connection Failure', 'Null Pointer Exception', 'Memory Leak', 'Configuration Mismatch', 'External Service Unavailable'.
- For Root Cause Analysis, cite EXACTLY ONE line from the log that is the most critical evidence. Do not invent facts.
- For Step-by-Step Fix, provide THREE concrete, sequential commands or code changes. Each step must be executable and self-contained. Do not use vague terms like 'check configuration'.

**Output Format:**
### 1. Error Classification
[Your single-category classification]

### 2. Root Cause Analysis
Evidence line: `[Exact line from log]`
Explanation: `[One sentence, max 20 words]`

### 3. Step-by-Step Fix
1. `[First concrete action]`
2. `[Second concrete action]`
3. `[Third concrete action]`

这个 skill.md 的精妙之处在于它的“强约束”。 input 字段明确了数据源(原始日志文本), output 字段强制了结构(三个标题、无废话),而 Rules 部分则是模型的“紧箍咒”。特别是“cite EXACTLY ONE line”和“Do not invent facts”这两条,直接对抗了 LLM 的幻觉倾向。我实测过,没有这些约束时,模型会自信地编造出根本不存在的日志行作为“证据”,导致整个分析失去可信度。

4.3 创建对应的 agents.md:绑定模型与触发条件

接下来,我们需要一个 agents.md 来“雇佣”这个 Skill。在项目根目录(比如你的 ~/my-project/ )下创建 agents.md

---
name: "dev-sre-assistant"
description: "An agent for developer and SRE daily tasks"
model: "deepseek"
temperature: 0.1
max_tokens: 2048
---

## Command: `analyze-log`

Analyze the provided application log for errors and suggest fixes. Paste the full log output here.

注意 model: "deepseek" 。这意味着你需要在 ~/.codex/config.toml 中预先配置好 DeepSeek 的 Provider。假设你使用的是 DeepSeek-Coder-V2 的 API(通过 OpenRouter 或自建服务),配置如下:

[providers.deepseek]
type = "openrouter"
api_key = "${OPENROUTER_API_KEY}"
model = "deepseek/deepseek-coder-v2-07b-base"
base_url = "https://openrouter.ai/api/v1"

4.4 测试与验证:一次真实的错误日志分析

现在,让我们用一段真实的 Spring Boot 错误日志来测试。保存以下内容到 sample-error.log

2024-05-20 14:22:33.123 ERROR [main] o.s.b.d.LoggingFailureAnalysisReporter : 
***************************
APPLICATION FAILED TO START
***************************
Description:
Failed to configure a DataSource: 'url' attribute is not specified and no embedded datasource could be configured.

Action:
Consider the following:
    If you want an embedded database, please put a supported one on the classpath.
    If you have database settings to be loaded from a particular profile you may need to activate it (the profiles 'dev' are currently active).

执行分析命令:

codex analyze-log < sample-error.log

预期输出(经 Codex v0.8.3 + DeepSeek-Coder-V2 实测):

### 1. Error Classification
Configuration Mismatch

### 2. Root Cause Analysis
Evidence line: Failed to configure a DataSource: 'url' attribute is not specified and no embedded datasource could be configured.
Explanation: The application is missing the required database connection URL.

### 3. Step-by-Step Fix
1. Open `src/main/resources/application.yml` and add the line `spring.datasource.url: jdbc:h2:mem:testdb`.
2. Add the H2 database dependency to your `pom.xml`: `<dependency><groupId>com.h2database</groupId><artifactId>h2</artifactId></dependency>`.
3. Run `mvn clean compile` to verify the dependencies are resolved.

这个结果干净、准确、可执行。它没有泛泛而谈“检查配置”,而是给出了具体的文件路径、YAML 行、Maven 依赖坐标和命令。这就是一个合格 Skill 的价值:将模糊的“帮我看看”转化为确定的“第一步做什么”。

提示:在热词列表里,“codex接入deepseek”和“claude code cli deepseek”并存,说明用户有混合使用多模型的需求。Codex 完全支持这一点。你只需在 ~/.codex/config.toml 中定义多个 Provider( deepseek , claude , qwen ),然后在不同的 agents.md 文件中指定 model: "deepseek" model: "claude" 即可。一个项目可以同时拥有 dev-sre-assistant (用 DeepSeek 分析日志)和 code-reviewer (用 Claude 做 PR 评论),互不干扰。

5. 常见问题排查:为什么 codex skill list 显示为空?为什么中文设置不生效?

即便你严格按照前面的步骤操作,实战中仍会遇到几个高频“静默失败”问题。它们不会抛出明显的错误,但会让你觉得 Codex “不工作”,从而放弃。我把这些问题的完整排查链路拆解出来,每一步都有依据和解决方案。

5.1 问题: codex skill list 命令返回空列表,或只显示 default

现象 :你确认 ~/.codex/skills/log-error-analyzer/skill.md 文件存在且内容无误,但执行 codex skill list 却看不到 log-error-analyzer

排查链路

  1. 检查目录权限 :Codex CLI 以当前用户身份运行,它需要有读取 ~/.codex/skills/ 及其所有子目录的权限。执行 ls -ld ~/.codex/skills/ ~/.codex/skills/log-error-analyzer/ 。如果输出中权限位是 drwx------ ,说明只有所有者可读,这是正常的。但如果看到 drwxr-x--- 且组名不是你的主组,或者权限是 drwx------ 但文件所有者不是你(比如是 root ),就会失败。解决方案: chmod 700 ~/.codex/skills/ ~/.codex/skills/log-error-analyzer/ && chown -R $USER:$USER ~/.codex/skills/
  2. 检查文件名与扩展名 :Codex 只识别 .skill.md 结尾的文件。如果你不小心创建了 skill.md.txt Skill.md (大小写敏感),它会被忽略。执行 find ~/.codex/skills/ -name "*.skill.md" 确认文件真实存在。
  3. 检查 YAML Front Matter 的完整性 skill.md 的开头 --- 必须是文件的第一行,且必须有结束的 --- 。如果中间有空格、Tab 或 Unicode BOM 字符,Rust 的 serde_yaml 解析器会静默失败,跳过整个文件。用 head -n 5 ~/.codex/skills/log-error-analyzer/skill.md 查看前五行,确保是干净的 ---\nname: ...\n...\n---
  4. 检查 Codex 的技能缓存 :Codex 会缓存已加载的 Skill 列表。如果之前加载失败过,缓存可能损坏。删除缓存文件: rm ~/.codex/cache/skills.json ,然后重试。

5.2 问题: codex --help codex analyze-log 输出是英文, config.toml 里设置了 language = "zh-CN" 却不生效

现象 :你在 ~/.codex/config.toml 中添加了 language = "zh-CN" ,但所有 CLI 的帮助信息、错误提示、甚至 Skill 的输出都是英文。

根因分析 :这是一个广泛存在的误解。Codex CLI 本身(即 codex 二进制) 不提供 UI 层面的国际化 language 字段在官方文档中从未被提及,它是一个被废弃的、未实现的配置项。所有你看到的“中文设置”相关热词,都源于早期某个 fork 分支的实验性 PR,该 PR 从未合并进主干。因此, config.toml 中的 language 设置是无效的。

真正的解决方案 :中文支持必须在 skill.md output 字段中显式声明。回到我们之前的 log-error-analyzer.skill.md ,将 output 字段改为:

output: "A markdown-formatted response in Chinese (Simplified) with exactly three sections: 1. 错误分类, 2. 根本原因分析, 3. 分步修复。No introduction or conclusion sentences."

同时,在 Rules 部分的所有指令,也必须用中文书写。这才是唯一可靠的方式。因为模型的输出语言,完全由你发送给它的 Prompt 决定,而不是由 CLI 的某个配置开关决定。这符合“Prompt Engineering”的基本原理:你告诉模型“用中文回答”,它才会用中文回答。

5.3 问题: codex analyze-log 执行后卡住,CPU 占用 100%,数分钟后才超时

现象 :命令长时间无响应, htop 显示 codex 进程 CPU 占用极高。

根因与解决 :这几乎 100% 是 agents.md 中的 max_tokens 设置过低,导致模型在生成过程中反复尝试、回溯、重试,陷入一种“生成-拒绝-重试”的死循环。例如,如果你设了 max_tokens = 128 ,但你的 skill.md 要求输出三个带编号的步骤,每个步骤平均 30 字,光是输出就需要至少 150 tokens。模型发现无法在限额内完成,就会不断压缩、删减、改写,最终耗尽重试次数。解决方案是: max_tokens 设置为预期输出长度的 2-3 倍 。对于我们的日志分析器, max_tokens = 512 是一个安全的起点。你可以在 agents.md 的 YAML Front Matter 中直接修改,无需重启 CLI。

注意:热词“rust unsafe”在此处有实际关联。Codex 的 CLI 在处理超长 Token 限制时,会使用 unsafe 块直接操作 tokio::sync::mpsc 通道的缓冲区,以避免在高并发场景下因频繁的 Arc 引用计数而引发性能抖动。这不是一个需要你干预的点,但了解它能让你明白,为什么 Codex 在处理这类边界情况时,选择了 Rust 的 unsafe 而非更“安全”的纯 safe Rust 方案——性能是本地 CLI 的第一生命线。

6. 进阶技巧与个人经验:如何让 Codex 成为你键盘上的“第六感”

经过前面的安装、配置、实战和排错,你已经掌握了 Codex 的核心脉络。但要让它真正融入你的工作流,成为像 grep vim 一样顺手的工具,还需要一些“肌肉记忆”级别的技巧。这些不是文档里写的,而是我在过去 8 个月、超过 2000 次日常使用中沉淀下来的个人心得。

6.1 技巧一:用 --dry-run 模式预览 Prompt,告别“黑盒”调试

当你写好一个 skill.md ,却不确定模型会收到什么样的最终 Prompt 时, --dry-run 是你的救命稻草。它会跳过模型调用,只做一件事:将 agents.md ## Command: 内容、 skill.md 的全部内容、以及所有变量(如当前路径、Git 分支名)拼接起来,然后原样打印到终端。执行:

codex analyze-log --dry-run < sample-error.log

你会看到一段长长的、格式化的 Markdown 文本,这就是 Codex 即将发送给 DeepSeek 的完整 Prompt。你可以逐行检查:

  • 是否包含了你不想要的上下文(比如多余的 Git 信息)?
  • input 字段是否被正确注入?
  • Rules 部分的约束是否清晰无歧义?
  • 中文指令是否完整,有没有被意外截断?

这个模式让我在编写 git-commit-linter.skill.md 时,发现了 input 字段被错误地写成了 {{commit_message}} ,而实际可用的变量是 {{git_commit_message}} --dry-run 一秒就暴露了问题,省去了等待模型 API 响应、再分析错误输出的漫长过程。

6.2 技巧二:为 Skill 添加“环境感知”,让它知道你是谁、在哪

一个强大的 Skill 不应该是一个孤立的函数,而应该是一个有上下文的协作者。Codex 支持在 skill.md input 字段中,使用双花括号语法注入环境变量和系统信息。例如,在 log-error-analyzer.skill.md input 字段,我们可以这样写:

input: "Raw text of an application log, containing at least one stack trace or error message. Current working directory: {{pwd}}, Git branch: {{git_branch}}, User: {{user}}"

然后,在 Rules 部分,就可以加入针对性的指令:

- If the current Git branch is 'main' or 'master', prioritize checking for production-grade fixes.
- If the user is 'jenkins' or 'ci', omit any suggestions that require interactive input.

这使得同一个 Skill,在 CI 服务器上运行时,会自动禁用需要人工确认的步骤;在你的本地开发机上,则会给出更详细的、带路径的调试建议。这种“环境感知”能力,是让 Codex 从玩具变成生产力工具的关键跃迁。

6.3 技巧三:用 codex run 直接执行 Skill,绕过 agents.md 的抽象层

有时候,你只想快速测试一个 Skill,不想为了它专门写一个 agents.md codex run 命令就是为此而生。它允许你直接指定 Skill 的路径和输入:

codex run ~/.codex/skills/log-error-analyzer/skill.md < sample-error.log

这个命令会跳过 agents.md 的解析,直接加载指定的 skill.md ,并用标准输入作为 input 。它非常适合 Skill 的单元测试和快速原型验证。我习惯在编写一个新的 skill.md 后,先用 codex run 测试 3-5 次,确保逻辑正确,再把它集成进正式的 agents.md 流程中。这大大缩短了反馈循环。

最后分享一个小技巧:我所有的 agents.md skill.md 文件,都用 VS Code 的 prettier 插件进行格式化,并启用了 markdownlint 规则。因为 Codex 的解析器对 Markdown 的语法非常敏感,一个多余的空行、一个未闭合的代码块,都可能导致解析失败。把格式检查变成编辑器的自动行为,比事后调试要高效得多。

Codex 的魅力,不在于它有多“智能”,而在于它把 AI 的能力,降维到了一个开发者最熟悉的领域:文本、命令行、配置文件。它不试图取代你,而是把你多年积累的领域知识(Git 流程、日志格式、部署规范),用一种新的方式固化下来,变成可分享、可复用、可版本控制的数字资产。当你第一次看到 codex analyze-log 在 2 秒内给出精准的修复步骤时,那种“我的经验被编码了”的感觉,是任何云端 Chat 工具都无法给予的踏实感。

Logo

Agent 垂直技术社区,欢迎活跃、内容共建。

更多推荐