fix: implement Anthropic thinking budget calculation in reasoning logic (#9991)

This commit is contained in:
SuYao 2025-09-06 22:29:36 +08:00 committed by GitHub
parent ff74e9035d
commit 2361c1b211
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 35 additions and 15 deletions

View File

@ -9,17 +9,19 @@ import {
isOpenRouterBuiltInWebSearchModel,
isReasoningModel,
isSupportedReasoningEffortModel,
isSupportedThinkingTokenClaudeModel,
isSupportedThinkingTokenModel,
isWebSearchModel
} from '@renderer/config/models'
import { getAssistantSettings, getDefaultModel } from '@renderer/services/AssistantService'
import type { Assistant, MCPTool, Provider } from '@renderer/types'
import { type Assistant, type MCPTool, type Provider } from '@renderer/types'
import type { StreamTextParams } from '@renderer/types/aiCoreTypes'
import type { ModelMessage } from 'ai'
import { stepCountIs } from 'ai'
import { setupToolsConfig } from '../utils/mcp'
import { buildProviderOptions } from '../utils/options'
import { getAnthropicThinkingBudget } from '../utils/reasoning'
import { getTemperature, getTopP } from './modelParameters'
const logger = loggerService.withContext('parameterBuilder')
@ -55,7 +57,7 @@ export async function buildStreamTextParams(
const model = assistant.model || getDefaultModel()
const { maxTokens } = getAssistantSettings(assistant)
let { maxTokens } = getAssistantSettings(assistant)
// 这三个变量透传出来,交给下面启用插件/中间件
// 也可以在外部构建好再传入buildStreamTextParams
@ -88,6 +90,16 @@ export async function buildStreamTextParams(
enableGenerateImage
})
// NOTE: ai-sdk会把maxToken和budgetToken加起来
if (
enableReasoning &&
maxTokens !== undefined &&
isSupportedThinkingTokenClaudeModel(model) &&
(provider.type === 'anthropic' || provider.type === 'aws-bedrock')
) {
maxTokens -= getAnthropicThinkingBudget(assistant, model)
}
// 构建基础参数
const params: StreamTextParams = {
messages: sdkMessages,

View File

@ -310,6 +310,26 @@ export function getOpenAIReasoningParams(assistant: Assistant, model: Model): Re
return {}
}
export function getAnthropicThinkingBudget(assistant: Assistant, model: Model): number {
const { maxTokens, reasoning_effort: reasoningEffort } = getAssistantSettings(assistant)
if (maxTokens === undefined || reasoningEffort === undefined) {
return 0
}
const effortRatio = EFFORT_RATIO[reasoningEffort]
const budgetTokens = Math.max(
1024,
Math.floor(
Math.min(
(findTokenLimit(model.id)?.max! - findTokenLimit(model.id)?.min!) * effortRatio +
findTokenLimit(model.id)?.min!,
(maxTokens || DEFAULT_MAX_TOKENS) * effortRatio
)
)
)
return budgetTokens
}
/**
* Anthropic
* AnthropicAPIClient
@ -331,19 +351,7 @@ export function getAnthropicReasoningParams(assistant: Assistant, model: Model):
// Claude 推理参数
if (isSupportedThinkingTokenClaudeModel(model)) {
const { maxTokens } = getAssistantSettings(assistant)
const effortRatio = EFFORT_RATIO[reasoningEffort]
const budgetTokens = Math.max(
1024,
Math.floor(
Math.min(
(findTokenLimit(model.id)?.max! - findTokenLimit(model.id)?.min!) * effortRatio +
findTokenLimit(model.id)?.min!,
(maxTokens || DEFAULT_MAX_TOKENS) * effortRatio
)
)
)
const budgetTokens = getAnthropicThinkingBudget(assistant, model)
return {
thinking: {