AI Gateway multiple providers
Mix.install([
{:kino, "~> 0.14"},
{:req, "~> 0.4"}
])
認証情報の設定
以下の値を Secrets に登録する
- OPENAI_API_KEY: OpenAI の API キー
- GEMINI_API_KEY: Google Gemini の API キー
- CF_ACCOUNT_ID: Cloudfaler のアカウントID
- WORKERS_AI_API_KEY: Workers AI の API キー
OpenAI API の直接呼出
openai_api_key = System.get_env("LB_OPENAI_API_KEY")
openai_base_url = "https://api.openai.com/v1/chat/completions"
openai_model_id = "gpt-4o-mini"
openai_headers = %{
"Content-Type" => "application/json",
"Authorization" => "Bearer #{openai_api_key}"
}
request_body = %{
model: openai_model_id,
messages: [
%{
role: "system",
content: "You are a helpful assistant."
},
%{
role: "user",
content: "あんパンとカレーパンはどちらが人気ですか"
}
]
}
response =
"#{openai_base_url}"
|> Req.post!(json: request_body, headers: openai_headers)
|> Map.get(:body)
response["choices"]
|> Enum.at(0)
|> Map.get("message")
|> Map.get("content")
|> Kino.Markdown.new()
Google Gemini API の直接呼出
gemini_api_key = System.get_env("LB_GEMINI_API_KEY")
gemini_base_url = "https://generativelanguage.googleapis.com/v1beta/models"
gemini_model_id = "gemini-1.5-flash-latest"
gemini_headers = %{
"Content-Type" => "application/json"
}
request_body = %{
contents: [
%{
parts: [
%{
text: "日本で最も人気のあるパンは何ですか"
}
]
}
]
}
response =
"#{gemini_base_url}/#{gemini_model_id}:generateContent?key=#{gemini_api_key}"
|> Req.post!(json: request_body, headers: gemini_headers)
|> Map.get(:body)
response["candidates"]
|> Enum.at(0)
|> Map.get("content")
|> Map.get("parts")
|> Enum.at(0)
|> Map.get("text")
|> Kino.Markdown.new()
Workers AI の直接呼出
cf_account_id = System.get_env("LB_CF_ACCOUNT_ID")
workers_ai_api_key = System.get_env("LB_WORKERS_AI_API_KEY")
workers_ai_base_url = "https://api.cloudflare.com/client/v4/"
workers_ai_model_id = "llama-3.1-8b-instruct"
workers_ai_headers = %{
"Content-Type" => "application/json",
"Authorization" => "Bearer #{workers_ai_api_key}"
}
request_body = %{
messages: [
%{
role: "system",
content: "あなたは優秀なAIアシスタントです。日本語で簡潔に質問に回答してください"
},
%{
role: "user",
content: "食パンの一番美味しいところはどこですか"
}
]
}
response =
"#{workers_ai_base_url}/accounts/#{cf_account_id}/ai/run/@cf/meta/#{workers_ai_model_id}"
|> Req.post!(json: request_body, headers: workers_ai_headers)
|> Map.get(:body)
response["result"]["response"]
|> Kino.Markdown.new()
AI Gateway からの呼出
cf_gateway_name_input = Kino.Input.text("CLOUDFLARE GATEWAY_NAME")
cf_gateway_name = Kino.Input.read(cf_gateway_name_input)
cf_host = "gateway.ai.cloudflare.com"
gw_url =
"https://#{cf_host}/v1/#{cf_account_id}/#{cf_gateway_name}"
gw_headers = %{
"Content-Type" => "application/json"
}
question = "コロネはどこから食べるべきですか"
openai_request_body = %{
provider: "openai",
endpoint: "chat/completions",
headers: openai_headers,
query: %{
model: openai_model_id,
messages: [
%{role: "system", content: "You are a helpful assistant."},
%{role: "user", content: question}
]
}
}
gemini_request_body = %{
provider: "google-ai-studio",
endpoint: "v1beta/models/#{gemini_model_id}:generateContent?key=#{gemini_api_key}",
headers: gemini_headers,
query: %{
contents: [%{parts: [%{text: question}]}]
}
}
workers_request_body = %{
provider: "workers-ai",
endpoint: "@cf/meta/#{workers_ai_model_id}",
headers: workers_ai_headers,
query: %{
messages: [
%{role: "system", content: "あなたは優秀なAIアシスタントです。日本語で簡潔に質問に回答してください"},
%{role: "user", content: question}
]
}
}
request_body = [
openai_request_body,
gemini_request_body,
workers_request_body
]
response =
gw_url
|> Req.post!(json: request_body, headers: gw_headers)
|> Map.get(:body)
request_body = [
gemini_request_body,
workers_request_body,
openai_request_body
]
response =
gw_url
|> Req.post!(json: request_body, headers: gw_headers)
|> Map.get(:body)
request_body = [
workers_request_body,
openai_request_body,
gemini_request_body
]
response =
gw_url
|> Req.post!(json: request_body, headers: gw_headers)
|> Map.get(:body)
認証エラーを発生させる
# 認証キーをリクエストから外す
request_body = [
%{
provider: "google-ai-studio",
endpoint: "v1beta/models/#{gemini_model_id}:generateContent",
headers: gemini_headers,
query: %{
contents: [%{parts: [%{text: question}]}]
}
},
workers_request_body,
openai_request_body
]
response =
gw_url
|> Req.post!(json: request_body, headers: gw_headers)
|> Map.get(:body)
キャッシュ
AI Gateway でキャッシュを有効にしてから2回実行する
request_body = [
openai_request_body,
gemini_request_body,
workers_request_body
]
response =
gw_url
|> Req.post!(json: request_body, headers: gw_headers)
|> Map.get(:body)
レート制限
AI Gateway で1分間のレート制限を3回にしてから5回実行する
1..5
|> Enum.map(fn index ->
request_body = [
%{
provider: "openai",
endpoint: "chat/completions",
headers: openai_headers,
query: %{
model: openai_model_id,
messages: [
%{role: "system", content: "You are a helpful assistant."},
%{role: "user", content: "#{index}といえば、何を表す数字ですか"}
]
}
}
]
gw_url
|> Req.post!(json: request_body, headers: gw_headers)
|> Map.get(:body)
end)