mobile wallpaper 1mobile wallpaper 2mobile wallpaper 3mobile wallpaper 4mobile wallpaper 5mobile wallpaper 6
2517 字
7 分钟
模型不是进程:从一次工具调用理解 Agent 如何运行
2026-10-22
2026-10-22
—

假设我对 Codex 说:“读一下这个仓库,修复失败的测试,然后运行 pytest。”屏幕上随后出现文件读取、补丁和终端输出。最容易产生的错觉是:GPT 模型像一个登录了电脑的程序,亲自打开文件并执行命令。

这个场景恰好适合用 408 操作系统知识拆开。模型给出下一步的候选动作,Agent Runtime 组织并约束动作,真正的读写与执行仍由程序、进程和操作系统完成。 这几者没有固定的一对一关系。

01|从一次 Codex 工具执行说起#

“运行 pytest”至少包含两个不同的问题:是否应该运行,以及谁来运行。模型可依据输入生成工具调用请求,例如工具名、命令和参数;请求本身还没有启动 pytest。运行环境收到请求后,才会检查工具是否存在、参数是否合规、当前权限是否允许,再交给执行器。OpenAI 的 Function Calling 文档把这条链路写成:提供工具、收到调用、应用侧执行、把结果送回模型、获得后续响应。OpenAI 对 Codex Harness 的公开介绍也将 Agent Loop、工具执行与沙盒列为软件层职责。

本文只用公开接口和通用操作系统原理解释这个过程,不把示意流程当成 Codex 每个版本的内部调用栈。

02|模型、Agent 与进程分别是什么#

模型权重是训练得到的参数数据;推理服务加载权重并进行计算,接收输入后生成输出。权重文件不是正在运行的程序,也没有 PID。推理服务本身会运行在计算设备上的软件环境里,但不能据此说“一个模型等于一个进程”:服务可以有多个工作进程,也可以同时处理多个请求。

Agent 是围绕目标组织模型、上下文、工具与反馈的软件系统;Agent Runtime(也常称 Harness)是其中驱动执行的软件层。进程则是操作系统管理的一次程序执行,有地址空间、进程标识和内核维护的控制信息。课本里的 PCB(进程控制块)属于操作系统对进程的表示,模型权重并不是 PCB。一个 Agent 任务可能跨多个本地或远程进程;一个 Runtime 进程也可能承载多个任务。

所以这些词处于不同抽象层:模型描述计算能力,Agent 描述任务系统,Runtime 描述控制软件,进程描述 OS 资源管理单位。它们可以关联,却不能直接画等号。

还可以从“重启会发生什么”检验这个区分。推理服务进程重启,模型权重可以重新加载;Agent 任务是否能续接,取决于会话和执行状态有没有被保存;一个已经启动的测试子进程能否继续被管理,又取决于执行环境的生命周期。三个问题答案可能完全不同。如果把它们都称作“模型还在不在”,就会失去分析故障所需的层次。

03|一次工具调用如何闭环#

以运行测试为例,Runtime 先收集用户目标、相关文件和可用工具描述,向模型服务发出请求。模型若返回“调用终端工具,参数为运行 pytest”,Runtime 要识别工具名、解析参数、应用权限策略,再把请求交给实际的工具执行器。执行器返回退出码、标准输出或错误摘要;Runtime 将这些结果与原来的调用关联,整理进下一轮输入。模型这时才有依据判断测试是否通过、是否还需修改。

从用户任务经 Agent Runtime 和模型推理服务,到工具执行环境与操作系统资源的流程图。

图 1:蓝框是 Agent Runtime 的逻辑职责;绿框表示工具实际运行的位置。模型输出调用请求,执行动作由 Runtime 授权后交给工具完成。

这里的“模型决定调用”是提出动作,不是获得执行权。即便模型生成了结构正确的命令,Runtime 也可以拒绝、要求审批或返回错误。反过来,工具执行完成也不意味着任务完成:模型可能依据失败输出继续定位问题。结果反馈改变的是下一轮输入和任务状态,不会自动修改模型参数。

调用请求也不能直接被当成可信程序输入。工具名需要匹配已注册能力,参数要满足类型与业务限制,命令与路径要符合当前任务权限。模型可能写错字段,也可能被仓库中的不可信文本诱导。把“模型建议”与“系统授权”分成两步,才能让调用链在错误发生时有明确的拒绝点。

04|工具究竟在哪里运行#

“调用工具”并不指定一种固定的 OS 形态。读取一个内存对象可能只是 Runtime 进程内的函数调用;运行 pytest 通常会启动子进程;搜索网页可能由远程服务执行,Runtime 只发网络请求。有些工具在容器或独立沙盒里运行。一次工具调用不必对应一次新进程。

下面的 Python 代码可以在有 Python 3 的 Windows、Linux 或 macOS 终端中运行。它用 subprocess.run 启动一个子 Python 解释器,再收集输出和退出码:

import os
import subprocess
import sys
result = subprocess.run(
[sys.executable, "-c",
"import os; print('child PID:', os.getpid()); "
"print('parent PID:', os.getppid())"],
capture_output=True, text=True, check=False,
)
print("runner PID:", os.getpid())
print(result.stdout, end="")
print("exit code:", result.returncode)

在 Windows、Python 3.10.3 上的一次实际运行输出(PID 每次运行都会变化):

runner PID: 4500
child PID: 27060
parent PID: 4500
exit code: 0

Python subprocess 文档明确说明了新进程、标准输入输出管道与返回码。这个例子能证明父子进程和结果回收,却不能证明子进程已被安全隔离:它默认仍能使用所属用户拥有的文件与网络权限。代码里的“runner”只是本例的父 Python 程序,并非 Codex 的真实进程;这些 PID 也只属于这次实验。

05|回到 408 操作系统#

408 里的“程序”是待执行的指令与数据;“进程”是其运行实例。执行器启动测试时,操作系统创建进程并维护 PID、状态、地址空间等信息。Python 父进程等待 subprocess.run 返回时可能阻塞;子进程退出后,父进程从管道读取输出并得到退出码。若 Runtime 采用异步 I/O,它也可以在等待时处理其他任务。阻塞、就绪和运行是调度状态,不是模型的思考状态。

“父子进程”在不同系统上的实现细节也不同。Linux 可用 fork() 创建子进程,再用 exec 家族装载程序;Linux fork(2) 手册说明父子具有不同 PID 和独立地址空间。Windows 常见的是直接通过 CreateProcess 创建新进程。Python 提供统一的 subprocess 接口,不代表底层两个平台走完全相同的系统调用。

文件读取、进程创建、管道与网络通信最终都依赖操作系统接口。模型并不持有一个神奇的“直接操作磁盘”通道;把模型输出变为受限的系统行为,是 Runtime 和工具软件的工作。

还有一个容易混淆的点:进程状态描述的是 CPU 调度,不描述 Agent 的业务进度。测试进程等待磁盘读取时可能阻塞;I/O 完成后进入就绪队列,等 CPU 分配时间片继续运行。与此同时,Agent 的“等待工具结果”只是上层任务状态。把这两张状态图分开,才能解释为什么界面看似停住,后台却可能在等待网络、审批或子进程,而不是模型持续占用 CPU。

06|重新理解 Agent#

读到这里,三个常见误解就可以拆开。第一,Agent 不是 OS 进程:一个任务可跨进程、机器与服务。第二,产品里的 Agent Thread 通常指会话或任务历史,不等于操作系统线程;OpenAI 对 Codex 的公开说明就把 thread 定义为用户与 Agent 的一次会话及其持久事件历史。第三,工具返回新信息后继续推理,只是在新上下文上再次运行模型,不等于发生了参数训练。

我认为这个区分很实用。排查一次失败时,先问“是模型提出了错误动作、Runtime 错误分发、工具失败,还是 OS/网络拒绝访问”,比笼统地说“Agent 没跑起来”更容易定位问题。下一篇将继续沿这条边界,拆开 Agent Runtime 内部如何管理状态、工具、权限与恢复。

资料来源#

分享

如果这篇文章对你有帮助,欢迎分享给更多人!

模型不是进程:从一次工具调用理解 Agent 如何运行
https://jaisong1n.com/posts/wordpress/model-agent-process-tool-calling/
作者
JaisonG1n AI Writer
发布于
2026-10-22
许可协议
CC BY-NC-SA 4.0

部分信息可能已经过时

目录