feat: add tools.disabled mode to skip all tool injection for max context savings

- tools.disabled: true completely skips tool definitions + few-shot injection
- Response-side parseToolCalls still works if model outputs action blocks
- Env var: TOOLS_DISABLED=true|false
- Updated config.yaml.example and docker-compose.yml
This commit is contained in:
小海
2026-03-20 09:23:15 +08:00
parent 7c2422ce60
commit 4a026b6b98
5 changed files with 44 additions and 1 deletions

View File

@@ -115,6 +115,14 @@ tools:
# 环境变量: TOOLS_PASSTHROUGH=true|false
# passthrough: true
# ★ 禁用模式(极致省上下文)
# true: 完全不注入工具定义和 few-shot 示例,节省大量上下文空间
# 模型凭自身训练记忆处理工具调用(适合已内化工具格式的场景)
# 响应中的 ```json action``` 块仍会被正常解析
# false: [默认] 正常注入工具定义
# 环境变量: TOOLS_DISABLED=true|false
# disabled: true
# ==================== 响应内容清洗(可选,默认关闭) ====================
# 开启后,会将响应中 Cursor 相关的身份引用替换为 Claude
# 例如 "I am Cursor's support assistant" → "I am Claude, an AI assistant by Anthropic"

View File

@@ -55,6 +55,10 @@ services:
# 开启后跳过 few-shot 注入,直接嵌入工具定义,减少身份冲突
# - TOOLS_PASSTHROUGH=true
# ── 工具禁用模式(极致省上下文) ──
# 完全不注入工具定义和 few-shot模型凭训练记忆调用工具
# - TOOLS_DISABLED=true
# ── 响应内容清洗 ──
# 开启后会将响应中 Cursor 身份引用替换为 Claude默认关闭
# - SANITIZE_RESPONSE=true

View File

@@ -90,6 +90,7 @@ function parseYamlConfig(defaults: AppConfig): { config: AppConfig; raw: Record<
includeOnly: Array.isArray(t.include_only) ? t.include_only.map(String) : undefined,
exclude: Array.isArray(t.exclude) ? t.exclude.map(String) : undefined,
passthrough: t.passthrough === true,
disabled: t.disabled === true,
};
}
// ★ 响应内容清洗开关(默认关闭)
@@ -150,6 +151,11 @@ function applyEnvOverrides(cfg: AppConfig): void {
if (!cfg.tools) cfg.tools = { schemaMode: 'full', descriptionMaxLength: 0 };
cfg.tools.passthrough = process.env.TOOLS_PASSTHROUGH === 'true' || process.env.TOOLS_PASSTHROUGH === '1';
}
// 工具禁用模式环境变量覆盖
if (process.env.TOOLS_DISABLED !== undefined) {
if (!cfg.tools) cfg.tools = { schemaMode: 'full', descriptionMaxLength: 0 };
cfg.tools.disabled = process.env.TOOLS_DISABLED === 'true' || process.env.TOOLS_DISABLED === '1';
}
// 响应内容清洗环境变量覆盖
if (process.env.SANITIZE_RESPONSE !== undefined) {

View File

@@ -258,9 +258,33 @@ export async function convertToCursorRequest(req: AnthropicRequest): Promise<Cur
const tools = req.tools!;
const toolChoice = req.tool_choice;
const toolsCfg = config.tools || { schemaMode: 'compact', descriptionMaxLength: 50 };
const isDisabled = toolsCfg.disabled === true;
const isPassthrough = toolsCfg.passthrough === true;
if (isPassthrough) {
if (isDisabled) {
// ★ 禁用模式:完全不注入工具定义和 few-shot 示例
// 目的:最大化节省上下文空间,让模型凭训练记忆处理工具调用
// 响应侧的 parseToolCalls 仍然生效,如果模型自行输出 ```json action``` 仍可解析
console.log(`[Converter] 工具禁用模式: ${tools.length} 个工具定义已跳过,不占用上下文`);
// 只注入系统提示词(如果有),不包含任何工具相关内容
if (combinedSystem) {
if (thinkingEnabled) {
combinedSystem += thinkingHint;
}
messages.push({
parts: [{ type: 'text', text: combinedSystem }],
id: shortId(),
role: 'user',
});
messages.push({
parts: [{ type: 'text', text: 'Understood. I\'ll help you with the task.' }],
id: shortId(),
role: 'assistant',
});
}
} else if (isPassthrough) {
// ★ 透传模式:直接嵌入原始工具定义,跳过 few-shot 注入
// 目的:减少与 Cursor 内建身份的提示词冲突
// 适用Roo Code、Cline 等非 Claude Code 客户端

View File

@@ -136,6 +136,7 @@ export interface AppConfig {
includeOnly?: string[]; // 白名单:只保留的工具名
exclude?: string[]; // 黑名单:要排除的工具名
passthrough?: boolean; // 透传模式:跳过 few-shot 注入,直接嵌入工具定义
disabled?: boolean; // 禁用模式:完全不注入工具定义,最大化节省上下文
};
sanitizeEnabled: boolean; // 是否启用响应内容清洗(替换 Cursor 身份引用为 Claude默认 false
refusalPatterns?: string[]; // 自定义拒绝检测规则(追加到内置列表之后)