AiRelay
LLM relay 어댑터 — OpenAI-compatible 호출 + 응답 정규화 (LiteLLM 호환, Chorus 제외)
상태
| 항목 | 값 |
|---|---|
| Layer | core |
| Tier | L1 |
| Status | released |
| Version | 1.0.0 |
| 가격 | Free (free) |
| 카테고리 | AI / LLM |
개요
개요
AiRelay 는 multi-saas-kit 의 Layer 1 Core Plugin 입니다. apis.how 의 External-First 원칙(/api/v1/edge/... mint → relay 단일 흐름)에 따라 OpenAI-compatible LLM 호출 어댑터를 표준화한 plugin.
LiteLLM 을 LLM control plane 으로, virtual key + model alias 사용. apis.how 는 자체 LLM 을 재구현하지 않고 운영 정책/토큰 관리/문서화/확장 레이어에 집중.
범위 경계: Chorus 는 로컬 또는 서버에 설치된 AI Agent CLI 를 subprocess 로 실행하는 orchestration 계층이므로 AiRelay 범위가 아닙니다. Chorus 통합은 별도 AgentCliBridge/ChorusBridge plugin 책임입니다.
핵심 컴포넌트
TextContentExtractor (Pure)
OpenAI-compatible chat completion payload 에서 text 추출. apis.how LlmApiRelayClient::extractText 추출.
두 가지 shape 지원:
choices[0].message.content = "string"choices[0].message.content = [{type:'text', text:'...'}, ...](multi-part)
image 등 비-text 항목은 자동 skip.
RelayResponseNormalizer (Pure)
LLM relay 응답 표준화 — apis.how 의 표준 shape 으로 변환:
success: { status: 'success', data: { text, model, usage, raw }, relay_meta: {...} }
error: { status: 'error', error: { code, message, http_status }, relay_meta: {...} }
relay_meta — mode, relay_elapsed_ms, upstream_http_status. 호출자가 audit log / 사용량 분석에 활용.
HTTP 4xx/5xx 자동 감지, error payload 에서 error.code / error.message 추출.
LlmRelayClient
OpenAI-compatible LLM relay 클라이언트.
complete($payload)—/v1/chat/completionsPOST + 정규화된 표준 응답 반환- 인증:
Authorization: Bearer {api_key}+x-litellm-api-key동시 헤더 (LiteLLM 호환) apiKey미설정 →AiRelayNotConfiguredException- 네트워크 예외 →
error.code = 'llm_relay_exception'안전 fallback - 후행 슬래시 base_url 자동 정규화
env 다중 후보 fallback (apis.how 의 resolveApiKey 패턴) 은 caller 책임으로 분리. 본 client 는 명시적 base_url + api_key 만 받음.
설정 (config/ai-relay.php)
return [
'enabled' => env('PLG_AI_RELAY_ENABLED', true),
'litellm' => [
'base_url' => env('LITELLM_BASE_URL', 'https://llm.apis.how'),
'api_key' => env('LITELLM_API_KEY'),
'completion_path' => '/v1/chat/completions',
'timeout_seconds' => 60,
],
'response_mode' => 'server_relay_llm',
];
사용 예시
use App\Plugins\AiRelay\Services\LlmRelayClient;
$client = LlmRelayClient::fromConfig(config('ai-relay'));
$result = $client->complete([
'model' => 'gpt-4o-mini',
'messages' => [
['role' => 'user', 'content' => '안녕하세요'],
],
]);
if ($result['status'] === 'success') {
return $result['data']['text']; // '안녕하세요!'
} else {
Log::warning('LLM relay failed', $result['error']);
}
// usage 정보는 호출 프로젝트의 metering/pricing 레이어가 소비
$usage = $result['data']['usage']; // ['prompt_tokens' => 10, 'completion_tokens' => 5]
출처
apis.how LlmApiRelayClient (174줄) 추출. env 다중 후보 resolution 부분은 프로젝트 책임으로 분리하고, 순수 호출 + 응답 정규화 만 plugin 으로 분리.
apis.how External-First 원칙
[모든 호출자]
↓
POST /api/v1/edge/{service}/sessions ← 공통 mint endpoint (Bearer 장기 키)
↓
← 단기 JWT (Ed25519, 3분)
↓
POST relay.apis.how/v1/{service}/{endpoint} ← 공통 relay (단기 JWT)
본 plugin 은 relay 부분의 표준 어댑터.
도매 단가 조회 (재과금용)
apis.how API 사용료를 회원에게 재과금하려면 우리 계약 단가를 알아야 합니다. 그 값을 요금표에 복제해 두면 공급자가 단가를 바꿀 때 조용히 틀린 금액을 청구하게 되므로, 필요할 때 공급자에게 물어봅니다.
운영자가 준비할 것 (둘 다 필요)
| # | 항목 | 없으면 |
|---|---|---|
| 1 | apis.how 측 우리 계약 요금표 항목 | 조회 거부 — 임의 단가로 답하지 않습니다 |
| 2 | 사용 중인 API 토큰에 billing:read 권한 | 조회 거부 |
billing:read 는 apis.how 토큰 편집 화면의 허용 동작 목록에서 체크합니다.
전용 토큰을 새로 발급할 필요는 없습니다 — 이미 쓰는 토큰에 권한만 추가하면 됩니다.
조회 결과에 "전용 단가 아님" 표시가 계속 나온다면 그 고객사 전용 요금표 가 아직 없다는 신호입니다.
이 조회는 과금하지 않습니다(읽기). 사용량 대시보드에 나타나지 않습니다.
자세한 사용법은 UsageMetering (사용량 과금) 문서를 참고하십시오.
다른 Plugin 과의 관계
- PromptTemplating (선택) — 시스템 프롬프트 합성 후
messages구성 - 프로젝트 고유 metering/pricing 레이어 —
data.usage를 기반으로 비용 계산 (apis.how등) - AiTracking (Phase 2) — 호출 이력 / 비용 / latency 기록
다음 단계 (Phase 3+)
- Streaming 지원 (
/v1/chat/completionsSSE) - Speech relay (apis.how
SpeechApiRelayClient) 통합 - EdgeRelay JWT 자동 mint + relay (
/api/v1/edge/...두 단계 통합) - OpenAI-compatible gateway 어댑터 추가 (LiteLLM-compatible 계열)
- Chorus/Agent CLI 실행은 별도 AgentCliBridge/ChorusBridge plugin 책임
- AiTracking plugin 자동 hook (호출 이력 자동 기록)
라이선스
MIT
의존성
- PromptTemplating (optional)
데모
- Platform 관리자 패널에서 메타 확인 🔒 로그인 필요
- 사용 예시 (PHP)
🛒 Plugin Store에서 보기: store.codebase.how/plugins/ai-relay