
openai-agents-python 沙箱 Token 截断工具深度解析TruncationPolicy 与截断算法实战指南【免费下载链接】openai-agents-pythonA lightweight, powerful framework for multi-agent workflows项目地址: https://gitcode.com/GitHub_Trending/op/openai-agents-pythonagents.sandbox.util.token_truncation是 openai-agents-python 沙箱子系统中的核心文本截断模块负责在 Agent 工作流中把超长输出Shell 命令结果、PTY 会话回显、记忆摘要、rollout 日志安全地裁剪到模型上下文窗口内。本文以 API 参考文档 为骨架结合源码实现与单元测试系统讲解TruncationPolicy配置模型、字节/Token 双模式截断算法、UTF-8 安全切割原理及其在仓库各模块中的真实调用场景读完即可掌握该工具的全部公开 API 并理解其内部机制。模块定位沙箱输出安全的最后一道防线在沙箱执行流程中Agent 运行 Shell 命令、读写记忆文件、回放 PTY 终端输出时可能产生远超模型上下文窗口的超长文本。如果直接把原始文本塞进提示词轻则浪费 Token 配额重则触发上下文溢出导致请求失败。token_truncation模块就是为了解决这个问题而设计的轻量级工具集它不依赖任何分词器仅凭约 1 Token ≈ 4 字节的经验换算即可完成近似预算控制。从源码结构看该模块被沙箱子系统多处复用src/agents/sandbox/capabilities/tools/shell_tool.pyShell 工具输出截断src/agents/sandbox/session/pty_types.pyPTY 输出截断包装src/agents/sandbox/session/pty_output.pyPTY 输出流截断落地src/agents/sandbox/capabilities/memory.py记忆摘要读取截断src/agents/sandbox/memory/phase_one.pyPhase 1 记忆生成的 rollout 截断模块的公开导出列表__all__在 token_truncation.py 中定义并在 src/agents/sandbox/util/init.py 中向上层模块统一再导出方便沙箱各子包以from ..util import TruncationPolicy, truncate_text的方式引用。TruncationPolicy两种模式统一预算配置所有截断入口都接受一个TruncationPolicy实例作为策略描述。它定义在 token_truncation.py是一个不可变frozenTrue的 dataclass包含两个字段字段类型说明modeTruncationModebytes/tokens预算计量单位limitint预算上限数值推荐通过两个类方法构造策略它们会把负数限制钳制为 0避免非法配置from agents.sandbox.util.token_truncation import TruncationPolicy # 以字节为单位的截断策略 byte_policy TruncationPolicy.bytes(4096) # 以 Token 为单位的截断策略 token_policy TruncationPolicy.tokens(15_000)TruncationPolicy还提供两个预算换算方法统一了字节预算与Token 预算的互转口径token_budget()若模式为bytes按 4 字节/Token 把字节上限换算为 Token 上限若模式为tokens直接返回limitbyte_budget()反向换算tokens模式按 4 字节/Token 放大为字节预算bytes模式直接返回limit。这样无论上层以哪种单位声明限制截断算法内部都可以统一按字节执行精确切割见下文字节级切割。近似换算模型APPROX_BYTES_PER_TOKEN 4整个模块的 Token 估算都建立在一个常数上APPROX_BYTES_PER_TOKEN 4围绕它提供了三个公开换算函数定义于 token_truncation.pyapprox_token_count(text)估算一段文本的 Token 数实现为(字节数 3) // 4即向上取整的字节数除以 4approx_bytes_for_tokens(tokens)Token 数乘以 4 得到字节预算负数钳制为 0approx_tokens_from_byte_count(byte_count)从字节数反推 Token 数同样向上取整 0时返回 0。测试 tests/sandbox/test_token_truncation.py 验证了这些换算行为例如approx_token_count(abcde) 25 字节向上取整为 2 个 Token。需要强调的是这是近似估算而非真实分词器结果对于中文等多字节字符场景会存在偏差但足以满足防止上下文溢出的工程目标。截断函数族从简单裁剪到带元数据输出模块提供了四个面向不同场景的公开截断入口按功能递进1.truncate_text(content, policy)基础截断最简单的入口按策略模式分派def truncate_text(content: str, policy: TruncationPolicy) - str: if policy.mode bytes: return truncate_with_byte_estimate(content, policy) truncated, _ truncate_with_token_budget(content, policy) return truncatedbytes模式走字节估算路径tokens模式走 Token 预算路径并丢弃返回的原始计数。若内容本身未超预算则原样返回truncate_with_token_budget的提前返回逻辑见 token_truncation.py。2.formatted_truncate_text(content, policy)带行数前缀的格式化截断在基础截断之上当发生截断时会在结果前附加原始总行数元数据def formatted_truncate_text(content: str, policy: TruncationPolicy) - str: if _byte_len(content) policy.byte_budget(): return content total_lines len(content.splitlines()) if policy.mode tokens: prefix fTotal output lines: {total_lines}\n\n return _truncate_token_output(content, policy, prefixprefix) result truncate_text(content, policy) return fTotal output lines: {total_lines}\n\n{result}行为要点内容未超预算时原样返回不附加前缀一旦触发截断输出以Total output lines: N开头让模型知道原始输出共有多少行避免把截断结果误认为完整内容。测试 tests/sandbox/test_token_truncation.py 验证了行数前缀与chars truncated标记的共存。3.formatted_truncate_text_with_token_count(text, max_output_tokens)带原始 Token 数回传的版本这是 Shell 工具与 PTY 输出实际使用的入口返回(截断后文本, 原始Token数)二元组def formatted_truncate_text_with_token_count( content: str, max_output_tokens: int | None ) - tuple[str, int | None]: if max_output_tokens is None: return content, None policy TruncationPolicy.tokens(max_output_tokens) if _byte_len(content) policy.byte_budget(): return content, None total_lines len(content.splitlines()) prefix fTotal output lines: {total_lines}\n\n truncated _truncate_token_output(content, policy, prefixprefix) return truncated, approx_token_count(content)设计上三个细节值得注意max_output_tokensNone表示不限制原样返回且计数为None未超预算时返回(content, None)即只有真正发生截断时才报告原始 Token 数预算为 0 时返回空字符串测试 tests/sandbox/test_token_truncation.py 验证并仍回传原始估算 Token 数。4.truncate_with_token_budget(s, policy)可获取原始计数的低层接口返回(截断后文本, 原始Token数)与第 3 个函数的差异在于它直接接受策略对象而非max_output_tokens且不添加行数前缀适合需要自行控制前缀格式的调用方。空字符串提前返回(, None)。截断算法原理保留头尾 标记计入预算截断不是简单地从尾部切掉而是保留开头和结尾、只移除中间这样模型既能读到命令输出的开头又能看到结尾的错误码或收尾信息。核心流程在_truncate_token_outputtoken_truncation.py先按byte_budget()得到总字节预算预算为 0 时直接返回空串用split_budget把内容预算对半分给头部和尾部split_budget(5) (2, 3)即不均等时余数给尾部调用split_string做 UTF-8 安全的字节级切割返回(被移除字符数, 头部文本, 尾部文本)用format_truncation_marker生成截断标记并统计实际被移除的字节/字符数关键点标记文本本身也计入字节预算。如果前缀加标记超过预算会先丢弃前缀若仍放不下则退化为只保留标记本身_truncate_utf8(marker, max_bytes)。这保证了截断结果严格不超过预算测试 tests/sandbox/test_token_truncation.py 断言approx_token_count(result) 32验证了这一点。UTF-8 安全的split_stringsplit_stringtoken_truncation.py是整个模块在字节模式下保持文本合法性的关键实现。它逐字符遍历字符串按字符的 UTF-8 编码字节长度累积偏移量只在字符边界处切分避免把多字节字符如中文あ、emoji拦腰截断成无法解码的字节序列。测试 tests/sandbox/test_token_truncation.py 用split_string(aあbいc, 2, 4)验证了结果为头部a、尾部いc且正确报告移除了 2 个字符。截断标记格式format_truncation_markertoken_truncation.py按模式生成不同标记tokens模式…N tokens truncated…bytes模式…N chars truncated…标记中的 N 是实际被移除的量字节模式统计被移除字符数Token 模式按approx_tokens_from_byte_count把被移除字节换算为 Token 数removed_units_for_sourcetoken_truncation.py。最终由assemble_truncated_output拼装为头部 标记 尾部的形式。仓库实战场景五处真实调用Shell 工具输出截断src/agents/sandbox/capabilities/tools/shell_tool.py 中_truncate_output直接委托给formatted_truncate_text_with_token_count并在_format_response同文件 L33-L52中将回传的original_token_count拼进响应头例如Original token count: 12345让模型对原始输出有多大有明确感知。PTY 输出截断PTY 会话侧pty_types.py 的truncate_text_by_tokens是formatted_truncate_text_with_token_count的薄包装随后由 pty_output.py 在真实输出路径中调用并重新编码为 UTF-8 字节流返回。记忆摘要读取截断src/agents/sandbox/capabilities/memory.py 定义_MEMORY_SUMMARY_MAX_TOKENS 15_000在读取memory_summary.md时用TruncationPolicy.tokens(15_000)截断后再渲染进记忆读取提示词同文件 L69-L72防止巨型记忆摘要挤占上下文。Phase 1 记忆生成 rollout 截断src/agents/sandbox/memory/phase_one.py 定义_PHASE_ONE_ROLLOUT_TOKEN_LIMIT 150_000将累计的 JSONL rollout 内容截断后送入提取提示词且一旦发生截断会在结果前插入显式的省略声明同文件 L20-L26警告模型当前渲染的 rollout 是不完整的视图。这与 docs/sandbox/memory.md 描述的行为一致如果对话过长将截断以适配上下文窗口保留开头和结尾。测试验证行为契约一览tests/sandbox/test_token_truncation.py 是模块行为的权威契约覆盖了以下关键不变量负数 limit 被钳制为 0且两个模式的预算换算结果都为 0L20-L30未超预算的内容原样返回不附加任何元数据L32-L34截断后总 Token 数严格不超过预算包括标记与行数前缀在内L43-L50空内容与预算为 0 的边界行为L83-L101UTF-8 多字节字符切割边界保持合法L110-L115换算辅助函数的数值正确性L122-L133。这些测试在仓库中以tests/sandbox/目录形式组织可直接用pytest tests/sandbox/test_token_truncation.py在本地复现。小结agents.sandbox.util.token_truncation以4 字节 ≈ 1 Token的近似模型为根基通过TruncationPolicy统一了字节与 Token 两种预算口径用保留头尾 标记计入预算 UTF-8 安全切割的算法保证了截断结果既合法又严格受限同时通过Total output lines前缀与Original token count回传让模型对截断失真保持感知。无论是为 Shell 工具、PTY 输出设置max_output_tokens还是在记忆生成管线中控制 rollout 与摘要体积该模块都是 openai-agents-python 沙箱中控制上下文成本与稳定性的基础设施。【免费下载链接】openai-agents-pythonA lightweight, powerful framework for multi-agent workflows项目地址: https://gitcode.com/GitHub_Trending/op/openai-agents-python创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考