121 lines
4.3 KiB
Python
121 lines
4.3 KiB
Python
|
|
"""
|
|||
|
|
对话压缩配置模型
|
|||
|
|
|
|||
|
|
参考 Claude Code:
|
|||
|
|
- src/services/compact/autoCompact.ts — 自动压缩阈值
|
|||
|
|
- src/services/compact/sessionMemoryCompact.ts — 会话记忆压缩配置
|
|||
|
|
"""
|
|||
|
|
from __future__ import annotations
|
|||
|
|
|
|||
|
|
from typing import List
|
|||
|
|
from pydantic import BaseModel, Field
|
|||
|
|
|
|||
|
|
|
|||
|
|
class CompactionConfig(BaseModel):
|
|||
|
|
"""对话自动压缩配置。"""
|
|||
|
|
|
|||
|
|
# ── 总开关 ──
|
|||
|
|
enabled: bool = Field(default=True, description="是否启用自动压缩")
|
|||
|
|
|
|||
|
|
# ── 各策略开关 ──
|
|||
|
|
micro_compact_enabled: bool = Field(default=True, description="MicroCompact: 旧工具结果打桩")
|
|||
|
|
full_compact_enabled: bool = Field(default=True, description="FullCompact: LLM 摘要替换")
|
|||
|
|
reactive_compact_enabled: bool = Field(default=True, description="ReactiveCompact: 错误触发压缩")
|
|||
|
|
|
|||
|
|
# ── 触发阈值(占模型上下文窗口的百分比) ──
|
|||
|
|
# 参考 Claude Code: autoCompact 在 effective_window - 13K 时触发
|
|||
|
|
# 这里用百分比便于适配不同模型
|
|||
|
|
micro_compact_threshold: float = Field(
|
|||
|
|
default=0.70,
|
|||
|
|
ge=0.1, le=1.0,
|
|||
|
|
description="MicroCompact 触发阈值(占窗口比例),默认 70%"
|
|||
|
|
)
|
|||
|
|
full_compact_threshold: float = Field(
|
|||
|
|
default=0.85,
|
|||
|
|
ge=0.1, le=1.0,
|
|||
|
|
description="FullCompact 触发阈值(占窗口比例),默认 85%"
|
|||
|
|
)
|
|||
|
|
reactive_threshold: float = Field(
|
|||
|
|
default=0.95,
|
|||
|
|
ge=0.5, le=1.0,
|
|||
|
|
description="被动压缩阈值 — 超过此值等待 API 报错后触发 reactive compact"
|
|||
|
|
)
|
|||
|
|
|
|||
|
|
# ── 保留策略 ──
|
|||
|
|
# 参考 Claude Code microCompact.ts: 至少保留最近的 tool/assistant 对
|
|||
|
|
min_preserve_messages: int = Field(
|
|||
|
|
default=6,
|
|||
|
|
ge=2,
|
|||
|
|
description="压缩后至少保留的最近消息数"
|
|||
|
|
)
|
|||
|
|
compact_older_than_rounds: int = Field(
|
|||
|
|
default=5,
|
|||
|
|
ge=1,
|
|||
|
|
description="工具结果超过此轮次的对话轮次后可被压缩"
|
|||
|
|
)
|
|||
|
|
|
|||
|
|
# ── 摘要配置 ──
|
|||
|
|
# 参考 Claude Code compact.ts: 用轻量模型做摘要
|
|||
|
|
summary_max_tokens: int = Field(
|
|||
|
|
default=500,
|
|||
|
|
ge=50, le=4000,
|
|||
|
|
description="压缩摘要的最大输出 token 数"
|
|||
|
|
)
|
|||
|
|
summary_model: str = Field(
|
|||
|
|
default="deepseek-v4-flash",
|
|||
|
|
description="用于生成摘要的轻量模型"
|
|||
|
|
)
|
|||
|
|
summary_temperature: float = Field(
|
|||
|
|
default=0.1,
|
|||
|
|
ge=0.0, le=1.0,
|
|||
|
|
description="摘要生成温度(低=更稳定)"
|
|||
|
|
)
|
|||
|
|
|
|||
|
|
# ── 熔断 ──
|
|||
|
|
# 参考 Claude Code: MAX_CONSECUTIVE_AUTOCOMPACT_FAILURES = 3
|
|||
|
|
max_consecutive_failures: int = Field(
|
|||
|
|
default=3,
|
|||
|
|
ge=0, le=10,
|
|||
|
|
description="连续压缩失败熔断阈值"
|
|||
|
|
)
|
|||
|
|
|
|||
|
|
# ── 可压缩工具列表 ──
|
|||
|
|
# 参考 Claude Code microCompact.ts: 只压缩 "searchable" 工具结果
|
|||
|
|
# write/edit/delete 等破坏性工具结果不压缩(安全考虑)
|
|||
|
|
compactable_tools: List[str] = Field(
|
|||
|
|
default_factory=lambda: [
|
|||
|
|
"file_read", "list_files", "search_files", "search_content",
|
|||
|
|
"web_search", "web_fetch", "code_execute", "datetime",
|
|||
|
|
"system_info", "entity_search", "knowledge_graph_search",
|
|||
|
|
"http_request", "url_parse", "math_calculate",
|
|||
|
|
"text_analyze", "json_process", "image_ocr",
|
|||
|
|
"image_vision", "excel_process", "pdf_generate",
|
|||
|
|
"random_generate", "notify_user",
|
|||
|
|
],
|
|||
|
|
description="可被 MicroCompact 压缩的工具名列表"
|
|||
|
|
)
|
|||
|
|
|
|||
|
|
# ── 受保护的工具(绝不压缩) ──
|
|||
|
|
protected_tools: List[str] = Field(
|
|||
|
|
default_factory=lambda: [
|
|||
|
|
"file_write", "file_edit", "deploy_push",
|
|||
|
|
"docker_manage", "database_query", "git_operation",
|
|||
|
|
"create_task", "agent_create", "agent_call",
|
|||
|
|
"send_email", "tool_register", "feishu_create_doc",
|
|||
|
|
"feishu_create_sheet", "feishu_send_approval",
|
|||
|
|
],
|
|||
|
|
description="绝不压缩的工具名列表(破坏性/外部通信操作)"
|
|||
|
|
)
|
|||
|
|
|
|||
|
|
# ── 上下文窗口覆盖 ──
|
|||
|
|
context_window_override: int = Field(
|
|||
|
|
default=0,
|
|||
|
|
ge=0,
|
|||
|
|
description="手动覆盖上下文窗口大小(0=自动检测模型窗口)"
|
|||
|
|
)
|
|||
|
|
output_reserve_tokens: int = Field(
|
|||
|
|
default=8192,
|
|||
|
|
ge=512, le=65536,
|
|||
|
|
description="留给模型输出的 token 余量"
|
|||
|
|
)
|