Files
aiagent/backend/app/core/compaction_config.py

121 lines
4.3 KiB
Python
Raw Normal View History

"""
对话压缩配置模型
参考 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 余量"
)