内容
# Traject
[](https://github.com/aarohim24/Traject/actions)
[](LICENSE)
[](https://www.python.org/)
**生产环境智能代理系统的高效成本可观测性和轨迹压缩工具。**
---
## 关于
多步骤智能代理在每次大型语言模型(LLM)调用时,都会重新传输其累计的全部上下文信息——工具结果、推理轨迹、先前的消息——这导致每次步骤的成本累积。在第10步,代理重新支付9步历史的费用。Traject拦截这些调用,在它们到达提供商之前压缩冗余部分,将请求路由到可以处理任务的最便宜模型,并发出结构化的OpenTelemetry跨度,以便团队可以准确地看到成本花费在哪里。
只需三行代码。现有的调用站点无需更改。
```python
traject.configure(export_to_stdout=True)
traject.patch(client, feature_tag="my_agent", shadow_mode=True)
```
**Traject与其他压缩工具的区别:**
- **验证过的数字。** 在49个真实的编码代理轨迹上进行基准测试:43–45%的聚合令牌减少,压缩评分器独立于事实保留检查。
- **企业级可观测性。** 按功能标签进行成本归因,通过Webhook警报进行预算强制执行,异常检测,多租户后端——不仅仅是压缩。
- **完全自主托管。** Python SDK + FastAPI后端 + Grafana仪表盘。您的数据永远不会离开您的基础设施。
- **可逆压缩(CCR)。** 丢弃的段存储在Redis中,可通过`traject_retrieve` MCP工具按需恢复——不会永久丢失信息。
**适用人群:** 构建和运行LLM代理或服务的工程团队,他们自行支付API账单。不适用于使用托管订阅(Copilot,Claude Team)的个人工程师——这些不暴露Traject减少的API支出。
---
## 目录
- [关于](#关于)
- [安装](#安装)
- [快速入门](#快速入门)
- [工作原理](#工作原理)
- [配置](#配置)
- [压缩策略](#压缩策略)
- [模型路由](#模型路由)
- [自主托管后端](#自主托管后端)
- [集成路径](#集成路径)
- [基准测试](#基准测试)
- [支持的提供商](#支持的提供商)
- [需求](#需求)
- [架构](#架构)
- [贡献](#贡献)
→ **完整文档索引:** [docs/INDEX.md](docs/INDEX.md)
---
## 安装
```bash
git clone https://github.com/aarohim24/Traject
cd Traject/sdk/python
pip install -e "."
```
可选的框架集成:
```bash
pip install -e ".[langchain]" # LangChain支持
pip install -e ".[autogen]" # AutoGen支持
pip install -e ".[ccr]" # 可逆压缩(Redis支持)
```
需要Python 3.11+。
---
## 快速入门
```python
# OpenAI — 检测现有的客户端
import openai
import traject
traject.configure(export_to_stdout=True)
client = openai.OpenAI()
traject.patch(client, feature_tag="my_agent", shadow_mode=True)
# 您现有的代理代码 — 不变
response = client.chat.completions.create(
model="gpt-4o-mini",
messages=[{"role": "user", "content": "Summarize this report."}]
)
```
```python
# Anthropic — 相同的模式
import anthropic
import traject
traject.configure(export_to_stdout=True)
client = anthropic.Anthropic()
traject.patch(client, feature_tag="support_bot", shadow_mode=True)
```
```python
# LangChain — 实时压缩,目标减少35%
import traject
from traject import CompressionStrategy
traject.configure(export_to_stdout=True)
traject.patch(
llm,
feature_tag="research_agent",
shadow_mode=False, # 实时压缩
strategy=CompressionStrategy.MODERATE, # 目标减少35%
)
```
`shadow_mode=True`(默认)静默运行压缩并记录可以节省的内容。设置`shadow_mode=False`在验证后。
---
## 工作原理
### 轨迹累积问题
在多步骤代理循环中,每次LLM调用都包含所有先前的上下文——系统提示、用户消息、工具调用及其结果、推理轨迹。在第10步,代理重新传输9个先前的回合。输入令牌构成代理推理成本的大部分,这种开销随着步骤数量的增加而扩大。
### 轨迹压缩
压缩管道在每次提供者调用之前运行:
1. **预处理(无损)** - 在任何有损决策之前,通过两个可逆传递缩小上下文:从助手回合中删除填充文本(对答、闲聊、介绍),将工具结果中的≥5个同质对象的JSON数组列化为紧凑的表格。两者都受到保护,以免产生更长的输出,包含代码块的内容将被跳过。
2. **解析** - 上下文窗口被分割为类型化的工件:`SYSTEM_PROMPT`、`USER_MESSAGE`、`TOOL_RESULT`、`REASONING_BLOCK`、`RAG_CHUNK`、`TOOL_CALL`、`FEW_SHOT_EXAMPLE`、`ASSISTANT_MESSAGE`。
3. **保护** - 系统提示和最后N个回合被标记为不可变。它们无论策略如何都不会被修改。
4. **软保护** - 每个剩余段都被嵌入(在进程中,`all-MiniLM-L6-v2`)并与接下来的5个段通过余弦相似度进行比较。两个独立的信号软保护一个段:(a)后面的回合*语义引用*它——这些保持逐字记录;(b)它仅*包含高信息内容*(错误、哈希、文件路径)。仅通过信号(b)保护的工具结果仍然有资格进行命令感知总结(如下),它保留了确切的负载信息。
5. **评分** - 剩余段通过以下方式评分:时间(0.4权重)、与当前任务的语义相关性(0.4权重)和最近回合中的引用计数(0.2权重)。语义组件在调用范围内通过内容哈希和任务相似性桶进行缓存,避免重复段的冗余嵌入查找。
6. **压缩** - 按顺序应用:
- **无损重复数据删除** - 字节相同的工具结果重复出现(代理重新读取相同的文件/命令)被短引用替换;最后一个出现的内容保持不变,因此不会丢失信息。
- **命令感知总结** - 工具结果按生成它们的命令进行子类划分(`git diff`、`git log`、pytest、`ls`/`find`、构建输出),并由特定于领域的压缩器总结,该压缩器保留负载信息(失败的测试、错误类型、文件:行引用、差异标头),同时修剪大量内容。其他低评分段根据策略阈值进行总结或丢弃。膨胀防护确保仅当严格更小时才替换。
- **CCR(可选)** - 配置了`CCRStore`,将要丢弃的段存储在Redis中,并替换为`<<ccr:HASH>>`存根。代理通过`traject_retrieve` MCP工具按需恢复完整内容——使压缩可逆。
7. **验证** - 断路器:如果系统提示或最近的回合在压缩输出中不存在,则中止压缩并返回原始上下文不变。
8. **发出** - OpenTelemetry跨度记录节省的令牌、压缩比率、应用的策略、缓存命中率、软保护计数和CCR存根计数。
### 影子模式
影子模式计算完整的压缩管道并记录可以节省的内容,但不会修改传递给提供者的上下文。它是默认的。在验证后启用实时压缩(`shadow_mode=False`)。
### OTel跨度属性
每个`traject.compression.complete`跨度都带有:
| 属性 | 类型 | 描述 |
|---|---|---|
| `tokens_saved` | int | 压缩消除的令牌 |
| `compression_ratio` | float | 消除的令牌分数,0–1 |
| `strategy` | str | `conservative`、`moderate`或`aggressive` |
| `shadow_mode` | bool | 是否返回原始消息 |
| `cache_hits` | int | 调用范围缓存的语义分数 |
| `cache_hit_rate` | float | 缓存命中分数,0–1 |
| `segments_soft_protected` | int | 提升到软保护层的段 |
| `segments_ccr_stubbed` | int | 存储在CCR中并替换为存根的段 |
`tokens_saved`和`compression_ratio`针对调用者发送的**原始输入令牌**进行测量——无损预处理节省(文本过滤、JSON列化)包含在报告的减少中,而不是通过缩小基线隐藏。
---
## 配置
```python
traject.configure(
export_to_stdout=True, # 将OTEL跨度打印到stdout
otlp_endpoint="http://...", # 将跨度发送到OTEL收集器
backend_url="http://...", # 发送到Traject后端
backend_api_key="...", # 后端API密钥
report_benchmarks=False, # 选择加入:提交到公共注册表
)
```
| 参数 | 类型 | 默认值 | 描述 |
|---|---|---|---|
| `export_to_stdout` | `bool` | `True` | 将OTEL跨度打印到stdout |
| `otlp_endpoint` | `str \| None` | `None` | OTEL收集器端点 |
| `backend_url` | `str \| None` | `None` | Traject后端URL |
| `backend_api_key` | `str \| None` | `None` | 后端API密钥 |
| `router` | `RuleRouter \| None` | `None` | 自适应模型路由器 |
| `report_benchmarks` | `bool` | `False` | 选择加入聚合遥测 |
---
## 压缩策略
| 策略 | 目标减少 | 用例 |
|---|---|---|
| `CONSERVATIVE` | 20% | 默认。新部署,未知工作负载。 |
| `MODERATE` | 35% | 验证后的工作负载,在影子模式审查后。 |
| `AGGRESSIVE` | 55% | 高容量、特征明确的工作负载。 |
```python
from traject import CompressionStrategy
traject.patch(client, strategy=CompressionStrategy.MODERATE)
```
---
## 模型路由
```python
from traject.router import RuleRouter
router = RuleRouter(provider="openai")
traject.configure(router=router)
```
任务按类型分类,并路由到可以处理它们的 cheapest 模型层。
| 任务类型 | 低复杂度 | 中等 | 高 |
|---|---|---|---|
| 总结、分类、提取 | gpt-4o-mini | gpt-4o-mini | gpt-4o |
| 问答、代码审查 | gpt-4o-mini | gpt-4o | gpt-4o |
| 代码生成、推理 | gpt-4o-mini | gpt-4o | gpt-4o |
支持自定义路由表和A/B测试模式。参见 [docs/router-guide.md](docs/router-guide.md)。
---
## 自主托管后端
```bash
git clone https://github.com/aarohim24/Traject
cd Traject
bash scripts/setup.sh # 生成deploy/.env并包含强随机密钥
docker compose -f deploy/docker-compose.yml up -d
```
`scripts/setup.sh`生成一个`deploy/.env`,包含Postgres、Redis和API密钥的加密随机密码,然后打印API密钥以配置SDK。后端拒绝启动时使用占位符密钥,因此请先运行此命令。
启动的服务:PostgreSQL 16 + pgvector,Redis 7,Traject后端(端口8000),Grafana仪表盘(端口3000),React仪表盘(端口5173)。
```python
traject.configure(
backend_url="http://localhost:8000",
backend_api_key="your-key",
)
```
添加:按功能标签进行成本归因、语义缓存、预算警报、团队仪表盘。后端是可选的——SDK在没有它的情况下独立运行。
---
## 集成路径
### 哪种集成适合您?
```
您是否正在编写Python/TypeScript代码?
└─ 是 → SDK patch() (3行,无需更改调用站点)
└─ 否 — 我希望无需更改代码
├─ 使用Copilot代理模式、Claude Desktop或Cursor?
│ └─ MCP服务器 → traject mcp
└─ 使用OpenAI兼容客户端运行任何代理?
└─ 代理 → traject proxy --port 8080 --backend https://api.openai.com
```
### MCP服务器
适用于GitHub Copilot代理模式、Claude Desktop、Cursor、M365 Copilot声明式代理——无需API密钥,无需代码更改。
```bash
pip install -e ".[mcp]"
traject mcp
```
**VS Code / Copilot**(`.vscode/mcp.json`):
```json
{
"servers": {
"traject": {
"command": "traject",
"args": ["mcp"]
}
}
}
```
**Claude Desktop**(`claude_desktop_config.json`):
```json
{
"mcpServers": {
"traject": {
"command": "traject",
"args": ["mcp"]
}
}
}
```
暴露了四个工具:
- `traject_compress` — 压缩任何文本块(工具输出、文件、日志、RAG块),返回压缩文本+令牌增量
- `traject_stats` — 会话聚合减少指标
- `traject_budget` — 设置令牌限制并检查确定/警告/超出状态
- `traject_retrieve` — 恢复`<<ccr:HASH>>`存根后面的完整内容(需要`TRAJECT_REDIS_URL`和 `[ccr]`额外)
影子模式是默认的——`traject_compress`返回原始文本和指标,直到您传递`shadow_mode=False`。
### OpenAI兼容的透明代理
无需代码更改。让您的代理指向`localhost:8080`而不是`api.openai.com`。适用于OpenAI、Azure OpenAI、Ollama、LM Studio或任何OpenAI兼容的后端。
```bash
pip install -e ".[proxy]"
traject proxy --port 8080 --backend https://api.openai.com
# Azure OpenAI: --backend https://your-resource.openai.azure.com
# Ollama: --backend http://localhost:11434
# 实时压缩:添加--live标志(默认为影子模式)
```
然后在您的代理或环境中:
```bash
export OPENAI_BASE_URL=http://localhost:8080
```
每个响应都带有`X-Traject-Tokens-Saved`和`X-Traject-Shadow-Mode`标头。
---
## 基准测试
工作负载:49个真实SWE-bench代理轨迹(OpenHands-SFT,SWE-Gym)。平均29个回合/轨迹。公开可复制。
数据集: [SWE-Gym/OpenHands-SFT-Trajectories](https://huggingface.co/datasets/SWE-Gym/SWE-Gym) (HuggingFace,公开)
49个OpenHands-SFT编码代理轨迹,来自SWE-Gym。令牌减少和事实保留在相同的实例上独立测量。
| 指标 | CONSERVATIVE | MODERATE |
|---|---|---|
| **聚合令牌减少** | **43.1%** | **45.1%** |
| 平均减少 | 40.2% | 41.7% |
| p50减少 | 41.5% | 46.6% |
| p95减少 | 62.3% | 65.8% |
| 平均事实保留 | 64.0% | 63.6% |
| p50事实保留 | 70.0% | 70.0% |
| 评估实例 | 49 | 49 |
CONSERVATIVE是安全的默认设置——验证后适用于新部署。切换到MODERATE后,请确认您的工作负载。
**减少**针对调用者发送的**原始输入令牌**进行测量。 **事实保留**是具体、不可重建的事实的分数——文件:行引用、错误/异常类型、测试名称、git SHA、URL——在压缩输出中逐字出现。这是一个故意严格的、与嵌入式评分器无关的指标。
64–70%的事实保留率反映了管道积极压缩大量工具输出(大型git差异、完整的pytest集合、文件列表),同时保留失败行、错误类型和函数级标识符。活跃引用的段中的事实完全受保护;旧的、未引用的大块输出中的事实可能会被总结掉。
重现:
```bash
python examples/benchmark/swebench_eval.py --input trajectories.jsonl --strategy conservative
python examples/benchmark/quality_eval.py --input trajectories.jsonl --strategy conservative
```
---
## 支持的提供商
| 提供商 | 检测 | 路由 | 批量路由 |
|---|---|---|---|
| OpenAI | ✓ | ✓ | ✓ |
| Anthropic | ✓ | ✓ | ✓ |
| AWS Bedrock | ✓ | — | — |
| Google Vertex AI | ✓ | — | — |
| LangChain(任意提供商) | ✓ | ✓ | — |
| AutoGen(任意提供商) | ✓ | ✓ | — |
---
## 需求
- Python 3.11+
- 无外部API调用进行优化——嵌入式模型(`all-MiniLM-L6-v2`)在进程中运行
- Docker和Docker Compose(自主托管后端,仅可选)
---
## 架构
```
您的应用程序
│
▼
Traject SDK
├── 检测包装器
├── 工件类型分类器
├── 轨迹压缩引擎
├── 语义缓存客户端
├── 模型路由器
└── OTel跨度发射器
│
├──────────────────────► LLM提供商
│ (OpenAI、Anthropic、Bedrock、Vertex)
│
└──────────────────────► Traject后端(可选)
FastAPI · PostgreSQL · Redis
│
└── Grafana / React 仪表盘
```
## 许可证
MIT - 参见 [LICENSE](LICENSE)。