nic-6443 commented on code in PR #13676:
URL: https://github.com/apache/apisix/pull/13676#discussion_r3585722841
##########
apisix/plugins/ai-proxy-multi.lua:
##########
@@ -156,7 +172,70 @@ function _M.check_schema(conf)
end
end
- return ok
+ if algo == "semantic" then
+ if not conf.embeddings then
+ return false, "must configure `embeddings` when balancer algorithm
is semantic"
+ end
+ -- Same scheme+host check the instance endpoints get: without it an
+ -- endpoint like "host/path" parses to a nil host and every request
would
+ -- silently fail open, i.e. the route would never work with no signal.
+ local eendpoint = conf.embeddings.endpoint
+ if eendpoint then
+ local scheme, host = eendpoint:match(endpoint_regex)
+ if not scheme or not host then
+ return false, "invalid `embeddings.endpoint`"
+ end
+ end
+ if conf.embeddings.provider == "azure-openai" then
+ -- Azure carries the deployment in the URL and declares no default
host
+ -- or path, so the endpoint must be the full embeddings URL.
Without a
+ -- path every request would silently fail open to the catchall.
+ if not eendpoint then
+ return false, "must configure `embeddings.endpoint` when
embeddings " ..
+ "provider is azure-openai"
+ end
+ local parsed = url.parse(eendpoint)
+ local epath = parsed and parsed.path
+ if not epath or epath == "" or epath == "/" then
+ return false, "`embeddings.endpoint` for azure-openai must
include the " ..
+ "full deployment path, e.g.
https://{resource}.openai.azure.com" ..
+
"/openai/deployments/{deployment}/embeddings?api-version=..."
+ end
+ end
+ local catchall_count = 0
+ for _, instance in ipairs(conf.instances) do
+ if instance.catchall then
+ catchall_count = catchall_count + 1
+ -- The catchall is the fallback target, never a ranking
candidate.
+ -- Allowing examples on it would let it outrank a real match.
+ if instance.examples then
+ return false, "instance '" .. (instance.name or "?") ..
+ "': `catchall` instance must not configure `examples`;
it is " ..
+ "the fallback target and does not take part in ranking"
+ end
+ else
+ local has_example = false
+ if instance.examples then
+ for _, ex in ipairs(instance.examples) do
+ if type(ex) == "string" and ex ~= "" then
+ has_example = true
+ break
+ end
+ end
+ end
+ if not has_example then
+ return false, "instance '" .. (instance.name or "?") ..
+ "': must configure non-empty `examples` for the
semantic " ..
+ "algorithm unless `catchall` is set"
+ end
+ end
+ end
+ if catchall_count > 1 then
+ return false, "at most one instance may be marked `catchall`"
Review Comment:
I feel this validation code is overly complex, and we can simplify it by
adjusting the configuration as follows:
```
{
"balancer": {
"algorithm": "semantic",
},
"semantic_opts":{
"embeddings": {...},
"fallback": "default", // Used when request the embedding model fails
or no instances exceed the threshold
"threshold": 0.5,
"debugging": true // Replace the current expose_scores. The name
expose_scores is too specific, as we may have other debug information besides
scores in the future.
},
"instances": [
{
"name": "reasoning"
...
},
{
"name": "cheap"
...
},
{
"name": "default"
...
}
]
}
```
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: [email protected]
For queries about this service, please contact Infrastructure at:
[email protected]