结果缓存¶
ToolUniverse 配备了双层结果缓存(内存 + SQLite),因此可以在多次运行中重复使用耗时的工具调用,而无需额外设置。本页面将解释缓存内容、如何配置缓存,以及如何检查或清除缓存条目。
Why Use Caching?¶
The Problem: Scientific API calls can be slow and rate-limited:
PubMed searches: 0.3-2 seconds per query
UniProt lookups: 0.5-1 second per protein
ChEMBL queries: 1-3 seconds per compound
Rate limits: 3-10 requests/second (even with API keys)
The Solution: Cache results to avoid redundant API calls.
Benefits:
Speed: Cached queries return in <1ms (vs 0.3-3 seconds)
Rate limit protection: Avoid hitting API limits in batch workflows
Reproducibility: Same query always returns same result (until source data changes)
Cost savings: Fewer API calls = lower costs for paid services
Offline work: Previously cached data available without internet
Example Impact: A 1000-protein batch analysis:
Without cache: 1000 API calls × 0.5s = 8.3 minutes
With cache (90% hit rate): 100 API calls × 0.5s + 900 cached × 0.001s = 51 seconds
10x faster with caching!
概述¶
内存中的LRU – 单次会话期间重复调用的最快路径。
SQLite 持久化 – 默认将结果存储在
~/.tooluniverse/cache.sqlite中,以确保结果在重启后仍然保留(路径可通过环境变量进行配置)。每个工具的指纹 – 每个工具会自动生成其源代码和参数结构的指纹。当其中任一发生变化时,缓存键也会随之改变,旧的条目将被忽略。
快速开始¶
缓存功能默认启用。调用工具时,只需传递 use_cache=True 参数即可重用结果:
from tooluniverse import ToolUniverse
tu = ToolUniverse()
result = tu.run({
"name": "UniProt_get_entry_by_accession",
"arguments": {"accession": "P05067"},
}, use_cache=True)
# Second call reuses the cached payload
cached = tu.run({
"name": "UniProt_get_entry_by_accession",
"arguments": {"accession": "P05067"},
}, use_cache=True)
对于模型训练类型的工作负载,您可以传递调用列表给``tu.run``并启用并行工作线程。每次调用仍会在访问网络之前检查缓存:
import json
batch = [
{"name": "UniProt_get_entry_by_accession", "arguments": {"accession": acc}}
for acc in accession_list
]
messages = tu.run(batch, use_cache=True, max_workers=16)
# Extract tool payloads (assistant metadata is at messages[0])
payloads = [json.loads(msg["content"])["content"] for msg in messages[1:]]
批处理执行提示¶
批处理运行器会自动执行多项优化:
调用去重 – 相同的``name``/``arguments``对仅执行一次,并将结果分发给每个请求者。启用``use_cache=True``时,结果也会被存储,以便后续批次能够立即返回结果。
每个工具的并发性 – 每个工具可以在其 JSON/定义中声明一个
batch_max_concurrency限制。在批处理运行期间,调度程序会强制执行该限制,以确保缓慢或受速率限制的 API 不会占用所有工作线程。可配置容量 – 如果预计缓存条目数量达到数百万,可以增加
TOOLUNIVERSE_CACHE_MEMORY_SIZE的值。例如,将其设置为5000000可在 RAM 中大约保留五百万个结果(请监控 RSS 使用情况,并根据负载大小进行调整)。
配置¶
在创建 ToolUniverse 实例之前,请使用环境变量调整缓存行为:
参见
Environment Variables Reference for complete environment variable reference including logging, LLM, and other configuration options.
示例配置:
import os
from tooluniverse import ToolUniverse
os.environ["TOOLUNIVERSE_CACHE_PATH"] = "/tmp/tooluniverse/cache.sqlite"
os.environ["TOOLUNIVERSE_CACHE_MEMORY_SIZE"] = "1024"
os.environ["TOOLUNIVERSE_CACHE_DEFAULT_TTL"] = "3600" # expire after 1 hour
tu = ToolUniverse()
检查和管理缓存¶
ToolUniverse 提供辅助工具以理解和控制缓存:
stats = tu.get_cache_stats()
print(stats)
# Export persisted entries (returns an iterator of dicts)
entries = list(tu.dump_cache())
# Clear all cached data (both layers)
tu.clear_cache()
版本控制与TTL¶
每个工具都继承了一个默认的指纹(get_cache_version),该指纹结合了工具的源代码和参数结构。您可以在自定义工具中重写此钩子,以实现更精细的控制(例如,添加一个手动的``STATIC_CACHE_VERSION``计数器)。工具还可以重写``get_cache_ttl``,以指定每个结果的过期时间。
异步持久化¶
SQLite 持久性仍默认启用,但现在写入操作在后台线程中进行,因此工具调用不会因磁盘 I/O 而被阻塞。您可以通过以下两种方式调整此行为:
在构造
ToolUniverse之前,将TOOLUNIVERSE_CACHE_ASYNC_PERSIST=false设置为 false,以回退到完全同步写入(当您需要结果立即写入磁盘时非常有用)。如果预计工作负载中写操作非常频繁,可以创建一个具有更大队列的自定义``ResultCacheManager``:
from tooluniverse import ToolUniverse from tooluniverse.cache.result_cache_manager import ResultCacheManager tu = ToolUniverse() tu.cache_manager.close() # replace the default manager tu.cache_manager = ResultCacheManager( memory_size=1_000_000, async_queue_size=50_000, )
使用``tu.cache_manager.flush()``,如果您需要等待未完成的写入操作(例如,在关闭工作线程之前)。现在``tu.get_cache_stats()``会报告``pending_writes``,因此您可以在批处理任务期间监控队列深度。
最佳实践¶
对确定性或幂等操作(只读API调用、耗时计算等)使用缓存。
在结果对时间敏感时,请设置明确的TTL。
在长时间运行的服务中,如果需要重新开始,请调用
tu.clear_cache()。对于动手演示,请运行 ``examples/cache_usage_example.py``(基础演练)或 ``examples/cache_stress_test.py``(随机负载测试及统计摘要)。 .. code-block:: json
- 请提供需要翻译的具体文本内容,我将为您提供专业的中文翻译。
“name”: “慢速工具”, “type”: “慢速工具”, “batch_max_concurrency”: 2, “parameter”: {“type”: “object”, “properties”: {}}
请提供需要翻译的具体英文文本,我将为您进行翻译。