如果把 ChatGPT 理解成聊天工具,把 Codex 理解成代码生成工具,其实都太表层了。
从更底层的工程角度看,它们更像是 AI Agent 系统中的两个不同阶段:
- ChatGPT 更像自然语言层的语义解释器;
- Codex 更像代码与工程动作层的执行生成器;
- AI Agent 则像一个运行时系统,负责把人的意图转化为可执行任务链。
这就引出一个更有意思的类比:
AI Agent 很像一种新的编译器。
传统编译器做的是:
text
Source Code
↓
Lexer
↓
Parser
↓
AST
↓
IR
↓
Optimization
↓
Machine Code
而 AI Agent 做的是:
text
Human Intent
↓
Intent Parsing
↓
Context Building
↓
Task IR
↓
Planning
↓
Tool Execution
↓
Verification
↓
System Change
也就是说,传统编译器把代码编译成机器指令。
而 AI Agent 把人的自然语言意图编译成任务执行链。
这才是 ChatGPT 和 Codex 真正值得讨论的地方。
它们并不是简单提高内容生成效率或编码效率,而是在改变软件系统接受任务、理解任务、执行任务的方式。
一、自然语言正在成为新的输入语言
过去,软件系统的输入是结构化的。
接口参数是结构化的。
配置文件是结构化的。
数据库查询是结构化的。
编程语言是结构化的。
比如一个函数调用:
python
def create_order(user_id: int, items: list, coupon_id: str | None):
pass
它要求调用者明确提供参数。
但人类真实表达不是这样的。
用户更可能说:
text
帮我把订单模块优化一下,最近筛选和导出经常出问题。
这句话非常模糊。
它没有明确函数名。
没有明确参数。
没有明确文件路径。
没有明确 bug 类型。
没有明确验收标准。
传统程序无法直接处理这种输入。
但 ChatGPT 可以先把它解析成相对结构化的任务表示:
json
{
"domain": "order_module",
"task_type": "optimization_or_debugging",
"mentioned_features": ["filter", "export"],
"known_problem": "frequent issues",
"missing_information": [
"具体错误日志",
"复现步骤",
"相关代码位置",
"期望行为",
"当前行为"
],
"next_action": "request_context_or_inspect_code"
}
这一步本质上就是:
text
Natural Language → Structured Intent
从编译器角度看,这相当于词法分析和语法分析。
只不过输入不是代码,而是自然语言。
二、ChatGPT 像 Parser,Codex 像 Code Generator
在传统编译器里,不同阶段负责不同事情。
Parser 负责理解源码结构。
Optimizer 负责优化中间表示。
Code Generator 负责生成目标平台代码。
如果套到 AI Agent 里,可以这样理解:
text
ChatGPT:
Natural Language Parser
Intent Analyzer
Context Organizer
Codex:
Code Context Analyzer
Patch Generator
Test Runner Assistant
Engineering Action Planner
ChatGPT 更偏语义层。
它擅长理解用户到底想要什么。
Codex 更偏工程层。
它擅长把任务落到代码、文件、测试和 diff 上。
二者结合,才接近完整的 AI 工程运行链。
比如用户说:
text
订单筛选这里有 bug,空数组的时候接口会挂掉,帮我看一下。
ChatGPT 负责把它解析成任务:
json
{
"task_type": "debugging",
"module": "order_filter",
"symptom": "empty array causes API failure",
"expected_behavior": "empty array should not crash",
"recommended_strategy": "diagnose before patch"
}
Codex 负责进入代码上下文:
text
1. 搜索 order filter 相关文件
2. 找到 controller / service / test
3. 分析空数组处理逻辑
4. 生成最小补丁
5. 补测试
6. 运行测试
7. 总结 diff
可以抽象成:
python
class ChatGPTLayer:
def parse_intent(self, user_input: str) -> dict:
return {
"task_type": "debugging",
"module": "order_filter",
"symptom": "empty array causes failure",
"constraints": ["minimal_change", "preserve_api_contract"]
}
class CodexLayer:
def solve_task(self, task_ir: dict, repo_context: dict) -> dict:
files = self.find_related_files(task_ir, repo_context)
plan = self.create_patch_plan(task_ir, files)
patch = self.generate_patch(plan)
tests = self.generate_tests(task_ir, files)
return {
"patch": patch,
"tests": tests,
"risk": self.analyze_risk(patch)
}
这里的关键不是"AI 写了代码"。
关键是任务被分层处理了。
三、AI Agent 需要一种 Task IR
传统编译器里,源码不会直接生成机器码。
通常会先变成中间表示,也就是 IR。
IR 的好处是:
- 比源码更结构化;
- 比机器码更抽象;
- 方便优化;
- 方便跨平台;
- 方便做静态分析。
AI Agent 也需要类似的中间表示。
可以叫:
text
Task IR
Task IR 是自然语言和工具执行之间的中间层。
例如用户输入:
text
帮我重构一下订单模块,不要影响现在接口。
直接执行很危险。
因为"重构"太宽泛。
更合理的方式是先生成 Task IR:
json
{
"task_id": "order_refactor_001",
"type": "refactor",
"target_module": "order",
"goal": "improve maintainability",
"hard_constraints": [
"do_not_change_public_api",
"do_not_modify_unrelated_modules",
"preserve_existing_behavior"
],
"risk_level": "medium",
"required_steps": [
"inspect_module_structure",
"identify_code_smells",
"propose_refactor_plan",
"request_human_review",
"apply_minimal_patch",
"run_regression_tests"
],
"verification": [
"existing_tests_pass",
"api_contract_unchanged",
"diff_scope_limited"
]
}
这个 Task IR 的作用很大。
它把模糊意图变成了可治理对象。
有了 Task IR,系统就可以做:
text
权限检查
风险评估
上下文检索
任务规划
工具选择
结果验证
审计记录
否则,AI 就只能靠自然语言直接猜。
这也是 AI Agent 工程化的关键:
不能让模型直接从自然语言跳到行动。
中间必须有结构化任务表示。
四、Task IR 的数据结构设计
可以定义一个简单的 Task IR 类型:
python
from dataclasses import dataclass, field
from typing import Literal
RiskLevel = Literal["low", "medium", "high"]
TaskType = Literal[
"writing",
"debugging",
"refactor",
"feature",
"analysis",
"tool_action"
]
@dataclass
class TaskIR:
task_id: str
task_type: TaskType
goal: str
target: str | None = None
constraints: list[str] = field(default_factory=list)
assumptions: list[str] = field(default_factory=list)
unknowns: list[str] = field(default_factory=list)
required_context: list[str] = field(default_factory=list)
steps: list[str] = field(default_factory=list)
verification: list[str] = field(default_factory=list)
risk_level: RiskLevel = "low"
requires_human_review: bool = False
然后构造一个任务:
python
task = TaskIR(
task_id="debug_order_filter_empty_array",
task_type="debugging",
goal="Fix API failure when order status filter receives an empty array",
target="order_filter",
constraints=[
"preserve_public_api",
"minimal_diff",
"do_not_modify_unrelated_files"
],
unknowns=[
"exact_error_log",
"related_test_files",
"current_service_logic"
],
required_context=[
"order controller",
"order service",
"filter query builder",
"existing tests"
],
steps=[
"inspect_related_files",
"identify_root_cause",
"create_minimal_patch",
"add_tests",
"run_tests",
"summarize_diff"
],
verification=[
"status=[] returns all orders or valid empty result",
"status=null does not crash",
"existing response schema unchanged",
"all related tests pass"
],
risk_level="medium",
requires_human_review=True
)
这看起来像普通数据结构,但它的意义很大。
它让 AI 任务从"文本"变成了"对象"。
只要任务对象化,就可以被系统管理。
五、从 Task IR 到 Execution Plan
Task IR 只是任务描述。
真正执行前,还要编译成 Execution Plan。
也就是具体执行步骤。
text
Task IR
↓
Planner
↓
Execution Plan
示例:
python
@dataclass
class ExecutionStep:
name: str
action_type: str
tool: str | None
input_ref: str | None
output_ref: str | None
risk_level: RiskLevel
requires_approval: bool = False
@dataclass
class ExecutionPlan:
task_id: str
steps: list[ExecutionStep]
生成计划:
python
plan = ExecutionPlan(
task_id="debug_order_filter_empty_array",
steps=[
ExecutionStep(
name="Search order filter files",
action_type="tool_call",
tool="search_code",
input_ref="target:order_filter",
output_ref="related_files",
risk_level="low"
),
ExecutionStep(
name="Read related files",
action_type="tool_call",
tool="read_file",
input_ref="related_files",
output_ref="file_context",
risk_level="low"
),
ExecutionStep(
name="Generate patch plan",
action_type="model_reasoning",
tool=None,
input_ref="file_context",
output_ref="patch_plan",
risk_level="medium",
requires_approval=True
),
ExecutionStep(
name="Apply patch",
action_type="tool_call",
tool="apply_patch",
input_ref="patch_plan",
output_ref="diff",
risk_level="medium",
requires_approval=True
),
ExecutionStep(
name="Run tests",
action_type="tool_call",
tool="run_tests",
input_ref="related_tests",
output_ref="test_result",
risk_level="low"
)
]
)
这里就出现了 AI Agent 和普通大模型的区别。
普通大模型回答:
text
你可以这样改......
AI Agent 执行计划:
text
我将先搜索文件,再读取上下文,再生成补丁计划,再等待确认,再应用补丁,再运行测试。
这是两个层级。
前者是建议。
后者是任务调度。
六、Planner 是 AI Agent 的大脑,不是模型本身
很多人以为模型就是 Agent 的大脑。
更准确地说,模型只是推理引擎。
真正的"大脑"是 Planner。
Planner 负责把 Task IR 变成可执行计划。
一个简单 Planner 可以这样写:
python
class Planner:
def create_plan(self, task: TaskIR) -> ExecutionPlan:
if task.task_type == "debugging":
return self._debugging_plan(task)
if task.task_type == "refactor":
return self._refactor_plan(task)
if task.task_type == "writing":
return self._writing_plan(task)
raise ValueError(f"Unsupported task type: {task.task_type}")
def _debugging_plan(self, task: TaskIR) -> ExecutionPlan:
return ExecutionPlan(
task_id=task.task_id,
steps=[
ExecutionStep(
name="collect_context",
action_type="tool_call",
tool="search_code",
input_ref=task.target,
output_ref="related_files",
risk_level="low"
),
ExecutionStep(
name="inspect_files",
action_type="tool_call",
tool="read_file",
input_ref="related_files",
output_ref="file_context",
risk_level="low"
),
ExecutionStep(
name="diagnose_root_cause",
action_type="model_reasoning",
tool=None,
input_ref="file_context",
output_ref="diagnosis",
risk_level="low"
),
ExecutionStep(
name="propose_fix",
action_type="model_reasoning",
tool=None,
input_ref="diagnosis",
output_ref="patch_plan",
risk_level="medium",
requires_approval=True
)
]
)
Planner 的质量决定 Agent 的工作质量。
如果 Planner 太激进,AI 会跳过验证直接执行。
如果 Planner 太保守,AI 每一步都要问人,效率低。
如果 Planner 没有风险意识,AI 可能做出不可逆操作。
如果 Planner 不理解任务类型,就会用错误流程处理任务。
所以 AI Agent 的关键不是单纯"模型更强"。
而是:
text
模型 + 任务表示 + Planner + 工具 + 验证
这才是完整系统。
七、Verifier 是 AI Agent 的类型系统
传统编译器有类型系统。
类型系统可以在运行前发现错误。
比如:
python
def add(a: int, b: int) -> int:
return a + b
如果传入字符串,类型检查可以提前报错。
AI Agent 也需要类似的机制。
只不过它检查的不是变量类型,而是任务执行是否符合约束。
可以把 Verifier 理解成 AI Agent 的"类型系统"。
它检查:
text
任务目标是否匹配
上下文是否足够
执行计划是否越权
工具调用参数是否合法
输出是否满足验收标准
是否违反硬性限制
是否需要人工确认
示例:
python
class Verifier:
def verify_plan(self, task: TaskIR, plan: ExecutionPlan) -> list[str]:
errors = []
if task.risk_level == "high" and not task.requires_human_review:
errors.append("High-risk task must require human review")
for step in plan.steps:
if step.risk_level == "medium" and step.tool == "apply_patch":
if not step.requires_approval:
errors.append("Applying patch requires approval")
if step.tool == "delete_file":
errors.append("delete_file is not allowed in current policy")
return errors
再比如验证补丁:
python
class PatchVerifier:
def verify_diff(self, diff: dict, task: TaskIR) -> list[str]:
errors = []
if "preserve_public_api" in task.constraints:
if diff.get("api_schema_changed"):
errors.append("Public API schema changed")
if "do_not_modify_unrelated_files" in task.constraints:
if diff.get("unrelated_files_modified"):
errors.append("Unrelated files modified")
if diff.get("new_dependencies"):
errors.append("New dependencies introduced")
return errors
这就是 AI 工程化的重要思想:
不要相信生成结果,必须让结果通过类型检查式的验证。
八、上下文构造类似依赖解析
编译器在编译代码时,需要解析依赖。
如果缺少依赖,就无法正确编译。
AI Agent 处理任务时,也需要依赖解析。
只不过这里的依赖不是包,而是上下文。
例如 Codex 处理代码任务时,需要:
text
当前文件
调用方
被调用方
接口定义
测试文件
配置文件
历史约束
可以设计一个 Context Resolver:
python
class ContextResolver:
def resolve(self, task: TaskIR, repo) -> dict:
context = {}
if task.task_type == "debugging":
context["entry_files"] = repo.search(task.target)
context["tests"] = repo.find_tests(task.target)
context["configs"] = repo.find_configs(task.target)
if "preserve_public_api" in task.constraints:
context["api_contracts"] = repo.find_api_contracts(task.target)
return context
这个过程类似:
text
Task Target
↓
Context Dependency Graph
↓
Minimal Context Slice
上下文不是越多越好。
就像编译器不会把整个互联网都当依赖一样。
Codex 也不应该把整个代码库无脑塞给模型。
它需要最小上下文切片。
python
class ContextSlice:
def __init__(self):
self.files = []
self.tests = []
self.contracts = []
self.configs = []
self.constraints = []
高质量上下文切片,是 Codex 输出稳定的关键。
九、工具调用类似后端代码生成
传统编译器最终会生成目标代码。
AI Agent 最终会调用工具。
工具调用可以看成 Agent 的后端。
text
Task IR
↓
Execution Plan
↓
Tool Calls
例如:
python
class ToolCall:
def __init__(self, tool_name: str, arguments: dict):
self.tool_name = tool_name
self.arguments = arguments
tool_calls = [
ToolCall("search_code", {"query": "order filter status"}),
ToolCall("read_file", {"path": "src/order/service.ts"}),
ToolCall("run_tests", {"target": "order_service_test"})
]
工具调用前必须做参数验证:
python
class ToolCallValidator:
def validate(self, call: ToolCall) -> bool:
if call.tool_name == "read_file":
return self._is_safe_path(call.arguments["path"])
if call.tool_name == "run_command":
return not self._contains_dangerous_command(
call.arguments["command"]
)
return True
这和编译器后端很像。
编译器不能生成非法机器码。
Agent 不能生成非法工具调用。
十、AI Agent 需要 Runtime,而不是裸模型
很多人做 AI 应用,结构很简单:
python
response = model.generate(prompt)
这适合轻量场景。
但不适合复杂任务。
复杂任务需要 Runtime。
python
class AgentRuntime:
def __init__(self, parser, planner, context_resolver, verifier, tool_executor):
self.parser = parser
self.planner = planner
self.context_resolver = context_resolver
self.verifier = verifier
self.tool_executor = tool_executor
def run(self, user_input: str):
task_ir = self.parser.parse(user_input)
context = self.context_resolver.resolve(task_ir)
plan = self.planner.create_plan(task_ir)
plan_errors = self.verifier.verify_plan(task_ir, plan)
if plan_errors:
return {
"status": "plan_rejected",
"errors": plan_errors
}
results = []
for step in plan.steps:
if step.requires_approval:
return {
"status": "approval_required",
"step": step
}
result = self.tool_executor.execute(step, context)
results.append(result)
result_errors = self.verifier.verify_result(step, result)
if result_errors:
return {
"status": "execution_failed",
"errors": result_errors,
"partial_results": results
}
return {
"status": "done",
"results": results
}
这个 Runtime 才是 AI Agent 的核心。
模型只是 Runtime 里的一个组件。
十一、为什么 CSDN 技术写作应该关注这种结构
很多 AI 文章停留在应用层:
怎么提问。
怎么写代码。
怎么提升效率。
怎么做插件。
怎么使用某个功能。
这些内容适合入门。
但对技术社区来说,更值得讨论的是:
text
AI 应用如何工程化?
AI Agent 如何建模?
自然语言如何转成任务表示?
工具调用如何治理?
验证系统如何设计?
上下文如何解析?
任务如何调度?
AI Runtime 如何落地?
这类问题才更接近软件工程本质。
因为未来的 AI 应用,不会只是一个聊天框。
更可能是一个由多个模块组成的运行时系统:
text
NLU Layer
Task IR Layer
Context Layer
Planner Layer
Tool Layer
Verifier Layer
Memory Layer
Audit Layer
也可以画成:
text
┌────────────────────┐
│ User Intent │
└─────────┬──────────┘
↓
┌────────────────────┐
│ Intent Parser │
└─────────┬──────────┘
↓
┌────────────────────┐
│ Task IR │
└─────────┬──────────┘
↓
┌────────────────────┐
│ Context Resolver │
└─────────┬──────────┘
↓
┌────────────────────┐
│ Planner │
└─────────┬──────────┘
↓
┌────────────────────┐
│ Tool Executor │
└─────────┬──────────┘
↓
┌────────────────────┐
│ Verifier │
└─────────┬──────────┘
↓
┌────────────────────┐
│ Final Response │
└────────────────────┘
这才是 ChatGPT 与 Codex 背后真正高阶的程序结构。
十二、写在最后:AI Agent 的本质是意图编译器
如果用一句话总结:
AI Agent 是一种意图编译器。
它把自然语言意图编译成任务中间表示。
再把任务中间表示编译成执行计划。
再把执行计划编译成工具调用。
最后通过验证系统确认结果是否符合目标。
完整链路是:
text
Human Intent
↓
Intent Parser
↓
Task IR
↓
Context Resolver
↓
Execution Plan
↓
Tool Calls
↓
Verification
↓
System Output
ChatGPT 在这个结构里,更像前端编译器。
它负责理解自然语言、提取意图、组织任务。
Codex 在这个结构里,更像面向代码世界的后端生成器。
它负责理解工程上下文、生成补丁、调用测试、解释 diff。
而 AI Agent Runtime 则负责把二者串起来。
这比"AI 会写代码"更深。
因为真正的变化不是代码生成变快。
而是软件系统开始接受更高层级的输入。
过去,人必须把需求翻译成代码,机器才能执行。
现在,AI 开始帮助机器理解人的意图。
这意味着软件系统的入口正在上移:
text
从按钮
到命令
到代码
到自然语言
到意图
未来程序员真正要掌握的,可能不只是写业务代码。
还包括设计:
text
意图如何解析
任务如何表示
上下文如何选择
计划如何生成
工具如何调用
结果如何验证
错误如何回滚
这就是 ChatGPT 与 Codex 真正进入工程系统后的核心问题。
不是模型会不会回答。
而是我们能不能设计一个可靠的系统,把回答变成可控行动。
从这个角度看,AI Agent 不是聊天机器人。
它更像下一代软件运行时。
而 ChatGPT 与 Codex,只是这个运行时中最先被看见的两个关键组件。