Openrouter 사용기 - 1
지난 글에서는 모델 리스트만 뽑고 끝이 났습니다.
이번 글에서는, 여러 모델들을 가지고 채팅 컨텍스트가 유연하게 유지되는지 테스트 해보려고 합니다.
가장 중요하게 생각하는 기능이기에, 글을 쓰면서도 이 글이 마지막 글이 될까봐 벌써 겁이 나기 시작하네요.
일단 아래와 같은 두가지의 free 모델을 사용해 보았는데,
error: {
message: 'Provider returned error',
code: 429,
metadata: {
raw: 'google/gemini-2.0-flash-exp:free is temporarily rate-limited upstream. Please retry shortly, or add your own key to accumulate your rate limits: https://openrouter.ai/settings/integrations',
provider_name: 'Google'
}
},
자꾸 429 에러가 나오네요. 몇 번 더 시도해보았는데,
error: {
message: 'Provider returned error',
code: 429,
metadata: {
raw: 'google/gemini-2.0-flash-exp:free is temporarily rate-limited upstream. Please retry shortly, or add your own key to accumulate your rate limits: https://openrouter.ai/settings/integrations',
provider_name: 'Google'
}
},
이번엔 Provider(Openrouter) 측에서 거절했습니다.
OpenRouter 가격 정책이 아래와 같기 때문입니다.
무료 사용 제한 (Free Usage Limits)
만약 무료 모델 버전(ID가 **:free**로 끝나는 모델)을 사용 중이라면, 다음과 같은 제한이 적용됩니다.
- 분당 제한: 분당 최대 20건의 요청을 할 수 있습니다.
- 일일 제한: 일일 요청 횟수는 보유한 크레딧(credits) 양에 따라 달라집니다.
- 10 크레딧 미만 구매 시: 하루에 :free 모델 요청을 50건으로 제한합니다.
- 10 크레딧 이상 구매 시: 일일 제한이 1,000건의 :free 모델 요청으로 증가합니다.
쓰고자만 한다면 금방 쓸 것 같으므로, 10크레딧 (10달러 + 수수료 0.8)을 결제했습니다.
그 이후, 아주 간단한 코드를 바이브코딩으로 만들어서, 터미널에서 동작하는 챗봇을 만들어봤습니다.
홀수번은 gemini가 응답을 하고, 짝수번은 gpt가 응답을 합니다.
import dotenv from "dotenv";
import OpenAI from "openai";
import * as readline from "readline";
import type { ChatCompletionMessageParam } from "openai/resources/chat/completions";
dotenv.config();
const client = new OpenAI({
baseURL: "https://openrouter.ai/api/v1",
apiKey: process.env.OPENROUTER_API_KEY,
});
async function interactiveChat() {
const models = ["google/gemini-2.5-flash-lite", "openai/gpt-4o-mini"];
const rl = readline.createInterface({
input: process.stdin,
output: process.stdout,
});
// 채팅 컨텍스트를 유지하는 전역 messages 배열
const messages: ChatCompletionMessageParam[] = [
{ role: "system", content: "당신은 까칠한 챗봇입니다." },
];
let callCount = 0;
function askQuestion(): void {
rl.question(
"\n메시지를 입력하세요 (종료하려면 'exit' 입력): ",
async (input) => {
if (input.toLowerCase() === "exit") {
console.log("\n대화를 종료합니다.");
rl.close();
return;
}
callCount++;
const modelIndex = callCount % 2 === 1 ? 0 : 1; // 홀수: gemini(0), 짝수: gpt(1)
const model = models[modelIndex];
console.log(`\n--- Call ${callCount}: ${model} ---`);
try {
// 현재 시간을 포함한 시스템 메시지 추가
const timestamp = Date.now();
messages.push({
role: "system",
content: `Current timestamp: ${timestamp}. Please consider the current time when responding.`,
});
// 사용자 메시지를 추가
messages.push({ role: "user", content: input });
const response = await client.chat.completions.create({
model: model,
messages: messages,
max_tokens: 100,
});
console.log("response:", response);
const responseContent = response.choices[0]?.message?.content;
console.log(response.choices[0].message);
console.log("Response:", responseContent);
// 모델 응답을 messages에 추가
if (responseContent) {
messages.push({ role: "assistant", content: responseContent });
}
} catch (error) {
console.error("Error:", error);
}
askQuestion(); // 다음 입력 받기
}
);
}
console.log("OpenRouter 챗봇 시작!");
console.log("홀수 번째 호출: Gemini");
console.log("짝수 번째 호출: GPT");
askQuestion();
}
interactiveChat();
응답 속도 자체는 굉장히 만족스러웠습니다. 오버헤드 시간이 좀 더 있을줄 알았는데. 기분 탓인지 모르겠지만 응답 속도가 미묘하게 빠른 느낌..? 가장 빠른 응답을 제공하는 라우팅 기능을 제공한다고 하는데, 나중에 가능하면 직접 시간을 비교해볼 필요도 있을 것 같습니다.
기존 gemini를 GenAI SDK로 사용할 때, 중간에 role: system 프롬프트를 넣을 수 없었습니다.
또한 모델 응답의 role 이름이 SDK마다 달랐습니다. OpenAI SDK는 assistant, GenAI SDK는 model을 사용해야 했습니다.
GenAI SDK는 메시지 포맷도 달랐습니다. 아래 형식이어야 합니다.
{"role": "<role>", "parts": [{"text": "content"}]}
그래서 파싱 코드를 별도로 작성했습니다.
또한 text가 빈 문자열이면 거절되는 경우가 있어, 플레이스홀더를 넣어야 했습니다.
(기존 프로젝트에 있던 코드라 python입니다)
history = []
for msg in request:
role = "model" if msg["role"] == "assistant" else "user"
if msg["content"] == "":
msg["content"] = "None"
history.append({"role": role, "parts": [{"text": msg["content"]}]})
Google 측에서 OpenAI SDK를 공식적으로 지원하긴 하지만, 지원이 그리 잘 되는 것 같지 않고 baseurl이 다른 client를 여러개 지정해두고 각자 로깅과 폴백을 걸어줘야 하기에, 그리고 앞으로 테스트 해봐야할 모델이 많기 때문에.... 좀 더 사용해볼 가치가 있을 것 같습니다.
첫 테스트는 이정도면 만족스러운 것 같고, 이 다음에는 perplexity API와, deepseek free API를 사용해보고, 챗봇 개발 후 운영시에 문제가 생겼던 부분들을 테스트 해보려고 합니다.