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
     },
     "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]

Reply via email to