背景
doctoragent/model/agent.py 里的 _estimate_tokens 用 tiktoken.get_encoding("cl100k_base") 估算 token 数,失败才回退 len(text) // 4。
现象
跑 tests/test_agent_react_loop.py::TestParallelToolDispatch::test_independent_tools_run_in_parallel 时,两个各 0.15s 的工具竟然耗了 25s。插桩后定位:25s 全部消耗在 _dispatch_tool_calls 内部、且发生在两次工具执行(各 0.15s)之外——也就是估算/记录阶段,不是工具本身慢。
根因
tiktoken 首次调用 get_encoding 会从 OpenAI 的 CDN 下载 BPE 编码文件。在离线或受限网络(院内隔离网、CI 受限出口)下,下载每次都要重试 ~5s 才失败;更要命的是失败没有被缓存——get_encoding 每次调用都重新尝试联网下载。完整测试集里 token 估算被高频触发,一次次重试累加成 25s 的硬阻塞。
影响(这是真 bug,不是测试问题)
建议 / 已做的修复
- 已本地把 tiktoken 的可用性(成功 or 失败)缓存到进程生命周期:加
_TIKTOKEN_CACHE = {"enc": None, "failed": False},get_encoding 只在 try 内解析并缓存一次;一旦失败就打标记,之后所有调用直接走 len // 4 兜底,不再碰网络。修复后并发测试从 25s 回到亚秒级。
- 进一步建议:把 tiktoken 的 BPE 文件随包内置(离线优先),彻底去掉下载依赖;或者在配置里允许显式指定编码缓存路径。
背景
doctoragent/model/agent.py里的_estimate_tokens用tiktoken.get_encoding("cl100k_base")估算 token 数,失败才回退len(text) // 4。现象
跑
tests/test_agent_react_loop.py::TestParallelToolDispatch::test_independent_tools_run_in_parallel时,两个各 0.15s 的工具竟然耗了 25s。插桩后定位:25s 全部消耗在_dispatch_tool_calls内部、且发生在两次工具执行(各 0.15s)之外——也就是估算/记录阶段,不是工具本身慢。根因
tiktoken 首次调用
get_encoding会从 OpenAI 的 CDN 下载 BPE 编码文件。在离线或受限网络(院内隔离网、CI 受限出口)下,下载每次都要重试 ~5s 才失败;更要命的是失败没有被缓存——get_encoding每次调用都重新尝试联网下载。完整测试集里 token 估算被高频触发,一次次重试累加成 25s 的硬阻塞。影响(这是真 bug,不是测试问题)
建议 / 已做的修复
_TIKTOKEN_CACHE = {"enc": None, "failed": False},get_encoding只在try内解析并缓存一次;一旦失败就打标记,之后所有调用直接走len // 4兜底,不再碰网络。修复后并发测试从 25s 回到亚秒级。