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 부분의 표준 어댑터.
다른 Plugin 과의 관계
- PromptTemplating (선택) — 시스�
� 프롬프트 합성 후
messages구성 - 프로젝트 고유 metering/pricing 레이어 —
data.usage를 기반으로 비용 계산 (apis.how등) - AiTracking (Phase 2) — 호출 이력 / 비용 / latency 기록