摘要

本文面向使用 AI 辅助日常开发工作的程序员与研发团队,系统梳理 ChatGPT Plus、ChatGPT Pro 与 Codex 在软件开发流程中的定位与分工。文章围绕一个真实案例——为任务管理 API 增加优先级字段并补充测试与持续集成——完整演示从需求分析、代码生成、测试验证到人工审查的可控工作流。读者将获得可直接复用的 Codex 提示词模板、Git 审查清单以及安全使用 AI 编程工具的基本原则。本文重点讨论技术工作流,不对动态额度或套餐权益作固定承诺,具体可用功能以当前官方页面为准。

目录

一、为什么开发者需要区分 ChatGPT 与 Codex

在日常开发中,很多开发者习惯把"AI 编程"简单理解为在对话框里输入一句"帮我写代码"。但实际工程场景远比这复杂:需求可能含糊不清,代码仓库可能包含几十个文件,测试环境可能与本地不一致,而一次错误的自动修改可能破坏已有功能。因此,理解 ChatGPT 与 Codex 的差异,是建立可控 AI 编程流程的第一步。

ChatGPT 的核心价值在于对话式推理。它适合需求梳理、方案讨论、代码解释、报错分析等需要上下文来回交互的任务。开发者可以把一段报错信息、一份接口文档或一段业务描述粘贴进去,通过多轮对话逐步澄清问题。ChatGPT 不直接操作本地文件系统,也不读取你的 Git 仓库,它的工作边界是"对话窗口内的信息"。

Codex 则面向仓库级任务。它能够读取项目目录结构、定位相关文件、在受限范围内修改代码,并可以执行测试命令来验证修改结果。Codex 的价值不在于"写一段代码",而在于"在一个真实项目中完成一项有边界的工程任务"。它需要明确的任务说明、允许修改的路径范围、以及可验证的完成标准。

因此,不能只靠一句"帮我写代码"来完成工程任务。仓库上下文决定了 AI 能否找到正确的文件,测试要求决定了修改是否可验证,任务边界决定了 AI 不会越界改动无关代码。理解这些区别,是后续所有工作流设计的基础。

二、ChatGPT Plus、ChatGPT Pro 与 Codex 的技术定位

下表从开发场景角度对比 ChatGPT Plus、ChatGPT Pro 与 Codex 的定位。需要说明的是,不同账号、地区或版本可能存在差异,具体可用功能以当前官方页面为准。本文重点讨论技术工作流,不对动态额度作固定承诺。

工具或方案 主要定位 适合任务 输入信息 输出结果 使用风险
ChatGPT Plus 通用对话助手 需求梳理、方案讨论、代码解释、文档撰写 对话文本、粘贴的代码片段、文档 文本回复、代码片段、解释说明 不读取本地仓库,可能基于过时上下文
ChatGPT Pro 高强度对话与推理 复杂架构讨论、长文档分析、多轮深度推理 对话文本、长文档、多文件代码片段 深度分析、方案对比、详细解释 上下文窗口有限,不直接操作代码仓库
Codex 仓库级编码代理 阅读项目、定位文件、实现功能、运行测试、生成 diff 项目仓库、任务说明、允许修改的路径范围 代码修改、测试结果、文件变更汇总 可能修改无关文件、破坏原有逻辑,需人工审查

从表中可以看出,ChatGPT 系列更适合"思考与讨论",Codex 更适合"执行与修改"。两者不是替代关系,而是互补关系。开发者应该根据任务类型选择合适的工具,而不是把所有工作都交给同一个对话框。

三、一套可控的 AI 编程工作流

要让 AI 安全地参与代码修改,必须建立一套可验证、可回退的工作流。下面是一个经过实践检验的十步流程,适用于个人开发者和小型团队。

明确需求

阅读项目

制定修改计划

创建Git分支

修改代码

运行测试

测试是否通过

人工代码审查

合并代码

第一步是明确需求。开发者需要把模糊的想法转化为可执行的任务描述,包括功能目标、输入输出、边界条件和验收标准。第二步是阅读项目,让 Codex 先理解仓库结构、关键文件和现有约定,而不是直接动手改代码。第三步是制定修改计划,明确要改哪些文件、新增哪些逻辑、影响哪些现有功能。

第四步是创建独立 Git 分支,这是最重要的安全边界之一。分支确保所有 AI 修改都可以被整体回退,不会污染主分支。第五步是修改代码,此时才允许 Codex 在限定范围内写入文件。第六步是编写并运行测试,用自动化测试验证修改是否符合预期。第七步检查测试结果,如果失败则回到修改环节继续迭代。

第八步是查看代码差异,开发者需要逐行检查 git diff,确认没有无关改动。第九步是人工审查,重点检查逻辑正确性、安全风险和边界条件。第十步是合并代码,在测试通过且审查无异议后合入主分支。这套流程的核心思想是:AI 负责执行,人类负责定义边界和最终把关。

四、实战项目:使用 Codex 辅助维护一个 Python API 项目

下面通过一个完整案例演示上述工作流。项目是一个简单的任务管理 API,需求是:为现有任务管理 API 增加任务优先级字段,并支持按照优先级筛选,同时补充单元测试和持续集成检查。

4.1 项目目录

task-api/
├── app/
│   ├── __init__.py
│   ├── main.py
│   ├── models.py
│   └── service.py
├── tests/
│   └── test_tasks.py
├── pyproject.toml
└── .github/
    └── workflows/
        └── test.yml

4.2 环境准备

以下命令在项目根目录执行。首先创建虚拟环境并激活:

python3.11 -m venv .venv
source .venv/bin/activate

然后安装依赖。项目使用 FastAPI、Pydantic 和 pytest,依赖声明在 pyproject.toml 中:

pip install --upgrade pip
pip install -e ".[dev]"

启动项目:

uvicorn app.main:app --reload

运行测试:

pytest -q

4.3 核心业务代码

首先是数据模型文件 app/models.py,定义任务数据结构和优先级枚举:

from enum import Enum
from pydantic import BaseModel, Field, field_validator


class Priority(str, Enum):
    low = "low"
    medium = "medium"
    high = "high"


class Task(BaseModel):
    id: int
    title: str = Field(..., min_length=1, max_length=200)
    priority: Priority = Priority.medium


class TaskCreate(BaseModel):
    title: str = Field(..., min_length=1, max_length=200)
    priority: Priority = Priority.medium

    @field_validator("title")
    @classmethod
    def title_not_blank(cls, v: str) -> str:
        if not v.strip():
            raise ValueError("title must not be blank")
        return v.strip()

接下来是业务逻辑文件 app/service.py,负责任务的存储与筛选:

from typing import Optional

from app.models import Priority, Task, TaskCreate


class TaskService:
    def __init__(self) -> None:
        self._tasks: dict[int, Task] = {}
        self._next_id = 1

    def create_task(self, payload: TaskCreate) -> Task:
        task = Task(id=self._next_id, title=payload.title, priority=payload.priority)
        self._tasks[task.id] = task
        self._next_id += 1
        return task

    def list_tasks(self, priority: Optional[Priority] = None) -> list[Task]:
        tasks = list(self._tasks.values())
        if priority is not None:
            tasks = [t for t in tasks if t.priority == priority]
        return tasks

    def get_task(self, task_id: int) -> Optional[Task]:
        return self._tasks.get(task_id)

最后是 API 入口文件 app/main.py,定义路由和参数校验:

from typing import Optional

from fastapi import FastAPI, HTTPException, Query

from app.models import Priority, Task, TaskCreate
from app.service import TaskService

app = FastAPI(title="Task API")
service = TaskService()


@app.post("/tasks", response_model=Task, status_code=201)
def create_task(payload: TaskCreate) -> Task:
    return service.create_task(payload)


@app.get("/tasks", response_model=list[Task])
def list_tasks(
    priority: Optional[Priority] = Query(default=None, description="Filter by priority"),
) -> list[Task]:
    return service.list_tasks(priority)


@app.get("/tasks/{task_id}", response_model=Task)
def get_task(task_id: int) -> Task:
    task = service.get_task(task_id)
    if task is None:
        raise HTTPException(status_code=404, detail="task not found")
    return task

4.4 自动化测试

测试文件 tests/test_tasks.py 覆盖正常创建、默认优先级、非法优先级、按优先级筛选、空结果和原有功能六个场景:

import pytest
from fastapi.testclient import TestClient

from app.main import app

client = TestClient(app)


def setup_function() -> None:
    # 每个测试前重置服务状态
    from app.main import service
    service._tasks.clear()
    service._next_id = 1


def test_create_task() -> None:
    resp = client.post("/tasks", json={"title": "write report"})
    assert resp.status_code == 201
    data = resp.json()
    assert data["title"] == "write report"
    assert data["priority"] == "medium"


def test_default_priority_is_medium() -> None:
    resp = client.post("/tasks", json={"title": "default priority"})
    assert resp.status_code == 201
    assert resp.json()["priority"] == "medium"


def test_invalid_priority_rejected() -> None:
    resp = client.post("/tasks", json={"title": "bad", "priority": "urgent"})
    assert resp.status_code == 422


def test_filter_by_priority() -> None:
    client.post("/tasks", json={"title": "low task", "priority": "low"})
    client.post("/tasks", json={"title": "high task", "priority": "high"})
    resp = client.get("/tasks", params={"priority": "high"})
    assert resp.status_code == 200
    data = resp.json()
    assert len(data) == 1
    assert data[0]["title"] == "high task"


def test_filter_empty_result() -> None:
    resp = client.get("/tasks", params={"priority": "high"})
    assert resp.status_code == 200
    assert resp.json() == []


def test_get_task_not_found() -> None:
    resp = client.get("/tasks/999")
    assert resp.status_code == 404

测试是使用 Codex 修改代码时最重要的安全边界。原因在于:测试把"需求"转化为"可执行的断言",AI 的修改是否满足要求不再依赖主观判断,而是由测试结果客观决定。没有测试的 AI 修改,本质上无法验证正确性。

4.5 持续集成配置

GitHub Actions 配置文件 .github/workflows/test.yml 与前面的项目保持一致:

name: test

on:
  push:
    branches: [main]
  pull_request:

jobs:
  test:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-python@v5
        with:
          python-version: "3.11"
      - name: Install dependencies
        run: |
          pip install --upgrade pip
          pip install -e ".[dev]"
      - name: Run tests
        run: pytest -q

4.6 查看并审查修改

Codex 完成修改后,开发者应使用以下命令检查变更:

git status
git diff
git diff --stat
git log --oneline -5
pytest -q

审查时应重点检查以下内容:

  • 是否修改了无关文件,例如配置文件、锁文件或文档被意外改动
  • 是否删除了原有逻辑,例如某个分支处理或异常捕获被移除
  • 是否引入了新的依赖,以及这些依赖是否必要
  • 是否存在硬编码,例如密钥、路径或环境相关的值被写死在代码里
  • 是否遗漏异常处理,例如网络请求、文件读写或外部服务调用没有容错
  • 是否存在安全风险,例如用户输入未校验、SQL 拼接或命令注入
  • 测试是否真正覆盖需求,而不是只覆盖了"快乐路径"

五、给 Codex 的高质量任务提示词

下面提供三个可直接复用的提示词模板。使用时根据项目情况替换方括号中的内容。

模板一:分析项目,不修改代码

请阅读当前仓库的项目结构,重点关注 [app/ 目录下的业务逻辑文件]。
找出与 [任务优先级筛选] 相关的所有文件,说明它们之间的调用关系。
基于现有代码风格,给出实现 [优先级字段] 的修改计划,列出需要新增或修改的文件。
暂时不要修改任何代码,只输出分析结果和计划。

这个模板的关键在于"暂时不要修改任何代码"。它强制 Codex 先理解项目再动手,避免在信息不足时盲目修改。开发者可以根据项目情况替换目录路径、功能名称和期望的分析深度。

模板二:实现功能并补充测试

功能目标:为任务管理 API 增加优先级字段,支持按优先级筛选。
允许修改的目录:app/ 和 tests/。
要求:
1. 保持现有 API 的向后兼容性,已有字段和路由不能破坏。
2. 在 tests/test_tasks.py 中补充测试,覆盖正常创建、默认值、非法值、筛选和空结果。
3. 运行 pytest -q,确保所有测试通过。
4. 完成后汇总修改的文件列表和测试结果。

这个模板明确了功能目标、修改边界和验证标准。其中"允许修改的目录"是最重要的安全约束,它防止 Codex 改动依赖文件、CI 配置或其他无关内容。"保持向后兼容"则提醒 AI 不要破坏已有接口。

模板三:代码审查

请审查 [app/service.py] 和 [app/main.py] 的代码,重点检查:
1. 逻辑错误,例如边界条件处理不当、状态更新遗漏。
2. 安全问题,例如用户输入未校验、敏感信息泄露。
3. 边界条件,例如空列表、重复数据、超大输入。
4. 测试覆盖,指出哪些分支没有被测试到。
5. 按严重程度分类输出:严重、一般、建议。
不要直接修改代码,只输出审查报告。

这个模板把审查任务限定为"只读",避免 AI 在审查过程中顺手改代码。按严重程度分类输出,便于开发者优先处理高风险问题。

六、ChatGPT Plus / Pro + Codex 的协同方式

在实际开发中,ChatGPT 与 Codex 可以形成明确的分工。下面以一个功能迭代为例说明协同方式。

第一步,使用 ChatGPT 梳理需求和业务规则。开发者可以把产品需求文档或口头描述粘贴给 ChatGPT,通过多轮对话澄清优先级字段的取值范围、默认值、筛选逻辑等细节。第二步,使用 ChatGPT 讨论架构和技术选型,例如优先级字段应该用枚举还是字符串、筛选应该放在服务层还是数据库层。

第三步,使用 Codex 阅读仓库并定位文件。Codex 可以快速扫描项目结构,找出与任务相关的模型、路由和测试文件。第四步,使用 Codex 执行受限范围内的修改,按照模板二的要求实现功能并补充测试。第五步,运行测试验证修改,Codex 会执行 pytest 并报告结果。

第六步,使用 ChatGPT 对代码差异进行第二次解释。开发者可以把 git diff 的输出粘贴给 ChatGPT,让它从第三方视角检查逻辑漏洞或遗漏场景。第七步,最终由开发者完成人工审查和合并。整个流程中,AI 承担的是"分析、执行、解释"的角色,而决策权和最终责任始终在开发者手中。

七、常见错误与解决方法

以下是使用 AI 编程工具时最常见的十种错误及对应的改进方法。

错误一:提示词只有一句话。 例如"帮我加个优先级字段"。改进方法:提供功能目标、输入输出、边界条件和验收标准,参考模板二的结构。

错误二:没有限制修改范围。 AI 可能改动依赖文件、CI 配置或无关模块。改进方法:在提示词中明确"允许修改的目录",并在审查时用 git diff --stat 核对。

错误三:没有先让 Codex 阅读项目。 直接要求修改代码,AI 可能基于猜测工作。改进方法:先使用模板一让 Codex 输出项目分析和修改计划,确认后再执行。

错误四:没有创建独立分支。 AI 的修改直接落在主分支上,出错后难以回退。改进方法:任何 AI 修改前先 git checkout -b feature/xxx

错误五:没有要求补充测试。 修改是否正确的判断完全依赖人工。改进方法:在提示词中明确要求补充测试并运行 pytest

错误六:不检查 Git diff。 直接信任 AI 的修改结果。改进方法:逐行审查 git diff,重点检查无关文件、硬编码和异常处理。

错误七:一次提交过多需求。 多个功能混在一次修改中,出错后难以定位。改进方法:每次只让 AI 完成一个边界清晰的任务,一个分支对应一个需求。

错误八:把密钥写入代码。 API Key、数据库密码等敏感信息被硬编码。改进方法:使用环境变量或密钥管理服务,并在审查时搜索密钥模式。

错误九:直接修改生产环境。 AI 的修改未经测试直接部署。改进方法:所有修改先在本地和 CI 环境验证,通过后再走发布流程。

错误十:完全相信 AI 的解释。 AI 可能自信地给出错误结论。改进方法:把 AI 的解释当作参考,关键逻辑必须由开发者验证,必要时用测试或调试器确认。

八、安全与隐私

使用 AI 编程工具时,安全与隐私必须放在首位。以下是必须遵守的基本原则。

第一,API Key 和访问令牌不能直接写入代码。应使用环境变量或专门的密钥管理服务。第二,不向模型提交生产环境密码、数据库凭据或客户敏感数据。第三,检查日志中的敏感信息,确保 AI 生成的代码不会把密钥或用户数据打印到日志中。第四,限制工具权限,Codex 只应被授予完成任务所需的最小权限。

第五,使用最小权限原则。AI 工具不应拥有删除生产数据、修改权限配置或访问未授权系统的能力。第六,对外部依赖进行审查。AI 可能建议引入新的第三方库,开发者需要确认这些库的来源、许可证和安全性。第七,AI 生成的代码仍需进行安全测试,包括输入校验、注入防护和权限检查。

以下是一个安全使用环境变量的示例:

import os

api_key = os.environ.get("TASK_API_KEY")
if api_key is None:
    raise RuntimeError("TASK_API_KEY is not set")

这段代码从环境变量读取密钥,而不是硬编码在源码中。开发者应确保 .env 文件被加入 .gitignore,避免密钥被提交到仓库。

九、总结

本文围绕 ChatGPT Plus、ChatGPT Pro 与 Codex 在软件开发中的定位与协同方式,给出了一套完整的可控工作流。核心结论是:ChatGPT 适合需求分析、方案讨论和代码解释,Codex 适合仓库级代码修改与测试验证,而开发者始终是最终决策者。通过明确需求、限定修改范围、补充测试、审查 diff 和建立 CI 检查,AI 可以成为可靠的开发助手,而不是不可控的风险源。具体可用功能以当前官方页面为准,不同账号、地区或版本可能存在差异,本文重点讨论技术工作流,不对动态额度作固定承诺。

Logo

AtomGit AI 社区提供模型库、数据集、Agent、Token等资源

更多推荐