fix: 收窄 OpenAI o 系列模型适配范围 (#5293)
* fix: 收窄 OpenAI o 系列模型适配范围 * fix(openai): 限制 gpt-5 适配仅作用于 OpenAI 模型 * fix(openai): narrow o-series reasoning model detection --------- Co-authored-by: Seefs <i@seefs.me>
This commit is contained in:
@@ -814,7 +814,7 @@ func buildTestRequest(model string, endpointType string, channel *model.Channel,
|
|||||||
testRequest.StreamOptions = &dto.StreamOptions{IncludeUsage: true}
|
testRequest.StreamOptions = &dto.StreamOptions{IncludeUsage: true}
|
||||||
}
|
}
|
||||||
|
|
||||||
if strings.HasPrefix(model, "o") {
|
if dto.IsOpenAIReasoningOModel(model) {
|
||||||
testRequest.MaxCompletionTokens = lo.ToPtr(uint(16))
|
testRequest.MaxCompletionTokens = lo.ToPtr(uint(16))
|
||||||
} else if strings.Contains(model, "thinking") {
|
} else if strings.Contains(model, "thinking") {
|
||||||
if !strings.Contains(model, "claude") {
|
if !strings.Contains(model, "claude") {
|
||||||
|
|||||||
+12
-2
@@ -213,12 +213,22 @@ func (r *GeneralOpenAIRequest) ToMap() map[string]any {
|
|||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func IsOpenAIReasoningOModel(modelName string) bool {
|
||||||
|
return strings.HasPrefix(modelName, "o1") ||
|
||||||
|
strings.HasPrefix(modelName, "o3") ||
|
||||||
|
strings.HasPrefix(modelName, "o4")
|
||||||
|
}
|
||||||
|
|
||||||
|
func IsOpenAIGPT5Model(modelName string) bool {
|
||||||
|
return strings.HasPrefix(modelName, "gpt-5")
|
||||||
|
}
|
||||||
|
|
||||||
func (r *GeneralOpenAIRequest) GetSystemRoleName() string {
|
func (r *GeneralOpenAIRequest) GetSystemRoleName() string {
|
||||||
if strings.HasPrefix(r.Model, "o") {
|
if IsOpenAIReasoningOModel(r.Model) {
|
||||||
if !strings.HasPrefix(r.Model, "o1-mini") && !strings.HasPrefix(r.Model, "o1-preview") {
|
if !strings.HasPrefix(r.Model, "o1-mini") && !strings.HasPrefix(r.Model, "o1-preview") {
|
||||||
return "developer"
|
return "developer"
|
||||||
}
|
}
|
||||||
} else if strings.HasPrefix(r.Model, "gpt-5") {
|
} else if IsOpenAIGPT5Model(r.Model) {
|
||||||
return "developer"
|
return "developer"
|
||||||
}
|
}
|
||||||
return "system"
|
return "system"
|
||||||
|
|||||||
@@ -71,3 +71,27 @@ func TestOpenAIResponsesRequestPreserveExplicitZeroValues(t *testing.T) {
|
|||||||
require.True(t, gjson.GetBytes(encoded, "stream").Exists())
|
require.True(t, gjson.GetBytes(encoded, "stream").Exists())
|
||||||
require.True(t, gjson.GetBytes(encoded, "top_p").Exists())
|
require.True(t, gjson.GetBytes(encoded, "top_p").Exists())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestGeneralOpenAIRequestGetSystemRoleName(t *testing.T) {
|
||||||
|
tests := []struct {
|
||||||
|
name string
|
||||||
|
model string
|
||||||
|
want string
|
||||||
|
}{
|
||||||
|
{name: "o1 uses developer", model: "o1", want: "developer"},
|
||||||
|
{name: "o3 family uses developer", model: "o3-mini-high", want: "developer"},
|
||||||
|
{name: "o4 family uses developer", model: "o4-mini", want: "developer"},
|
||||||
|
{name: "o1 mini stays system", model: "o1-mini", want: "system"},
|
||||||
|
{name: "o1 preview stays system", model: "o1-preview", want: "system"},
|
||||||
|
{name: "gpt 5 uses developer", model: "gpt-5", want: "developer"},
|
||||||
|
{name: "omni is not o series", model: "omni-moderation-latest", want: "system"},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, tt := range tests {
|
||||||
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
|
req := GeneralOpenAIRequest{Model: tt.model}
|
||||||
|
|
||||||
|
require.Equal(t, tt.want, req.GetSystemRoleName())
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -310,18 +310,20 @@ func (a *Adaptor) ConvertOpenAIRequest(c *gin.Context, info *relaycommon.RelayIn
|
|||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
if strings.HasPrefix(info.UpstreamModelName, "o") || strings.HasPrefix(info.UpstreamModelName, "gpt-5") {
|
isOModel := dto.IsOpenAIReasoningOModel(info.UpstreamModelName)
|
||||||
|
isGPT5Model := dto.IsOpenAIGPT5Model(info.UpstreamModelName)
|
||||||
|
if isOModel || isGPT5Model {
|
||||||
if lo.FromPtrOr(request.MaxCompletionTokens, uint(0)) == 0 && lo.FromPtrOr(request.MaxTokens, uint(0)) != 0 {
|
if lo.FromPtrOr(request.MaxCompletionTokens, uint(0)) == 0 && lo.FromPtrOr(request.MaxTokens, uint(0)) != 0 {
|
||||||
request.MaxCompletionTokens = request.MaxTokens
|
request.MaxCompletionTokens = request.MaxTokens
|
||||||
request.MaxTokens = nil
|
request.MaxTokens = nil
|
||||||
}
|
}
|
||||||
|
|
||||||
if strings.HasPrefix(info.UpstreamModelName, "o") {
|
if isOModel {
|
||||||
request.Temperature = nil
|
request.Temperature = nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// gpt-5系列模型适配 归零不再支持的参数
|
// gpt-5系列模型适配 归零不再支持的参数
|
||||||
if strings.HasPrefix(info.UpstreamModelName, "gpt-5") {
|
if isGPT5Model {
|
||||||
request.Temperature = nil
|
request.Temperature = nil
|
||||||
request.TopP = nil
|
request.TopP = nil
|
||||||
request.LogProbs = nil
|
request.LogProbs = nil
|
||||||
|
|||||||
Reference in New Issue
Block a user