codex 或 piagent。切换前应检查工具、模型配置和回调的兼容性
以下示例均需先完成模型配置。火山引擎与 BytePlus 分别使用对应平台的模型端点和 API Key
默认运行时
不设置runtime 时等同于 runtime="adk",适用于标准模型调用、结构化输出和工具协作
main.py
python main.py 可看到最终文本回复。需要处理事件和流式输出时使用 Runner.run_async
同步工具并行执行
默认 ADK 运行时中的同步函数可能阻塞其他异步任务。设置tool_thread_pool_config 后,同步工具可在线程池执行;当模型同一轮发出多个调用时,可并行处理
parallel_tools.py
python parallel_tools.py 可获得两个商品的库存。示例展示配置方式,模型是否同一轮发起多个调用由模型决定;线程池不会主动拆分任务。工具若共享可变数据或连接,需保证并发访问安全
RunConfig.tool_thread_pool_config 优先于 Agent 上的配置。该设置只影响 ADK 同步工具,不控制 codex 或 piagent 的执行机制。并行 run_code 的会话隔离及 VEADK_RUN_CODE_ISOLATE_PARALLEL_CALLS 见代码沙箱
切换执行后端
使用 Codex 运行时
安装包含 SDK 与 CLI 二进制的可选依赖组:model_name、model_api_base 和 model_api_key 配置。默认采用隔离工作区、workspace_write、关闭网络和拒绝提权;以下示例显式保留这些设置
codex_runtime.py
python codex_runtime.py。函数工具与 MCP 工具可通过 Agent.tools 注册,本地 ADK SkillToolset 中的技能可交给运行时使用;旧 skills_mode 的限制见下方兼容性表
Codex 安全配置
Agent.codex_runtime_config 接受 CodexRuntimeConfig 或同字段字典
VeADK 使用自定义权限配置实现 Session 隔离:
workspace_write 和 read_only 下,沙箱命令运行在 VeADK 生成的权限配置下,以只读访问为基础,拒绝访问临时目录和非共享的工作区根目录,只放行当前 Session 的工作目录和技能。一个 Session 的命令无法读写其他 Session 的工作区、rollout 和配置。主机上的其他文件(例如应用配置、本地 SQLite 会话数据库)仍然可读;需要在容器或操作系统用户层面隔离租户
以下环境变量优先于构造配置:
Codex 进程复用与并发
direct 传输且 thread_mode="resume" 时,无工具回合与暴露稳定 ADK/MCP 工具的回合默认复用进程。设置 mcp_process_reuse=False 或 VEADK_CODEX_MCP_PROCESS_REUSE=0 关闭 MCP 进程复用,无工具回合仍可复用。每轮重新绑定执行器、回调、工作目录和工具预算;执行前校验 SDK 确认的 thread/turn ID,旧轮次、缺失或不一致的身份及进程内重复的请求 ID 均被拒绝。空闲进程不接受工具执行。仅在同一存储、Session、thread,且模型、权限、skills、instruction、工具声明未变,存储中的 thread 身份和版本仍匹配时复用。错误、中断、保存失败或请求生命周期无法确定时关闭进程。VEADK_CODEX_PROCESS_POOL_SIZE=0 保持每轮新起进程。
复用避免在正常 warm 路径反复注入 skills 和环境上下文;冷恢复时仍保留必要上下文。已有的空工作目录不再被提示为重置,新建或重建的目录仍会提示。
常驻进程在空闲超时后自动释放。如需提前释放:
await veadk.runtime.codex.release_codex_session(app_name, user_id, session_id) 关闭某个 Session 的常驻进程(删除 Session 时调用);await veadk.runtime.codex.shutdown_codex_runtime() 关闭全部常驻进程以及 MCP bridge 和 shim,AgentKit 应用关闭时自动调用。VeADK 进程被强杀时其 Codex 子进程随之退出;同一主机上后续 VeADK 进程只在能证明 owner 已退出时清理带锁的工作区和目录
并行与批量工具场景
当 Codex 在同一次模型响应里生成多个独立异步函数调用时,现有链路即可并行执行。应用 instruction 和简洁的工具描述应明确哪些查询独立;有依赖的读取和写入仍按业务顺序执行。应用可以提供批量工具,对每个查询项返回结果或明确错误,并逐项鉴权:ADK 工具在宿主进程执行,Codex 沙箱不能替代业务权限。一个批量请求计作一次 SDK 工具调用,应用须另外限制业务查询数量。 仓库的scripts/benchmark_codex_tools.py 提供 single、parallel、serial、batch 示例与基准。其 bounded_batch_lookup 限制批量准入、设置逐项超时、保留取消行为并报告部分失败,不会自动合并任意已注册工具。
CODEX_RUN_SMOKE=1 uv run --extra dev pytest tests/runtime/codex/test_codex_tool_workloads.py -m codex_smoke -p no:xdist -rs。
模型传输模式
model_transport 决定 Codex 如何访问模型和执行工具:
auto 模式下,火山引擎方舟(*.volces.com)、BytePlus ModelArk(*.bytepluses.com)和 api.openai.com 的端点使用 direct,其他端点使用 shim
线程恢复
thread_mode="resume" 时,每个会话保持一个 Codex 线程。线程的 rollout 随会话一起存储(使用数据库会话存储时保存在数据库中),后续调用恢复该线程,Codex 保留自身完整历史而无需重放对话。ephemeral 模式每次调用创建新的临时线程
线程恢复仅在
direct 传输模式下生效。shim 模式始终使用临时线程,因为适配层执行的工具不会进入 Codex 的历史记录。线程恢复依赖会话存储的持久性;使用内存会话存储时,线程不会在进程重启后保留运行时转向
Runner.steer(session_id, text) 在当前正在运行的轮次中插入一条附加指令,无需开始新的轮次。智能体在执行过程中调整方向而不丢失已有进展
steer.py
steer 返回 True 表示指令已送达正在运行的轮次,False 表示当前没有正在运行的轮次或运行时不支持转向。仅在 direct 传输模式下支持,且轮次必须在当前进程内运行
Codex 可观测性
运行时将生命周期通知、函数和 MCP 工具调用转换为 ADK 事件,可供会话、链路和前端消费。运行日志中的invocation_id、call_id、tool、status 与 duration_ms 用于关联调用;token 用量通过 codex_event_type=token_usage 事件提供
运行时日志不等同于每次模型调用的完整链路。事件、会话或自行配置的导出器可能包含任务与工具内容,接入日志系统时应控制访问和保留范围
配置临时错误重试
使用 PiAgent
piagent_runtime.py
python piagent_runtime.py。VeADK 依次查找 PIAGENT_BINARY、托管缓存;未找到时从 Pi Release 下载。下载只有在设置 PIAGENT_BINARY_SHA256 时才校验该摘要。离线与生产环境建议预先安装并指定可执行文件
使用 DeepSeek Harness 运行时
DeepSeek Harness 运行时将智能体内层循环交给 DeepSeek Harness SDK 执行。安装时通过 Python extra 获取二进制,运行时懒启动子进程,不依赖首次运行下载 安装包含 SDK 与匹配二进制的可选依赖组:veadk-python[dsh] 依赖 deepseek-harness-sdk,该 SDK 再依赖匹配版本的 deepseek-harness-runtime-bin。dsh 可执行文件随 wheel 安装,VeADK 不在运行时下载二进制。导入 VeADK 或构造 Agent 不会启动 DSH;第一次执行到运行时入口时 SDK 才拉起子进程
同一有效配置复用一个 SDK 对象和 DSH 子进程;同一 VeADK app/user/session/agent 映射到稳定的 DSH 会话标识。VeADK 会话历史作为短期记忆的事实来源,以结构化形式序列化进 prompt;DSH 会话标识保持稳定但不作为唯一记忆来源
ADK 函数工具与 MCP 工具在 DSH 运行前展开,通过生成的工具插件和带鉴权的本地回调服务执行。sub_agents 使用与其他外部运行时相同的注入式转交路径。ADK SkillToolset 与 legacy 技能会被物料化到隔离目录,注册为 DSH 原生技能插件。根会话的 DSH 流式输出映射为 ADK partial 事件,DSH 原生工具事件映射为 ADK 函数调用/响应事件
模型仍通过 model_name、model_api_base 和 model_api_key 配置。以下示例使用火山引擎方舟端点:
dsh_runtime.py
python dsh_runtime.py 可看到最终文本回复
provider 是面向用户的 provider 名称,默认 deepseek-official。openai、volcengine、volcengine-ark、ark、openai-compatible 和 third-party 均映射到当前 DSH 的 deepseek-official adapter;未知 provider 名称原样透传,供未来 DSH 原生 adapter 使用。base_url 和 api_key 未在配置中设置时,分别回退到 Agent.model_api_base 和 Agent.model_api_key
未配置 dsh_home 时,VeADK 生成进程隔离目录并显式传给 SDK,不会隐式使用 ~/.dsh。需要跨进程保留 DSH 会话时,显式配置 dsh_home
DSH 配置
Agent.deepseek_harness_runtime_config 接受 DeepSeekHarnessRuntimeConfig 或同字段字典
enable_skills_checklist 不会在 DSH 原生技能加载器内执行。DSH 子智能体会话的通知尚未投影为一等子会话事件。这两项与 codex、piagent 的差异见下方兼容性表运行时兼容性
以下是切换到codex、piagent 或 dsh 时需要检查的配置:
智能体转移
transfer_to_agent 允许模型将当前任务转交给智能体树中的其他智能体,由目标继续执行并输出结果。ADK、Codex、PiAgent 与 DSH 均支持转交
transfer.py
python transfer.py 后可得到公告文本。转交需要由 Runner 驱动,目标仍在同一次调用上下文中运行;它的 output_key 也会生效。需要固定顺序执行时,使用下节的顺序工作流
输出持久化
output_key 将最终回复保存到会话状态,ADK、Codex、PiAgent 和 DSH 均支持。它不是独立的磁盘持久化机制;跨进程保存取决于所选会话存储
pipeline.py
python pipeline.py。规划结果写入 plan,写作智能体通过 {plan} 读取,正文写入 draft。示例打印回复和两个状态值,以便检查传递结果
模型回调
回调可以使用同步或异步函数。ADK 按模型调用执行;外部运行时的前后回调围绕整轮执行,插件回调先于智能体回调。返回None 表示继续默认处理
修改请求不意味着外部运行时支持全部 ADK 配置,仍需遵循兼容性表。例如不能通过回调假定获得
output_schema 支持
model_callback.py
python model_callback.py:模型正常时输出回答,模型调用失败时返回预设文本。该回调不处理所有初始化、工具或业务错误
将 PDF 转为图片
pdf_to_images_before_model_callback 将输入中的 PDF 字节转为图片,适用于支持图片但不能直接读取 PDF 的模型。PDF 渲染依赖已包含在 VeADK 默认安装中
将可发送给模型服务的文件保存为当前目录的 example.pdf,选择支持图片输入的模型,然后运行以下脚本:
pdf_callback.py
2.0。需要调整时,从同一模块导入 make_pdf_to_images_callback,通过 max_pages 和 scale 创建回调。更多页面或更高比例会增加图片数量、内存占用和模型输入用量
按工具选择执行位置
RuntimeProvider 决定单个工具调用如何执行,通常用于保留 ADK 流程而把部分工具交给自有服务。DispatchRuntimeProvider 调用你提供的派发函数;LocalRuntimeProvider 执行原有工具。需要自定义完整策略时,继承 RuntimeProvider 并实现 execute(tool_call)
使用示例
以下示例使用本地演示适配函数模拟服务结果,可验证派发后的库存为12,原始工具返回的 0 不会再次执行。它不连接实际远端服务
dispatch.py
dispatch_task 替换为已配置认证与超时的客户端调用,用 tool_call.id 关联请求。派发函数可以同步或异步,并应返回可作为工具结果的数据。服务接口由应用自行约定
也可将 runtime_provider.before_tool_callback 传给 Agent.before_tool_callback;不要同时注册两个入口,否则会重复拦截。MCP 工具仍使用自身连接执行,不受派发范围影响
DispatchRuntimeProvider 参数
ToolCall 字段
请求处理
run_processor 包裹 Runner.run 的整轮事件流,用于鉴权、计时、清理或事件转换。优先级依次为:本次 Runner.run(run_processor=...)、Runner 构造配置、根智能体配置,最后是默认的透传处理器。直接调用 run_async 不会自动使用这一包装
身份认证可使用 veadk.integrations.ve_identity.AuthRequestProcessor,并传给 Agent(run_processor=...);所需身份配置见入站认证
自定义处理器
继承BaseRunProcessor 并实现 process_run(runner, message, **kwargs)。下面的处理器转发事件,并在正常结束、失败或取消时记录耗时和关闭事件流
run_processor.py
python run_processor.py 可看到回复及执行耗时。处理器若包含重试,应先确认任务是否已产生外部副作用,避免重复执行