mirror of
https://github.com/claude-code-best/claude-code.git
synced 2026-06-23 08:45:50 +00:00
feat: langfuse tracing 增加 thinking 参数记录
在 recordLLMObservation 中添加 thinking 配置(type/budgetTokens), 所有 provider(claude/gemini/openai)及 tokenEstimation、sideQuery 调用处同步传递 thinking 信息,便于 Langfuse 面板观察 thinking 使用情况。 Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
@@ -1776,6 +1776,8 @@ async function* queryModel(
|
|||||||
// captures only primitives instead of paramsFromContext's full closure scope
|
// captures only primitives instead of paramsFromContext's full closure scope
|
||||||
// (messagesForAPI, system, allTools, betas — the entire request-building
|
// (messagesForAPI, system, allTools, betas — the entire request-building
|
||||||
// context), which would otherwise be pinned until the promise resolves.
|
// context), which would otherwise be pinned until the promise resolves.
|
||||||
|
// Also capture thinking params for Langfuse observability.
|
||||||
|
let langfuseThinking: { type: string; budgetTokens?: number } | undefined
|
||||||
{
|
{
|
||||||
const queryParams = paramsFromContext({
|
const queryParams = paramsFromContext({
|
||||||
model: options.model,
|
model: options.model,
|
||||||
@@ -1785,6 +1787,15 @@ async function* queryModel(
|
|||||||
const logBetas = useBetas ? (queryParams.betas ?? []) : []
|
const logBetas = useBetas ? (queryParams.betas ?? []) : []
|
||||||
const logThinkingType = queryParams.thinking?.type ?? 'disabled'
|
const logThinkingType = queryParams.thinking?.type ?? 'disabled'
|
||||||
const logEffortValue = queryParams.output_config?.effort
|
const logEffortValue = queryParams.output_config?.effort
|
||||||
|
if (queryParams.thinking && queryParams.thinking.type !== 'disabled') {
|
||||||
|
langfuseThinking = {
|
||||||
|
type: queryParams.thinking.type,
|
||||||
|
...('budget_tokens' in queryParams.thinking &&
|
||||||
|
typeof queryParams.thinking.budget_tokens === 'number' && {
|
||||||
|
budgetTokens: queryParams.thinking.budget_tokens,
|
||||||
|
}),
|
||||||
|
}
|
||||||
|
}
|
||||||
void options.getToolPermissionContext().then(permissionContext => {
|
void options.getToolPermissionContext().then(permissionContext => {
|
||||||
logAPIQuery({
|
logAPIQuery({
|
||||||
model: options.model,
|
model: options.model,
|
||||||
@@ -2925,6 +2936,7 @@ async function* queryModel(
|
|||||||
endTime: new Date(),
|
endTime: new Date(),
|
||||||
completionStartTime: ttftMs > 0 ? new Date(start + ttftMs) : undefined,
|
completionStartTime: ttftMs > 0 ? new Date(start + ttftMs) : undefined,
|
||||||
tools: convertToolsToLangfuse(toolSchemas as unknown[]),
|
tools: convertToolsToLangfuse(toolSchemas as unknown[]),
|
||||||
|
thinking: langfuseThinking,
|
||||||
})
|
})
|
||||||
|
|
||||||
void options.getToolPermissionContext().then(permissionContext => {
|
void options.getToolPermissionContext().then(permissionContext => {
|
||||||
|
|||||||
@@ -193,6 +193,15 @@ export async function* queryModelGemini(
|
|||||||
endTime: new Date(),
|
endTime: new Date(),
|
||||||
completionStartTime: ttftMs > 0 ? new Date(start + ttftMs) : undefined,
|
completionStartTime: ttftMs > 0 ? new Date(start + ttftMs) : undefined,
|
||||||
tools: convertToolsToLangfuse(toolSchemas as unknown[]),
|
tools: convertToolsToLangfuse(toolSchemas as unknown[]),
|
||||||
|
thinking:
|
||||||
|
thinkingConfig.type !== 'disabled'
|
||||||
|
? {
|
||||||
|
type: thinkingConfig.type,
|
||||||
|
...(thinkingConfig.type === 'enabled' && {
|
||||||
|
budgetTokens: thinkingConfig.budgetTokens,
|
||||||
|
}),
|
||||||
|
}
|
||||||
|
: undefined,
|
||||||
})
|
})
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
const errorMessage = error instanceof Error ? error.message : String(error)
|
const errorMessage = error instanceof Error ? error.message : String(error)
|
||||||
|
|||||||
@@ -418,6 +418,7 @@ export async function* queryModelOpenAI(
|
|||||||
endTime: new Date(),
|
endTime: new Date(),
|
||||||
completionStartTime: ttftMs > 0 ? new Date(start + ttftMs) : undefined,
|
completionStartTime: ttftMs > 0 ? new Date(start + ttftMs) : undefined,
|
||||||
tools: convertToolsToLangfuse(toolSchemas as unknown[]),
|
tools: convertToolsToLangfuse(toolSchemas as unknown[]),
|
||||||
|
...(enableThinking && { thinking: { type: 'enabled' } }),
|
||||||
})
|
})
|
||||||
|
|
||||||
// Safety: if stream ended without message_stop, assemble and yield whatever we have
|
// Safety: if stream ended without message_stop, assemble and yield whatever we have
|
||||||
|
|||||||
@@ -78,6 +78,11 @@ export function recordLLMObservation(
|
|||||||
endTime?: Date
|
endTime?: Date
|
||||||
completionStartTime?: Date
|
completionStartTime?: Date
|
||||||
tools?: unknown
|
tools?: unknown
|
||||||
|
/** Thinking depth configuration used for this request */
|
||||||
|
thinking?: {
|
||||||
|
type: string
|
||||||
|
budgetTokens?: number
|
||||||
|
}
|
||||||
},
|
},
|
||||||
): void {
|
): void {
|
||||||
if (!rootSpan || !isLangfuseEnabled()) return
|
if (!rootSpan || !isLangfuseEnabled()) return
|
||||||
@@ -97,6 +102,10 @@ export function recordLLMObservation(
|
|||||||
metadata: {
|
metadata: {
|
||||||
provider: params.provider,
|
provider: params.provider,
|
||||||
model: params.model,
|
model: params.model,
|
||||||
|
...(params.thinking && { thinkingType: params.thinking.type }),
|
||||||
|
...(params.thinking?.budgetTokens !== undefined && {
|
||||||
|
thinkingBudgetTokens: params.thinking.budgetTokens,
|
||||||
|
}),
|
||||||
},
|
},
|
||||||
...(params.completionStartTime && { completionStartTime: params.completionStartTime }),
|
...(params.completionStartTime && { completionStartTime: params.completionStartTime }),
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -354,6 +354,7 @@ export async function countTokensViaHaikuFallback(
|
|||||||
},
|
},
|
||||||
startTime: new Date(apiStart),
|
startTime: new Date(apiStart),
|
||||||
endTime: new Date(),
|
endTime: new Date(),
|
||||||
|
...(containsThinking && { thinking: { type: 'enabled', budgetTokens: TOKEN_COUNT_THINKING_BUDGET } }),
|
||||||
})
|
})
|
||||||
endTrace(langfuseTrace)
|
endTrace(langfuseTrace)
|
||||||
|
|
||||||
|
|||||||
@@ -294,6 +294,12 @@ export async function sideQuery(opts: SideQueryOptions): Promise<BetaMessage> {
|
|||||||
startTime: new Date(start),
|
startTime: new Date(start),
|
||||||
endTime: new Date(),
|
endTime: new Date(),
|
||||||
...(tools && { tools: convertToolsToLangfuse(tools as unknown[]) }),
|
...(tools && { tools: convertToolsToLangfuse(tools as unknown[]) }),
|
||||||
|
...(thinkingConfig && thinkingConfig.type !== 'disabled' && {
|
||||||
|
thinking: {
|
||||||
|
type: thinkingConfig.type,
|
||||||
|
...(thinkingConfig.type === 'enabled' && { budgetTokens: thinkingConfig.budget_tokens }),
|
||||||
|
},
|
||||||
|
}),
|
||||||
})
|
})
|
||||||
endTrace(langfuseTrace)
|
endTrace(langfuseTrace)
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user