Codex Agent
本文介绍如何将Codex Agent接入华为云AgentArts观测服务,实现调用链追踪和业务指标监控。接入后无需修改业务代码,探针通过HTTP代理模式自动拦截Codex CLI的API调用,采集Agent对话、LLM调用、工具调用等数据并上报。
快速入门:
前提:本地已安装Codex CLI并可正常使用,已安装Python(版本>= 3.9)。
- 在AgentArts平台创建Codex智能体,获取接入参数。
- 安装探针whl包,准备config.json配置文件,修改Codex的base_url指向代理端口。
- 使用codex-traced.cmd启动脚本启动Codex,在AgentArts观测页面查看调用链和指标数据。
详细步骤见下方接入步骤。
前提条件
工作原理
Codex CLI是OpenAI开源的代码生成智能体,提供代码搜索、代码生成、工具调用等能力,支持在终端中直接运行。
Codex CLI架构:
- Rust核心:负责HTTP请求、模型推理、工具执行。
- Node.js客户端:负责CLI交互、TUI渲染。
由于Codex的HTTP请求由Rust核心直接发出,不经过Node.js的HTTP模块,传统的Node.js进程内注入方式(monkey-patch)无法拦截。本探针采用HTTP代理模式:在本地启动一个OTel代理服务器,在网络层拦截Codex CLI的API调用,自动创建调用链和指标数据并上报。
数据流转过程:
Codex CLI
├── base_url指向代理端口 (http://localhost:8090/v1)
│
▼
OTel 代理服务器 (端口 8090)
├── 拦截 POST /v1/responses 或 /v1/chat/completions
├── 创建 OpenTelemetry Span,记录请求/响应信息
├── 请求转发到真实模型端点 (proxy.upstream)
├── 解析响应中的 Token 用量、首 Token 延时等数据
│
├── Trace数据 ──OTLP gRPC──→ APM(调用链)
└── Metrics数据 ──OTLP gRPC──→ AOM(指标)
│
▼
AgentArts观测平台展示 Codex接入探针后base_url改为指向探针代理(端口8090),探针代理再将请求转发到原始模型端点(proxy.upstream)。唯一的配置变更就是修改base_url的指向——这是纯地址指向,不是代码注入,不影响Codex的任何功能。
探针工作流程:
- 将Codex CLI的base_url配置为代理地址(http://localhost:8090/v1)。
- 代理拦截每个POST请求到/v1/responses或/v1/chat/completions。
- 创建OpenTelemetry Span,记录请求/响应信息。
- 请求转发到真实模型端点(proxy.upstream),响应原样返回给Codex。
- 代理解析响应中的Token用量、首Token延时等数据。
- 数据上报到华为云APM(调用链)和AOM(指标)。
接入后,以下能力将被自动监控:
- Agent对话链路(AGENT:gen_ai.chat):对话请求的完整生命周期。
- LLM调用:模型名称、Token用量、输入/输出内容、首Token延时(TTFT)、总延时。
- 工具调用(PLUGIN:codex.tool_call):工具名称、输入参数、返回结果。
| 数据类型 | 上报方式 | 默认延迟 |
|---|---|---|
| Trace(调用链) | 批量上报 | 几秒内 |
| Metrics(指标) | 周期上报 | 最长60秒 |
- Trace:Span结束后先进入内存队列,达到一定数量或超时后批量发送(默认队列2048,超时5秒)。
- Metrics:默认每60秒上报一次(由OTEL_METRIC_EXPORT_INTERVAL控制)。
接入步骤
步骤一:获取接入参数
- 登录AgentArts 智能体平台。
- 在左侧导航栏选择“观测与优化 > 观测”。
- 在“智能体列表”页面,单击“接入智能体”,按照页面指引填写名称、智能体类型,创建一个“Codex”智能体,并获取各配置参数。 图1 获取配置参数
步骤二:安装探针
- 下载探针。 下载Codex探针包,探针下载到本地项目后执行安装。
pip install huaweicloud_opentelemetry_instrumentation_codex-1.0.0-py3-none-any.whl --force-reinstall - 验证探针安装成功。
python -c "from opentelemetry.instrumentation.huawei_codex import auto_instrument; print('codex probe OK')"输出codex probe OK即安装成功。
- 定位探针安装目录。
whl包安装后,config.example.json(配置模板)、codex-traced.cmd(启动脚本)、load_config.py(配置加载脚本)等文件会释放到Python的site-packages目录下。执行以下命令查看site-packages路径:
python -c "import sysconfig; print(sysconfig.get_paths()['purelib'])"
输出示例(Windows):C:\Users\<用户名>\AppData\Local\Programs\Python\Python311\Lib\site-packages
探针文件位于该路径下的opentelemetry/instrumentation/huawei_codex/子目录中。请记录此路径,后续步骤需要用到。
步骤三:准备配置文件
探针通过本地配置文件config.json管理全部配置(凭证、代理、日志),无需再手动设置环境变量。
- 创建探针工作目录。
建议在本地创建一个专用目录用于存放探针配置和启动脚本,例如C:\codex-probe:
mkdir C:\codex-probe
- 从探针安装目录中复制所需文件到工作目录。
将以下文件从<site-packages>\opentelemetry\instrumentation\huawei_codex\复制到C:\codex-probe\:
- config.example.json(配置模板)
- codex-traced.cmd(启动脚本)
- load_config.py(配置加载脚本)
copy "<site-packages路径>\opentelemetry\instrumentation\huawei_codex\config.example.json" C:\codex-probe\ copy "<site-packages路径>\opentelemetry\instrumentation\huawei_codex\codex-traced.cmd" C:\codex-probe\ copy "<site-packages路径>\opentelemetry\instrumentation\huawei_codex\load_config.py" C:\codex-probe\
其中<site-packages路径>为步骤二:安装探针第3步中获取的路径。
- 将模板复制为config.json。
在工作目录中执行:
cd C:\codex-probe copy config.example.json config.json
- 编辑config.json,将占位符替换为实际值。各参数值参考步骤一:获取接入参数获取。
用文本编辑器打开C:\codex-probe\config.json,编辑以下内容:
{ "version": "1.0.0", "enabled": true, "outputDir": "/tmp", "proxy": { "port": 8090, "upstream": "<CODEX_ORIGINAL_BASE_URL>" }, "otel": { "agentarts_agentops_otel_agent_apm_enable": true, "agentarts_agentops_otel_agent_aom_enable": true, "agent_domain_id": "<AGENT_DOMAIN_ID>", "agentarts_project_id": "<AGENTARTS_PROJECT_ID>", "agent_resource_id": "<AGENT_RESOURCE_ID>", "resource_type": "<AGENT_TYPE>", "agentarts_agentops_apm_token": "<APM_TOKEN>", "agentarts_agentops_apm_exporter_endpoint": "<APM_ENDPOINT>:4317", "agentarts_agentops_aom_access_code": "<AOM_ACCESS_CODE>", "agentarts_agentops_aom_exporter_endpoint": "<AOM_ENDPOINT>:4317", "agentarts_agentops_aom_prometheus_id": "<AOM_PROMETHEUS_ID>" } }表2 参数说明 参数
是否必填
说明
otel.agent_domain_id
是
账号Domain ID。
otel.agentarts_project_id
是
华为云项目ID。
otel.agent_resource_id
是
智能体ID。
otel.resource_type
是
智能体类型:agent(单智能体)、multiagents(多智能体)、workflow(工作流)。
otel.agentarts_agentops_apm_token
条件必填(上报调用链数据时必填)
APM接入凭证。
otel.agentarts_agentops_apm_exporter_endpoint
条件必填(上报调用链数据时必填)
APM数据上报地址。
otel.agentarts_agentops_aom_access_code
条件必填(上报指标数据时必填)
AOM接入凭证Access Code。
otel.agentarts_agentops_aom_exporter_endpoint
条件必填(上报指标数据时必填)
AOM数据上报地址。
otel.agentarts_agentops_aom_prometheus_id
条件必填(上报指标数据时必填)
AOM Prometheus实例ID。
proxy.upstream
是
Codex接入观测前的模型端点地址(代理转发目标)。即Codex的config.toml中base_url的原始值。
例如:使用OpenAI API时填https://api.openai.com/v1;使用本地Ollama时填http://localhost:11434/v1。
- proxy.upstream是探针代理转发的目标地址,必须与Codex接入观测前的base_url一致。探针代理会将拦截到的请求转发到该地址。
- APM/AOM开关默认开启,某服务凭证缺失会只禁用该服务(日志warning),另一服务仍正常上报;显式设置=false可关闭对应服务。
步骤四:修改Codex配置
将Codex的base_url从原始模型端点改为探针代理地址,使Codex的请求经过探针代理拦截。
- 打开Codex配置文件。
Codex配置文件路径:
- Windows:%USERPROFILE%\.codex\config.toml(即C:\Users\<用户名>\.codex\config.toml)
- Linux/macOS:~/.codex/config.toml
如果该文件不存在,先创建.codex目录和文件:
mkdir %USERPROFILE%\.codex type nul > %USERPROFILE%\.codex\config.toml
- 找到[model_providers.<id>]段(当前使用的model provider),将base_url改为探针代理地址。
修改前(示例,base_url指向原始模型端点):
model_provider = "custom" model = "gpt-4o" model_reasoning_effort = "high" [model_providers.custom] name = "custom" wire_api = "responses" base_url = "https://api.openai.com/v1"
修改后(base_url指向探针代理端口8090):
model_provider = "custom" model = "gpt-4o" model_reasoning_effort = "high" [model_providers.custom] name = "custom" wire_api = "responses" base_url = "http://localhost:8090/v1"
- 仅修改base_url的值,将其从原始模型端点改为探针代理地址(默认http://localhost:8090/v1)。其他配置项(model、model_provider、wire_api、env_key等)保持不变。
- base_url的端口必须与config.json中proxy.port的取值一致(默认8090)。
- 如果代理端口被占用,修改config.json中proxy.port(如8091)后,必须在此处同步修改base_url端口为http://localhost:8091/v1。
- 原始模型端点地址已记录在config.json的proxy.upstream中(步骤三:准备配置文件),探针代理会自动将请求转发到该地址。
- 以上示例使用custom作为provider ID,仅为说明格式。请根据实际配置修改,provider ID不能使用保留名称openai、ollama、lmstudio。
步骤五:启动与验证
方式一:使用启动脚本(推荐)
- 在命令行中切换到探针工作目录(即存放codex-traced.cmd和config.json的目录): 在步骤三:准备配置文件中,已创建一个专用目录用于存放探针配置和启动脚本,进入到该目录。
cd C:\codex-probe
- 执行启动脚本。
codex-traced
脚本会自动完成以下操作:
- 通过load_config.py自动从config.json(或config.example.json)加载配置,设置代理端口、上游端点、APM/AOM凭证等对应环境变量。
- 检查CODEX_UPSTREAM_ENDPOINT是否设置。
- 在后台(无窗口)启动OTel代理。
- 轮询/health端点验证代理是否就绪。
- 启动Codex CLI。
- Codex退出后自动清理代理进程。
方式二:手动启动
如果不使用启动脚本,可以手动分步执行:
- 在命令行中切换到探针工作目录:
在步骤三:准备配置文件中,已创建一个专用目录用于存放探针配置和启动脚本,进入到该目录。
cd C:\codex-probe
- 通过load_config.py加载config.json设置环境变量,然后在后台启动代理:
for /f "delims=" %v in ('python -m opentelemetry.instrumentation.huawei_codex.load_config .') do %v start /min cmd /c "python -c "from opentelemetry.instrumentation.huawei_codex import auto_instrument; auto_instrument(); import time; time.sleep(99999)"" - 等待2-3秒后,验证代理是否就绪:
python -c "import http.client; c=http.client.HTTPConnection('localhost', 8090, timeout=3); c.request('GET', '/health'); r=c.getresponse(); print('proxy ready' if r.status==200 else 'proxy NOT ready'); c.close()"输出proxy ready后启动Codex:
codex
验证数据上报
启动完成后,可通过以下步骤验证探针是否正常工作:
- 查看代理日志,确认代理已正常启动。
如果config.json中outputDir配置为/tmp(默认值),日志文件为%TEMP%\codex-proxy.log:
type %TEMP%\codex-proxy.log
如果配置了自定义outputDir(如/d/codex-probe-logs),则查看对应目录下的codex-proxy.log。
正常情况下,日志应包含以下关键信息:
CodexProbe | TracerProvider configured successfully CodexProbe | MeterProvider configured successfully CodexProxy | listening on port 8090, forwarding to <proxy.upstream地址> CodexProxy | 127.0.0.1 - POST /v1/responses
- 在Codex中进行几轮对话,触发数据上报。
- 前往AgentArts平台观测页面查看数据。数据上报存在延迟:Trace几秒内上报,Metrics最长60秒。
配置文件说明
探针不再依赖手动设置环境变量,全部配置集中在config.json(模板config.example.json),由启动脚本自动加载。以下为config.json各字段与对应含义:
| 配置字段 | 说明 | 是否必填 | 示例值 |
|---|---|---|---|
| otel.agent_domain_id | 账号Domain ID | 是 | your-domain-id |
| otel.agentarts_project_id | 华为云项目ID | 是 | your-project-id |
| otel.agent_resource_id | 智能体ID | 是 | your-agent-id |
| otel.resource_type | 智能体类型:agent、multiagents、workflow | 是 | agent |
| otel.agentarts_agentops_apm_token | APM接入凭证Token | 条件必填(上报调用链数据时必填) | your-apm-token |
| otel.agentarts_agentops_apm_exporter_endpoint | APM OTLP数据上报地址 | 条件必填(上报调用链数据时必填) | http://<APM地址> |
| otel.agentarts_agentops_aom_access_code | AOM接入凭证 | 条件必填(上报指标数据时必填) | your-aom-access-code |
| otel.agentarts_agentops_aom_exporter_endpoint | AOM OTLP数据上报地址 | 条件必填(上报指标数据时必填) | http://<AOM地址> |
| otel.agentarts_agentops_aom_prometheus_id | Prometheus实例ID | 条件必填(上报指标数据时必填) | your-prometheus-id |
| proxy.upstream | 真实模型端点地址(代理转发目标,即Codex接入观测前的base_url) | 是 | https://api.openai.com/v1 |
| 配置字段 | 说明 | 默认值 |
|---|---|---|
| enabled | 是否输出代理日志 | true |
| outputDir | 代理日志输出目录 | /tmp |
| proxy.port | 代理监听端口 | 8090 |
| otel.agentarts_agentops_otel_agent_apm_enable | 是否启用APM Trace | true |
| otel.agentarts_agentops_otel_agent_aom_enable | 是否启用AOM Metrics | true |
| otel.resource_version | 智能体版本 | 0.1.0 |
| 环境变量agent_name | 智能体名称(写入Span名与属性) | codex |
| 环境变量AGENTARTS_AGENTOPS_USER_ID | 用户ID(注入user.id) | 主机名 |
| 环境变量OTEL_INSTRUMENTATION_GENAI_CAPTURE_MESSAGE_CONTENT | 是否采集输入/输出内容 | true |
| 环境变量OTEL_TRACES_EXPORTER | Trace导出器:otlp或console(本地调试用console) | otlp |
| 环境变量OTEL_METRICS_EXPORTER | Metrics导出器:otlp或console | otlp |
| 环境变量OTEL_METRIC_EXPORT_INTERVAL | Metrics上报/窗口周期(毫秒) | 60000 |
查看监控数据
数据上报成功后,可在AgentArts智能体平台的观测功能中查看监控数据。
- 登录AgentArts 智能体平台。
- 在左侧导航栏选择“观测与优化 > 观测”。
- 在“智能体列表”页面,找到已接入的智能体,单击智能体名称进入详情页面。
查看业务指标
在“指标分析”页签中,可以查看关键业务指标:
- Tokens消耗:Input Tokens和Output Tokens的消耗总量
- 模型调用次数:应用调用大模型的累计次数
- 模型调用平均耗时:模型调用的平均响应时间
- 模型调用成功率:大模型调用成功的比例
- 会话数:应用产生的会话总数
- 工具调用次数与耗时:工具调用总量、平均耗时(含 Skill 调用的独立指标)
- 响应成功率:服务响应的成功率
查看调用链信息
在“调用链分析”页签中,可以查看完整的Trace调用链路:
- 查看各Span类型的层级关系及各节点耗时
- 单击具体Span查看详细信息:
- Agent节点(invoke_agent):可查看Agent名称、输入/输出消息
- LLM节点(chat):可查看模型名称、输入/输出消息(Input/Output Messages)、Token消耗(Total tokens)
- Tool节点:可查看工具名称、输入参数、返回结果
- 中间件节点:可查看中间件执行耗时
查看会话分析
在“会话分析”页签中,可以查看智能体与用户对话的历史数据:
- 追踪对话上下文
- 分析模型响应耗时
- 统计Token消耗
- 快速定位对话异常问题
更多参考
控制内容采集
默认情况下,探针会采集LLM输入/输出内容。如需关闭(隐私/合规场景):
set OTEL_INSTRUMENTATION_GENAI_CAPTURE_MESSAGE_CONTENT=false
关闭后:
- LLM节点:gen_ai.input.messages / gen_ai.output.messages / input.value / output.value不采集。
- 模型名、Token用量、耗时、调用链结构等非内容属性不受影响。
本地调试(Console导出器)
无APM/AOM凭证时,可通过Console导出器在终端直接查看Span和指标:
set agentarts_project_id=<your-project-id> set agentarts_agentops_apm_token=<dummy> set agentarts_agentops_apm_exporter_endpoint=<dummy> set agentarts_agentops_aom_access_code=<dummy> set agentarts_agentops_aom_exporter_endpoint=<dummy> set agentarts_agentops_aom_prometheus_id=<dummy> set OTEL_TRACES_EXPORTER=console set OTEL_METRICS_EXPORTER=console codex-traced
跟Codex对话后,如果终端输出JSON格式的Span,说明探针正常工作。
代理日志
代理日志由config.json的enabled(是否写日志)与outputDir(日志目录)控制:
{
"enabled": true,
"outputDir": "/d/codex-probe-logs"
} 日志文件为codex-proxy.log(默认目录/tmp,文件名同%TEMP%兜底)。排查问题时查看该文件:
type %TEMP%\codex-proxy.log
若配置了outputDir,则查看对应目录下的codex-proxy.log。
常见问题
如何卸载探针与回滚到旧版本
- 停止代理进程(如果正在运行):
taskkill /fi "WINDOWTITLE eq codex-proxy*" /f
- 恢复Codex配置文件中的base_url为原始模型端点地址。
编辑%USERPROFILE%\.codex\config.toml,将base_url从http://localhost:8090/v1改回原始模型端点地址。
- 卸载探针包:
pip uninstall huaweicloud-opentelemetry-instrumentation-codex
代理启动失败:端口被占用
- 检查端口是否被占用:
netstat -an | findstr 8090
- 如果被占用,修改config.json中proxy.port:
"proxy": { "port": 8091, "upstream": "https://api.openai.com/v1" } - 同步修改Codex配置中的base_url为http://localhost:8091/v1。
代理启动失败:探针未安装
- 验证探针是否安装:
python -c "from opentelemetry.instrumentation.huawei_codex import auto_instrument; print('OK')" - 如果报ModuleNotFoundError,请参考步骤二:安装探针重新安装探针。
Codex连接失败
- 确认代理已启动并就绪:
python -c "import http.client; c=http.client.HTTPConnection('localhost', 8090, timeout=3); c.request('GET', '/health'); r=c.getresponse(); print(r.status, r.read().decode()); c.close()"返回200 OK说明代理正常。
- 确认proxy.upstream配置正确(指向真实模型端点)。
- 确认Codex配置base_url指向代理端口(http://localhost:8090/v1)。
- 确认真实模型端点可达:
curl <proxy.upstream地址>
无数据上报
- 查看代理日志,确认是否出现CodexProbe | env is not complete or probe is turned off,出现该日志说明config.json中凭证不完整或未正确加载。
- 确认config.json已存在且已填真实值(模板config.example.json中的占位符<...>会被跳过)。
- 确认config.json为合法JSON(不能以逗号结尾、注释要使用合法格式)。
- 用Console导出器验证Span是否生成(临时设置即可,不影响config):
set OTEL_TRACES_EXPORTER=console set OTEL_METRICS_EXPORTER=console codex-traced
跟Codex对话后,如果终端输出JSON格式的Span,说明探针正常,问题在上报端(凭证/网络)。
- 检查OTLP端点是否可达:
curl http://<APM_ENDPOINT> curl http://<AOM_ENDPOINT>
- 确认OTLP端点地址包含http://前缀(例如http://<APM地址>:4317)且与config.json一致。
代理拦截到请求但无数据上报
- 检查代理日志是否有CodexProxy | 127.0.0.1 - POST /v1/responses(确认请求被拦截)。
- 检查APM/AOM凭证是否正确。
- 检查网络连通性:OTLP端点4317端口是gRPC协议,用curl测试会返回HTTP/0.9,这是正常的。
- 确认数据上报延迟:Trace几秒内上报,Metrics最长60秒。