feat(ai-proxy): add modelMapping regexp support (#2358)

Signed-off-by: Xijun Dai <daixijun1990@gmail.com>
This commit is contained in:
Xijun Dai
2025-06-03 22:29:17 +08:00
committed by GitHub
parent 7b1ae49cd4
commit 896780b60e
2 changed files with 195 additions and 179 deletions

View File

@@ -20,23 +20,22 @@ description: AI 代理插件配置参考
插件执行阶段:`默认阶段`
插件执行优先级:`100`
## 配置字段
### 基本配置
| 名称 | 数据类型 | 填写要求 | 默认值 | 描述 |
|------------|--------|------|-----|------------------|
| ---------- | -------- | -------- | ------ | ---------------------------- |
| `provider` | object | 必填 | - | 配置目标 AI 服务提供商的信息 |
`provider`的配置字段说明如下:
| 名称 | 数据类型 | 填写要求 | 默认值 | 描述 |
|------------------| --------------- | -------- | ------ |-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| ---------------------- | ---------------------- | -------- | ------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `type` | string | 必填 | - | AI 服务提供商名称 |
| `apiTokens` | array of string | 非必填 | - | 用于在访问 AI 服务时进行认证的令牌。如果配置了多个 token插件会在请求时随机进行选择。部分服务提供商只支持配置一个 token。 |
| `timeout` | number | 非必填 | - | 访问 AI 服务的超时时间。单位为毫秒。默认值为 120000即 2 分钟。此项配置目前仅用于获取上下文信息,并不影响实际转发大模型请求。 |
| `modelMapping` | map of string | 非必填 | - | AI 模型映射表,用于将请求中的模型名称映射为服务提供商支持模型名称。<br/>1. 支持前缀匹配。例如用 "gpt-3-\*" 匹配所有名称以“gpt-3-”开头的模型;<br/>2. 支持使用 "\*" 为键来配置通用兜底映射关系;<br/>3. 如果映射的目标名称为空字符串 "",则表示保留原模型名称。 |
| `modelMapping` | map of string | 非必填 | - | AI 模型映射表,用于将请求中的模型名称映射为服务提供商支持模型名称。<br/>1. 支持前缀匹配。例如用 "gpt-3-\*" 匹配所有名称以“gpt-3-”开头的模型;<br/>2. 支持使用 "\*" 为键来配置通用兜底映射关系;<br/>3. 如果映射的目标名称为空字符串 "",则表示保留原模型名称。<br/>4. 支持以 `~` 前缀使用正则匹配。例如用 "~gpt(.\*)" 匹配所有以 "gpt" 开头的模型并支持在目标模型中使用 capture group 引用匹配到的内容。示例: "~gpt(.\*): openai/gpt\$1" |
| `protocol` | string | 非必填 | - | 插件对外提供的 API 接口契约。目前支持以下取值openai默认值使用 OpenAI 的接口契约、original使用目标服务提供商的原始接口契约 |
| `context` | object | 非必填 | - | 配置 AI 对话上下文信息 |
| `customSettings` | array of customSetting | 非必填 | - | 为 AI 请求指定覆盖或者填充参数 |
@@ -48,12 +47,11 @@ description: AI 代理插件配置参考
`context`的配置字段说明如下:
| 名称 | 数据类型 | 填写要求 | 默认值 | 描述 |
|---------------|--------|------|-----|----------------------------------|
| ------------- | -------- | -------- | ------ | -------------------------------------------------------- |
| `fileUrl` | string | 必填 | - | 保存 AI 对话上下文的文件 URL。仅支持纯文本类型的文件内容 |
| `serviceName` | string | 必填 | - | URL 所对应的 Higress 后端服务完整名称 |
| `servicePort` | number | 必填 | - | URL 所对应的 Higress 后端服务访问端口 |
`customSettings`的配置字段说明如下:
| 名称 | 数据类型 | 填写要求 | 默认值 | 描述 |
@@ -63,11 +61,9 @@ description: AI 代理插件配置参考
| `mode` | string | 非必填 | "auto" | 参数设置的模式,可以设置为"auto"或者"raw",如果为"auto"则会自动根据协议对参数名做改写,如果为"raw"则不会有任何改写和限制检查 |
| `overwrite` | bool | 非必填 | true | 如果为 false 则只在用户没有设置这个参数时填充参数,否则会直接覆盖用户原有的参数设置 |
custom-setting 会遵循如下表格,根据`name`和协议来替换对应的字段,用户需要填写表格中`settingName`列中存在的值。例如用户将`name`设置为`max_tokens`,在 openai 协议中会替换`max_tokens`,在 gemini 中会替换`maxOutputTokens`
`none`表示该协议不支持此参数。如果`name`不在此表格中或者对应协议不支持此参数,同时没有设置 raw 模式,则配置不会生效。
| settingName | openai | baidu | spark | qwen | gemini | hunyuan | claude | minimax |
| ----------- | ----------- | ----------------- | ----------- | ----------- | --------------- | ----------- | ----------- | ------------------ |
| max_tokens | max_tokens | max_output_tokens | max_tokens | max_tokens | maxOutputTokens | none | max_tokens | tokens_to_generate |
@@ -82,7 +78,7 @@ custom-setting会遵循如下表格根据`name`和协议来替换对应的字
`failover` 的配置字段说明如下:
| 名称 | 数据类型 | 填写要求 | 默认值 | 描述 |
|------------------|--------|-----------------|-------|-----------------------------------|
| ------------------- | --------------- | -------------------- | -------------- | -------------------------------------------------------- |
| enabled | bool | 非必填 | false | 是否启用 apiToken 的 failover 机制 |
| failureThreshold | int | 非必填 | 3 | 触发 failover 连续请求失败的阈值(次数) |
| successThreshold | int | 非必填 | 1 | 健康检测的成功阈值(次数) |
@@ -95,9 +91,8 @@ custom-setting会遵循如下表格根据`name`和协议来替换对应的字
目前仅支持对非流式请求进行重试。
| 名称 | 数据类型 | 填写要求 | 默认值 | 描述 |
|------------------|--------|--------|-------|---------------------------|
| ------------- | --------------- | -------- | -------------- | -------------------------------------------------- |
| enabled | bool | 非必填 | false | 是否启用失败请求重试 |
| maxRetries | int | 非必填 | 1 | 最大重试次数 |
| retryTimeout | int | 非必填 | 30000 | 重试超时时间,单位毫秒 |
@@ -110,17 +105,16 @@ custom-setting会遵循如下表格根据`name`和协议来替换对应的字
OpenAI 所对应的 `type``openai`。它特有的配置字段如下:
| 名称 | 数据类型 | 填写要求 | 默认值 | 描述 |
|-------------------|----------|----------|--------|-------------------------------------------------------------------------------|
| `openaiCustomUrl` | string | 非必填 | - | 基于OpenAI协议的自定义后端URL例如: www.example.com/myai/v1/chat/completions |
| -------------------- | -------- | -------- | ------ | ---------------------------------------------------------------------------------- |
| `openaiCustomUrl` | string | 非必填 | - | 基于 OpenAI 协议的自定义后端 URL例如: <www.example.com/myai/v1/chat/completions> |
| `responseJsonSchema` | object | 非必填 | - | 预先定义 OpenAI 响应需满足的 Json Schema, 注意目前仅特定的几种模型支持该用法 |
#### Azure OpenAI
Azure OpenAI 所对应的 `type``azure`。它特有的配置字段如下:
| 名称 | 数据类型 | 填写要求 | 默认值 | 描述 |
|-------------------|--------|------|-----|----------------------------------------------|
| ----------------- | -------- | -------- | ------ | -------------------------------------------------------- |
| `azureServiceUrl` | string | 必填 | - | Azure OpenAI 服务的 URL须包含 `api-version` 查询参数。 |
**注意:** Azure OpenAI 只支持配置一个 API Token。
@@ -130,7 +124,7 @@ Azure OpenAI 所对应的 `type` 为 `azure`。它特有的配置字段如下:
月之暗面所对应的 `type``moonshot`。它特有的配置字段如下:
| 名称 | 数据类型 | 填写要求 | 默认值 | 描述 |
|------------------|--------|------|-----|-------------------------------------------------------------|
| ---------------- | -------- | -------- | ------ | ---------------------------------------------------------------------------------------------------- |
| `moonshotFileId` | string | 非必填 | - | 通过文件接口上传至月之暗面的文件 ID其内容将被用做 AI 对话的上下文。不可与 `context` 字段同时配置。 |
#### 通义千问Qwen
@@ -138,7 +132,7 @@ Azure OpenAI 所对应的 `type` 为 `azure`。它特有的配置字段如下:
通义千问所对应的 `type``qwen`。它特有的配置字段如下:
| 名称 | 数据类型 | 填写要求 | 默认值 | 描述 |
| ---------------------- | --------------- | -------- | ------ | ------------------------------------------------------------ |
| ---------------------- | --------------- | -------- | ------ | ------------------------------------------------------------------------------------------------------- |
| `qwenEnableSearch` | boolean | 非必填 | - | 是否启用通义千问内置的互联网搜索功能。 |
| `qwenFileIds` | array of string | 非必填 | - | 通过文件接口上传至 Dashscope 的文件 ID其内容将被用做 AI 对话的上下文。不可与 `context` 字段同时配置。 |
| `qwenEnableCompatible` | boolean | 非必填 | false | 开启通义千问兼容模式。启用通义千问兼容模式后,将调用千问的兼容模式接口,同时对请求/响应不做修改。 |
@@ -184,7 +178,7 @@ Mistral 所对应的 `type` 为 `mistral`。它并无特有的配置字段。
MiniMax 所对应的 `type``minimax`。它特有的配置字段如下:
| 名称 | 数据类型 | 填写要求 | 默认值 | 描述 |
| ---------------- | -------- | ------------------------------ | ------ |----------------------------------------------------------------|
| ---------------- | -------- | ------------------------------ | ------ | ----------------------------------------------------------------------- |
| `minimaxApiType` | string | v2 和 pro 中选填一项 | v2 | v2 代表 ChatCompletion v2 APIpro 代表 ChatCompletion Pro API |
| `minimaxGroupId` | string | `minimaxApiType` 为 pro 时必填 | - | `minimaxApiType` 为 pro 时使用 ChatCompletion Pro API需要设置 groupID |
@@ -193,7 +187,7 @@ MiniMax所对应的 `type` 为 `minimax`。它特有的配置字段如下:
Anthropic Claude 所对应的 `type``claude`。它特有的配置字段如下:
| 名称 | 数据类型 | 填写要求 | 默认值 | 描述 |
|-----------|--------|------|-----|----------------------------------|
| --------------- | -------- | -------- | ------ | ----------------------------------------- |
| `claudeVersion` | string | 可选 | - | Claude 服务的 API 版本,默认为 2023-06-01 |
#### Ollama
@@ -201,7 +195,7 @@ Anthropic Claude 所对应的 `type` 为 `claude`。它特有的配置字段如
Ollama 所对应的 `type``ollama`。它特有的配置字段如下:
| 名称 | 数据类型 | 填写要求 | 默认值 | 描述 |
|-------------------|--------|------|-----|----------------------------------------------|
| ------------------ | -------- | -------- | ------ | ----------------------------------- |
| `ollamaServerHost` | string | 必填 | - | Ollama 服务器的主机地址 |
| `ollamaServerPort` | number | 必填 | - | Ollama 服务器的端口号,默认为 11434 |
@@ -210,7 +204,7 @@ Ollama 所对应的 `type` 为 `ollama`。它特有的配置字段如下:
混元所对应的 `type``hunyuan`。它特有的配置字段如下:
| 名称 | 数据类型 | 填写要求 | 默认值 | 描述 |
|-------------------|--------|------|-----|----------------------------------------------|
| ---------------- | -------- | -------- | ------ | -------------------------- |
| `hunyuanAuthId` | string | 必填 | - | 混元用于 v3 版本认证的 id |
| `hunyuanAuthKey` | string | 必填 | - | 混元用于 v3 版本认证的 key |
@@ -223,7 +217,7 @@ Ollama 所对应的 `type` 为 `ollama`。它特有的配置字段如下:
Cloudflare Workers AI 所对应的 `type``cloudflare`。它特有的配置字段如下:
| 名称 | 数据类型 | 填写要求 | 默认值 | 描述 |
|-------------------|--------|------|-----|----------------------------------------------------------------------------------------------------------------------------|
| --------------------- | -------- | -------- | ------ | -------------------------------------------------------------------------------------------------------------------------- |
| `cloudflareAccountId` | string | 必填 | - | [Cloudflare Account ID](https://developers.cloudflare.com/workers-ai/get-started/rest-api/#1-get-api-token-and-account-id) |
#### 星火 (Spark)
@@ -237,7 +231,7 @@ Cloudflare Workers AI 所对应的 `type` 为 `cloudflare`。它特有的配置
Gemini 所对应的 `type``gemini`。它特有的配置字段如下:
| 名称 | 数据类型 | 填写要求 | 默认值 | 描述 |
| --------------------- | -------- | -------- |-----|-------------------------------------------------------------------------------------------------|
| --------------------- | ------------- | -------- | ------ | -------------------------------------------------------------------------------------------------------------- |
| `geminiSafetySetting` | map of string | 非必填 | - | Gemini AI 内容过滤和安全级别设定。参考[Safety settings](https://ai.google.dev/gemini-api/docs/safety-settings) |
#### DeepL
@@ -253,19 +247,20 @@ DeepL 所对应的 `type` 为 `deepl`。它特有的配置字段如下:
Cohere 所对应的 `type``cohere`。它并无特有的配置字段。
#### Together-AI
Together-AI 所对应的 `type``together-ai`。它并无特有的配置字段。
#### Dify
Dify 所对应的 `type``dify`。它特有的配置字段如下:
| 名称 | 数据类型 | 填写要求 | 默认值 | 描述 |
| -- | -------- |------| ------ | ---------------------------- |
| ---------------- | -------- | -------- | ------ | -------------------------------------------------------------------------------- |
| `difyApiUrl` | string | 非必填 | - | dify 私有化部署的 url |
| `botType` | string | 非必填 | - | dify 的应用类型Chat/Completion/Agent/Workflow |
| `inputVariable` | string | 非必填 | - | dify 中应用类型为 workflow 时需要设置输入变量,当 botType 为 workflow 时一起使用 |
| `outputVariable` | string | 非必填 | - | dify 中应用类型为 workflow 时需要设置输出变量,当 botType 为 workflow 时一起使用 |
## 用法示例
### 使用 OpenAI 协议代理 Azure OpenAI 服务
@@ -376,20 +371,20 @@ provider:
provider:
type: qwen
apiTokens:
- "YOUR_QWEN_API_TOKEN"
- 'YOUR_QWEN_API_TOKEN'
modelMapping:
'gpt-3': "qwen-turbo"
'gpt-35-turbo': "qwen-plus"
'gpt-4-turbo': "qwen-max"
'gpt-4-*': "qwen-max"
'gpt-4o': "qwen-vl-plus"
'gpt-3': 'qwen-turbo'
'gpt-35-turbo': 'qwen-plus'
'gpt-4-turbo': 'qwen-max'
'gpt-4-*': 'qwen-max'
'gpt-4o': 'qwen-vl-plus'
'text-embedding-v1': 'text-embedding-v1'
'*': "qwen-turbo"
'*': 'qwen-turbo'
```
**AI 对话请求示例**
URL: http://your-domain/v1/chat/completions
URL: <http://your-domain/v1/chat/completions>
请求示例:
@@ -434,7 +429,7 @@ URL: http://your-domain/v1/chat/completions
**多模态模型 API 请求示例(适用于 `qwen-vl-plus` 和 `qwen-vl-max` 模型)**
URL: http://your-domain/v1/chat/completions
URL: <http://your-domain/v1/chat/completions>
请求示例:
@@ -493,7 +488,7 @@ URL: http://your-domain/v1/chat/completions
**文本向量请求示例**
URL: http://your-domain/v1/embeddings
URL: <http://your-domain/v1/embeddings>
请求示例:
@@ -606,12 +601,12 @@ provider:
provider:
type: qwen
apiTokens:
- "YOUR_QWEN_API_TOKEN"
- 'YOUR_QWEN_API_TOKEN'
modelMapping:
"*": "qwen-long" # 通义千问的文件上下文只能在 qwen-long 模型下使用
'*': 'qwen-long' # 通义千问的文件上下文只能在 qwen-long 模型下使用
qwenFileIds:
- "file-fe-xxx"
- "file-fe-yyy"
- 'file-fe-xxx'
- 'file-fe-yyy'
```
**请求示例**
@@ -661,11 +656,12 @@ provider:
provider:
type: qwen
apiTokens:
- "YOUR_DASHSCOPE_API_TOKEN"
- 'YOUR_DASHSCOPE_API_TOKEN'
protocol: original
```
**请求实例**
```json
{
"input": {
@@ -789,7 +785,7 @@ provider:
provider:
type: groq
apiTokens:
- "YOUR_GROQ_API_TOKEN"
- 'YOUR_GROQ_API_TOKEN'
```
**请求示例**
@@ -848,8 +844,8 @@ provider:
provider:
type: claude
apiTokens:
- "YOUR_CLAUDE_API_TOKEN"
version: "2023-06-01"
- 'YOUR_CLAUDE_API_TOKEN'
version: '2023-06-01'
```
**请求示例**
@@ -899,14 +895,14 @@ provider:
```yaml
provider:
type: "hunyuan"
hunyuanAuthKey: "<YOUR AUTH KEY>"
type: 'hunyuan'
hunyuanAuthKey: '<YOUR AUTH KEY>'
apiTokens:
- ""
hunyuanAuthId: "<YOUR AUTH ID>"
- ''
hunyuanAuthId: '<YOUR AUTH ID>'
timeout: 1200000
modelMapping:
"*": "hunyuan-lite"
'*': 'hunyuan-lite'
```
**请求示例**
@@ -967,10 +963,10 @@ curl --location 'http://<your higress domain>/v1/chat/completions' \
provider:
type: baidu
apiTokens:
- "YOUR_BAIDU_API_TOKEN"
- 'YOUR_BAIDU_API_TOKEN'
modelMapping:
'gpt-3': "ERNIE-4.0"
'*': "ERNIE-4.0"
'gpt-3': 'ERNIE-4.0'
'*': 'ERNIE-4.0'
```
**请求示例**
@@ -1022,11 +1018,11 @@ provider:
provider:
type: minimax
apiTokens:
- "YOUR_MINIMAX_API_TOKEN"
- 'YOUR_MINIMAX_API_TOKEN'
modelMapping:
"gpt-3": "abab6.5s-chat"
"gpt-4": "abab6.5g-chat"
"*": "abab6.5t-chat"
'gpt-3': 'abab6.5s-chat'
'gpt-4': 'abab6.5g-chat'
'*': 'abab6.5t-chat'
```
**请求示例**
@@ -1090,12 +1086,12 @@ provider:
provider:
type: github
apiTokens:
- "YOUR_GITHUB_ACCESS_TOKEN"
- 'YOUR_GITHUB_ACCESS_TOKEN'
modelMapping:
"gpt-4o": "gpt-4o"
"gpt-4": "Phi-3.5-MoE-instruct"
"gpt-3.5": "cohere-command-r-08-2024"
"text-embedding-3-large": "text-embedding-3-large"
'gpt-4o': 'gpt-4o'
'gpt-4': 'Phi-3.5-MoE-instruct'
'gpt-3.5': 'cohere-command-r-08-2024'
'text-embedding-3-large': 'text-embedding-3-large'
```
**请求示例**
@@ -1121,6 +1117,7 @@ provider:
```
**响应示例**
```json
{
"choices": [
@@ -1191,13 +1188,13 @@ provider:
provider:
type: ai360
apiTokens:
- "YOUR_360_API_TOKEN"
- 'YOUR_360_API_TOKEN'
modelMapping:
"gpt-4o": "360gpt-turbo-responsibility-8k"
"gpt-4": "360gpt2-pro"
"gpt-3.5": "360gpt-turbo"
"text-embedding-3-small": "embedding_s1_v1.2"
"*": "360gpt-pro"
'gpt-4o': '360gpt-turbo-responsibility-8k'
'gpt-4': '360gpt2-pro'
'gpt-3.5': '360gpt-turbo'
'text-embedding-3-small': 'embedding_s1_v1.2'
'*': '360gpt-pro'
```
**请求示例**
@@ -1257,7 +1254,7 @@ provider:
**文本向量请求示例**
URL: http://your-domain/v1/embeddings
URL: <http://your-domain/v1/embeddings>
请求示例:
@@ -1305,10 +1302,10 @@ URL: http://your-domain/v1/embeddings
provider:
type: cloudflare
apiTokens:
- "YOUR_WORKERS_AI_API_TOKEN"
cloudflareAccountId: "YOUR_CLOUDFLARE_ACCOUNT_ID"
- 'YOUR_WORKERS_AI_API_TOKEN'
cloudflareAccountId: 'YOUR_CLOUDFLARE_ACCOUNT_ID'
modelMapping:
"*": "@cf/meta/llama-3-8b-instruct"
'*': '@cf/meta/llama-3-8b-instruct'
```
**请求示例**
@@ -1356,11 +1353,11 @@ provider:
provider:
type: spark
apiTokens:
- "APIKey:APISecret"
- 'APIKey:APISecret'
modelMapping:
"gpt-4o": "generalv3.5"
"gpt-4": "generalv3"
"*": "general"
'gpt-4o': 'generalv3.5'
'gpt-4': 'generalv3'
'*': 'general'
```
**请求示例**
@@ -1474,8 +1471,8 @@ provider:
provider:
type: deepl
apiTokens:
- "YOUR_DEEPL_API_TOKEN"
targetLang: "ZH"
- 'YOUR_DEEPL_API_TOKEN'
targetLang: 'ZH'
```
**请求示例**
@@ -1500,6 +1497,7 @@ provider:
```
**响应示例**
```json
{
"choices": [
@@ -1522,16 +1520,18 @@ provider:
### 使用 OpenAI 协议代理 Together-AI 服务
**配置信息**
```yaml
provider:
type: together-ai
apiTokens:
- "YOUR_TOGETHER_AI_API_TOKEN"
- 'YOUR_TOGETHER_AI_API_TOKEN'
modelMapping:
"*": "Qwen/Qwen2.5-72B-Instruct-Turbo"
'*': 'Qwen/Qwen2.5-72B-Instruct-Turbo'
```
**请求示例**
```json
{
"model": "Qwen/Qwen2.5-72B-Instruct-Turbo",
@@ -1545,6 +1545,7 @@ provider:
```
**响应示例**
```json
{
"id": "8f5809d54b73efac",
@@ -1576,16 +1577,18 @@ provider:
### 使用 OpenAI 协议代理 Dify 服务
**配置信息**
```yaml
provider:
type: dify
apiTokens:
- "YOUR_DIFY_API_TOKEN"
- 'YOUR_DIFY_API_TOKEN'
modelMapping:
"*": "dify"
'*': 'dify'
```
**请求示例**
```json
{
"model": "gpt-4-turbo",
@@ -1600,6 +1603,7 @@ provider:
```
**响应示例**
```json
{
"id": "e33fc636-f9e8-4fae-8d5e-fbd0acb09401",
@@ -1624,7 +1628,6 @@ provider:
}
```
## 完整配置示例
### Kubernetes 示例
@@ -1643,7 +1646,7 @@ spec:
provider:
type: groq
apiTokens:
- "YOUR_API_TOKEN"
- 'YOUR_API_TOKEN'
ingress:
- groq
url: oci://higress-registry.cn-hangzhou.cr.aliyuncs.com/plugins/ai-proxy:1.0.0
@@ -1655,7 +1658,7 @@ metadata:
higress.io/backend-protocol: HTTPS
higress.io/destination: groq.dns
higress.io/proxy-ssl-name: api.groq.com
higress.io/proxy-ssl-server-name: "on"
higress.io/proxy-ssl-server-name: 'on'
labels:
higress.io/resource-definer: higress
name: groq
@@ -1716,7 +1719,7 @@ services:
networks:
- higress-net
ports:
- "10000:10000"
- '10000:10000'
volumes:
- ./envoy.yaml:/etc/envoy/envoy.yaml
- ./plugin.wasm:/etc/envoy/plugin.wasm
@@ -1745,7 +1748,7 @@ static_resources:
- filters:
- name: envoy.filters.network.http_connection_manager
typed_config:
"@type": type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager
'@type': type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager
scheme_header_transformation:
scheme_to_overwrite: https
stat_prefix: ingress_http
@@ -1753,23 +1756,23 @@ static_resources:
access_log:
- name: envoy.access_loggers.stdout
typed_config:
"@type": type.googleapis.com/envoy.extensions.access_loggers.stream.v3.StdoutAccessLog
'@type': type.googleapis.com/envoy.extensions.access_loggers.stream.v3.StdoutAccessLog
# Modify as required
route_config:
name: local_route
virtual_hosts:
- name: local_service
domains: [ "*" ]
domains: ['*']
routes:
- match:
prefix: "/"
prefix: '/'
route:
cluster: claude
timeout: 300s
http_filters:
- name: claude
typed_config:
"@type": type.googleapis.com/udpa.type.v1.TypedStruct
'@type': type.googleapis.com/udpa.type.v1.TypedStruct
type_url: type.googleapis.com/envoy.extensions.filters.http.wasm.v3.Wasm
value:
config:
@@ -1780,7 +1783,7 @@ static_resources:
local:
filename: /etc/envoy/plugin.wasm
configuration:
"@type": "type.googleapis.com/google.protobuf.StringValue"
'@type': 'type.googleapis.com/google.protobuf.StringValue'
value: | # 插件配置
{
"provider": {
@@ -1809,8 +1812,8 @@ static_resources:
transport_socket:
name: envoy.transport_sockets.tls
typed_config:
"@type": type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext
"sni": "api.anthropic.com"
'@type': type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext
'sni': 'api.anthropic.com'
```
访问示例:

View File

@@ -5,6 +5,7 @@ import (
"errors"
"math/rand"
"net/http"
"regexp"
"strings"
"github.com/alibaba/higress/plugins/wasm-go/extensions/ai-proxy/util"
@@ -614,9 +615,10 @@ func doGetMappedModel(model string, modelMapping map[string]string) string {
}
for k, v := range modelMapping {
if k == wildcard || !strings.HasSuffix(k, wildcard) {
if k == wildcard {
continue
}
if strings.HasSuffix(k, wildcard) {
k = strings.TrimSuffix(k, wildcard)
if strings.HasPrefix(model, k) {
log.Debugf("model [%s] is mapped to [%s] via prefix [%s]", model, v, k)
@@ -624,6 +626,17 @@ func doGetMappedModel(model string, modelMapping map[string]string) string {
}
}
if strings.HasPrefix(k, "~") {
k = strings.TrimPrefix(k, "~")
re := regexp.MustCompile(k)
if re.MatchString(model) {
v = re.ReplaceAllString(model, v)
log.Debugf("model [%s] is mapped to [%s] via regex [%s]", model, v, k)
return v
}
}
}
if v, ok := modelMapping[wildcard]; ok {
log.Debugf("model [%s] is mapped to [%s] via wildcard", model, v)
return v