CAI SDK 全局初始化与配置指南:OpenAI Key、客户端、API 协议与追踪开关全解析
【免费下载链接】caiCybersecurity AI (CAI), the framework for AI Security项目地址: https://gitcode.com/GitHub_Trending/cai3/cai
CAI(Cybersecurity AI)框架的cai.sdk.agents模块在进程启动阶段提供了一组轻量的全局配置函数,用于统一管理 LLM 请求所需的 API Key、OpenAI 客户端、底层 API 协议(Responses / Chat Completions)以及内置 Tracing 追踪系统的开关与导出行为。本文以 API 参考页 docs/ref/index.md 中列出的 7 个函数为骨架,结合 docs/config.md、docs/tracing.md 的官方说明与 src/cai/sdk/agents 的源码实现,完整讲解每个函数的签名、参数语义、底层调用链与组合实战用法,帮助你正确初始化 CAI 运行时,并把它接入 OpenAI、自建网关或本地模型服务。
一、模块定位:为什么需要全局配置函数
cai.sdk.agents是 CAI 框架的 Agent 运行时核心包。按 API 参考页的约定,模块公开了两类内容:
- 一类是类型与运行时对象:
Agent、Runner、Model、Tool、Handoff、Guardrail、RunResult等,它们构成 Agent 编排的主体; - 另一类就是本文主角——7 个模块级全局配置函数:
set_default_openai_key、set_default_openai_client、set_default_openai_api、set_tracing_export_api_key、set_tracing_disabled、set_trace_processors、enable_verbose_stdout_logging。
它们解决的问题非常一致:在运行 Agent 之前,把"连哪个模型服务、用什么 Key、走哪个 API、要不要上报追踪、日志要多详细"一次性配置好。因为OpenAIProvider会在创建模型时读取这些全局默认值,所以只要配置一次,后续所有Agent/Runner调用都会自动生效。
从源码看,这 7 个函数都是薄封装:LLM 相关的三个函数转发到 _config.py,再由其调用models/_openai_shared.py中维护的模块级单例状态;Tracing 相关的三个函数直接操作tracing/setup.py中的全局GLOBAL_TRACE_PROVIDER;日志函数则直接配置 Python logging。
二、LLM 请求配置:Key、客户端与 API 协议
2.1 set_default_openai_key:进程内注入 API Key
from cai.sdk.agents import set_default_openai_key set_default_openai_key("sk-...")签名:set_default_openai_key(key: str, use_for_tracing: bool = True) -> None
参数说明:
| 参数 | 类型 | 默认值 | 含义 |
|---|---|---|---|
key | str | 必填 | 用于 LLM 请求的 OpenAI API Key |
use_for_tracing | bool | True | 是否同时用该 Key 向 OpenAI 后端上传 Trace |
官方文档(docs/config.md)指出:SDK 默认在导入时读取OPENAI_API_KEY环境变量用于 LLM 请求和 Tracing。如果你无法在进程启动前设置该环境变量,就在代码里调用本函数注入。从实现看,_config.py的底层逻辑是:
- 调用
_openai_shared.set_default_openai_key(key),把 Key 写入模块级变量_default_openai_key(见 models/_openai_shared.py); - 若
use_for_tracing=True,再调用set_tracing_export_api_key(key),让默认的BackendSpanExporter用同一个 Key 上传 Trace。
_default_openai_key的实际消费点在 models/openai_provider.py:OpenAIProvider._get_client()创建AsyncOpenAI时按api_key=self._stored_api_key or _openai_shared.get_default_openai_key()取值,也就是说显式传入 provider 的 Key 优先,其次才轮到全局默认 Key,最后兜底由 OpenAI 客户端自身读取OPENAI_API_KEY环境变量。
2.2 set_default_openai_client:替换默认 AsyncOpenAI 客户端
from openai import AsyncOpenAI from cai.sdk.agents import set_default_openai_client custom_client = AsyncOpenAI(base_url="http://localhost:11434/v1", api_key="ollama") set_default_openai_client(custom_client)签名:set_default_openai_client(client: AsyncOpenAI, use_for_tracing: bool = True) -> None
SDK 默认会自行创建AsyncOpenAI实例(使用环境变量或默认 Key)。如果你的场景需要自定义base_url(如接入网关、代理或本地推理服务)、组织/项目 ID,或想复用已有的连接池,就用这个函数替换默认客户端。实现逻辑(_config.py):
_openai_shared.set_default_openai_client(client)写入模块级_default_openai_client;- 若
use_for_tracing=True,则把client.api_key作为 Tracing 导出 Key 写入 exporter。
OpenAIProvider._get_client()中优先返回get_default_openai_client(),只有未设置时才现场新建(openai_provider.py)。注意:新客户端默认共享一个全局httpx.AsyncClient(shared_http_client(),见 openai_provider.py),以复用连接池降低延迟与资源开销。
在 CAI 的安全攻防场景中,这个函数是接入本地/私有模型的标准姿势。参考示例 examples/cai/basic_usage.py:
from openai import AsyncOpenAI from cai.sdk.agents import Runner, Agent, OpenAIChatCompletionsModel import os ctf_agent = Agent( name="CTF agent", description="Agent focused on conquering security challenges", instructions="You are a Cybersecurity expert Leader facing a CTF", tools=[execute_cli_command], model=OpenAIChatCompletionsModel( model=os.getenv("CAI_MODEL", "qwen2.5:14b"), openai_client=AsyncOpenAI(), ), )2.3 set_default_openai_api:切换 Responses 与 Chat Completions
from cai.sdk.agents import set_default_openai_api set_default_openai_api("chat_completions")签名:set_default_openai_api(api: Literal["chat_completions", "responses"]) -> None
SDK默认使用 OpenAI Responses API,本函数可将全局默认切换为 Chat Completions API。底层通过 _openai_shared.py 的set_use_responses_by_default()维护布尔状态_use_responses_by_default(初始为True)。该状态在 openai_provider.py 的get_model()中消费:
return ( OpenAIResponsesModel(model=model_name, openai_client=client) if self._use_responses else OpenAIChatCompletionsModel(model=model_name, openai_client=client) )也就是说,set_default_openai_api("chat_completions")会让所有没有显式指定use_responses的OpenAIProvider自动选用OpenAIChatCompletionsModel。这在对接尚未支持 Responses API 的第三方或本地模型服务时几乎是必需的——官方示例 examples/model_providers/custom_example_global.py 正是这么做的。
三、Tracing 追踪控制:Key、开关与处理器替换
CAI SDK 内置 Tracing 系统:一次 Agent 运行的 LLM 生成、工具调用、handoff、guardrail 以及自定义事件都会被记录为 Trace / Span,默认批量上报到 OpenAI 后端(见 docs/tracing.md)。本模块提供三个全局控制函数。
3.1 set_tracing_export_api_key:单独设置追踪上报 Key
from cai.sdk.agents import set_tracing_export_api_key set_tracing_export_api_key("sk-...")签名:set_tracing_export_api_key(api_key: str) -> None
当 LLM 请求与 Tracing 使用不同 Key 时(例如请求走本地服务、上报走 OpenAI 平台),用本函数单独指定上传 Key。实现直接调用default_exporter().set_api_key(api_key)(tracing/init.py),作用于全局共享的 BackendSpanExporter。该 exporter 的api_key是cached_property,读取顺序为:显式设置的 Key →OPENAI_API_KEY环境变量;若最终为空,则跳过导出并打 warning(processors.py)。同时它也支持OPENAI_ORG_ID、OPENAI_PROJECT_ID环境变量。
3.2 set_tracing_disabled:全局关闭追踪
from cai.sdk.agents import set_tracing_disabled set_tracing_disabled(True)签名:set_tracing_disabled(disabled: bool) -> None
Tracing 默认开启。三种关闭方式:
- 本函数全局关闭:
set_tracing_disabled(True); - 环境变量
OPENAI_AGENTS_DISABLE_TRACING=1(在 setup.py 初始化TraceProvider时读取,等价于"true"/"1"); - 单次运行关闭:给
Runner.run(..., RunConfig(tracing_disabled=True))。
关闭后,GLOBAL_TRACE_PROVIDER.create_trace()/create_span()会直接返回NoOpTrace/NoOpSpan,几乎零开销(setup.py)。CAI 的实战示例在入口处显式关闭,避免本地开发时上报无关数据(见 examples/cai/basic_usage.py)。
3.3 set_trace_processors:替换默认追踪处理器
from cai.sdk.agents import set_trace_processors set_trace_processors([my_processor])签名:set_trace_processors(processors: list[TracingProcessor]) -> None
默认架构是:全局TraceProvider→BatchTraceProcessor(后台线程 + 线程安全队列,批量导出)→BackendSpanExporter(指数退避 + 抖动重试,POST 到https://api.openai.com/v1/traces/ingest)。模块初始化时通过add_trace_processor(default_processor())注册默认处理器,并用atexit注册优雅关闭(tracing/init.py)。
set_trace_processors()会整体替换处理器列表(不同于add_trace_processor()的追加语义),适合把 Trace 导出到自建后端或完全接管。底层由SynchronousMultiTracingProcessor的set_processors()在锁保护下替换处理器元组(setup.py),后续每个 trace/span 事件都会按注册顺序转发给列表中的处理器。若替换列表不含默认处理器,Trace 将不再上报 OpenAI 后端(docs/tracing.md)。
BatchTraceProcessor的关键可调参数(processors.py):
| 参数 | 默认值 | 说明 |
|---|---|---|
max_queue_size | 8192 | 内存队列上限,满则丢弃并告警 |
max_batch_size | 128 | 单批最大导出条数 |
schedule_delay | 5.0 | 定时导出间隔(秒) |
export_trigger_ratio | 0.7 | 队列达到上限 70% 时立即触发导出 |
四、enable_verbose_stdout_logging:开启调试日志
from cai.sdk.agents import enable_verbose_stdout_logging enable_verbose_stdout_logging()签名:enable_verbose_stdout_logging() -> None
SDK 的日志器默认没有 handler,因此只有 warning/error 会输出,其余级别被抑制。本函数将openai.agents日志器级别设为DEBUG并挂一个输出到sys.stdout的StreamHandler(src/cai/sdk/agents/init.py),适合排查 Agent 运行、Tracing 导出等内部流程问题。
更精细的自定义方式(docs/config.md):
import logging logger = logging.getLogger("openai.agents") # 或 openai.agents.tracing logger.setLevel(logging.DEBUG) # DEBUG / INFO / WARNING ... logger.addHandler(logging.StreamHandler())注意敏感数据:日志可能包含 LLM 输入输出与工具调用数据,可用以下环境变量关闭:
export OPENAI_AGENTS_DONT_LOG_MODEL_DATA=1 # 不记录 LLM 输入输出 export OPENAI_AGENTS_DONT_LOG_TOOL_DATA=1 # 不记录工具输入输出五、组合实战:一条龙初始化本地模型服务
把上述函数组合起来,即可在几行代码内完成"接入任意 OpenAI 兼容服务"的全局初始化。参考 examples/model_providers/custom_example_global.py 与 examples/model_providers/custom_example_provider.py:
import os import asyncio from openai import AsyncOpenAI from cai.sdk.agents import ( Agent, Runner, function_tool, set_default_openai_client, set_default_openai_api, set_tracing_disabled, ) BASE_URL = os.getenv("EXAMPLE_BASE_URL") # 例如本地网关地址 API_KEY = os.getenv("EXAMPLE_API_KEY") MODEL_NAME = os.getenv("EXAMPLE_MODEL_NAME") # 例如 qwen2.5:14b client = AsyncOpenAI(base_url=BASE_URL, api_key=API_KEY) set_default_openai_client(client=client, use_for_tracing=False) # 客户端只用于 LLM 请求 set_default_openai_api("chat_completions") # 多数本地服务不支持 Responses API set_tracing_disabled(disabled=True) # 无 OpenAI 平台 Key 时关闭上报 @function_tool def get_weather(city: str): return f"The weather in {city} is sunny." async def main(): agent = Agent( name="Assistant", instructions="You only respond in haikus.", model=MODEL_NAME, # 未显式传 Model 对象,走全局默认 provider tools=[get_weather], ) result = await Runner.run(agent, "What's the weather in Tokyo?") print(result.final_output) asyncio.run(main())关键点在于:Agent未显式指定model/provider时,Runner会通过全局OpenAIProvider解析模型名(默认模型gpt-4o,见 openai_provider.py),而该 provider 会读取上述三个全局配置——这正是"一次配置、全局生效"的机制来源。
六、配置优先级与使用建议
综合源码调用链,配置优先级总结如下:
- API Key:
OpenAIProvider(api_key=...)显式参数 >set_default_openai_key()全局默认 >OPENAI_API_KEY环境变量; - 客户端:
OpenAIProvider(openai_client=...)显式参数 >set_default_openai_client()全局默认 > SDK 自动创建; - API 协议:
OpenAIProvider(use_responses=...)显式参数 >set_default_openai_api()全局默认 > 默认使用 Responses API; - Tracing Key:
set_tracing_export_api_key()>set_default_openai_key(use_for_tracing=True)间接设置 >OPENAI_API_KEY; - Tracing 开关:
set_tracing_disabled()/OPENAI_AGENTS_DISABLE_TRACING全局控制,RunConfig.tracing_disabled单次控制。
实战建议:
- 连 OpenAI 官方服务:设置
OPENAI_API_KEY环境变量即可,无需任何代码配置; - 连兼容网关/本地模型:
set_default_openai_client+set_default_openai_api("chat_completions"),并视需求用set_tracing_disabled(True)关闭上报; - 自建可观测后端:实现
TracingProcessor后用set_trace_processors替换默认处理器; - 问题排查:先
enable_verbose_stdout_logging()看 DEBUG 日志,再决定是否需要关闭敏感数据日志。
七、相关资源
- 模块入口与全部导出符号:src/cai/sdk/agents/init.py
- 配置函数实现:src/cai/sdk/agents/_config.py、src/cai/sdk/agents/models/_openai_shared.py
- Tracing 实现:src/cai/sdk/agents/tracing/init.py、src/cai/sdk/agents/tracing/setup.py、src/cai/sdk/agents/tracing/processors.py
- 官方指南:docs/config.md、docs/tracing.md、docs/models.md
- 完整示例:examples/model_providers/custom_example_global.py、examples/cai/basic_usage.py
- 相关测试:tests/others/test_config.py、tests/conftest.py
【免费下载链接】caiCybersecurity AI (CAI), the framework for AI Security项目地址: https://gitcode.com/GitHub_Trending/cai3/cai
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考