MCPcopy Create free account
hub / github.com/astercloud/aster / WrapModelCall

Method WrapModelCall

pkg/middleware/telemetry.go:100–181  ·  view source on GitHub ↗

WrapModelCall 包装模型调用,添加 GenAI 追踪

(ctx context.Context, req *ModelRequest, handler ModelCallHandler)

Source from the content-addressed store, hash-verified

98
99// WrapModelCall 包装模型调用,添加 GenAI 追踪
100func (m *TelemetryMiddleware) WrapModelCall(ctx context.Context, req *ModelRequest, handler ModelCallHandler) (*ModelResponse, error) {
101 startTime := time.Now()
102
103 // 构建 span 名称: "chat {model}"
104 spanName := genai.ChatSpanName(m.model)
105
106 // 构建初始属性
107 attrs := []telemetry.Attribute{
108 telemetry.String(genai.AttrOperationName, genai.OpChat),
109 telemetry.String(genai.AttrProviderName, m.provider),
110 telemetry.String(genai.AttrAgentID, m.agentID),
111 telemetry.String(genai.AttrAgentName, m.agentName),
112 telemetry.String(genai.AttrRequestModel, m.model),
113 }
114
115 // 添加会话 ID (如果有)
116 if m.conversationID != "" {
117 attrs = append(attrs, telemetry.String(genai.AttrConversationID, m.conversationID))
118 }
119
120 // 从 Metadata 中提取额外信息
121 if req.Metadata != nil {
122 if maxTokens, ok := req.Metadata["max_tokens"].(int); ok {
123 attrs = append(attrs, telemetry.Int(genai.AttrRequestMaxTokens, maxTokens))
124 }
125 if temperature, ok := req.Metadata["temperature"].(float64); ok {
126 attrs = append(attrs, telemetry.Float64(genai.AttrRequestTemperature, temperature))
127 }
128 if topP, ok := req.Metadata["top_p"].(float64); ok {
129 attrs = append(attrs, telemetry.Float64(genai.AttrRequestTopP, topP))
130 }
131 // 覆盖模型名称(如果 metadata 中指定了)
132 if model, ok := req.Metadata["model"].(string); ok && model != "" {
133 attrs = append(attrs, telemetry.String(genai.AttrRequestModel, model))
134 }
135 // 覆盖 provider(如果 metadata 中指定了)
136 if provider, ok := req.Metadata["provider"].(string); ok && provider != "" {
137 attrs = append(attrs, telemetry.String(genai.AttrProviderName, provider))
138 }
139 }
140
141 // 开始 span (CLIENT 类型,因为是调用外部 LLM)
142 ctx, span := m.tracer.StartSpan(ctx, spanName,
143 telemetry.WithSpanKind(telemetry.SpanKindClient),
144 telemetry.WithAttributes(attrs...),
145 )
146 defer span.End()
147
148 // 记录提示词事件 (如果启用)
149 if m.recordPrompts && len(req.Messages) > 0 {
150 m.recordPromptEvent(span, req)
151 }
152
153 // 调用下一层
154 resp, err := handler(ctx, req)
155
156 // 计算延迟
157 latencyMs := time.Since(startTime).Milliseconds()

Calls 15

recordPromptEventMethod · 0.95
setErrorTypeAttributeMethod · 0.95
recordCompletionEventMethod · 0.95
extractTokenUsageMethod · 0.95
extractResponseInfoMethod · 0.95
ChatSpanNameFunction · 0.92
StringFunction · 0.92
IntFunction · 0.92
Float64Function · 0.92
WithSpanKindFunction · 0.92
WithAttributesFunction · 0.92
Int64Function · 0.92