Aimeos Prisma 0.5: AI 제공업체를 위한 더 견고한 PHP 레이어
요약
Aimeos Prisma 0.5는 다양한 AI 제공업체의 API를 단일 인터페이스로 통합하는 PHP 라이브러리입니다. 텍스트, 이미지, 오디오 등 멀티모달 기능을 지원하며 스트리밍 응답과 대화 기록 관리 기능을 강화했습니다.
핵심 포인트
- 다양한 AI 제공업체를 위한 단일 PHP API 제공
- 스트리밍 응답(stream)을 핵심 API로 통합 지원
- 프레임워크에 구애받지 않는 PHP 8.2+ 패키지
- 대화 기록 및 강력한 스키마 지원 기능 추가
대부분의 AI 통합은 첫 번째 제공업체(provider)를 호출하는 것이 어려워서 실패하는 것이 아닙니다. 애플리케이션이 동시에 여러 방언을 구사해야 하는 상황이 닥쳤을 때 비로소 어색해지기 시작합니다.
어떤 엔드포인트는 텍스트를 생성합니다. 다른 엔드포인트는 임베딩 (embeddings)을 반환합니다. 세 번째는 전사 (transcription)를 처리합니다. 이미지 생성은 그 자체의 페이로드 형태 (payload shape), 고유한 에러, 그리고 고유한 메타데이터 (metadata) 개념을 가지고 등장합니다. 웹 검색, 도구 호출 (tool calling), 로컬 모델 (local models), 또는 OpenAI 호환 게이트웨이 (OpenAI-compatible gateway)를 추가하다 보면, 유용한 애플리케이션 코드가 제공업체의 배관 작업 (provider plumbing) 뒤로 사라지기 시작합니다.
Aimeos Prisma는 그 경계를 작게 유지하기 위해 존재합니다. 이는 PHP 애플리케이션에 텍스트, 이미지, 오디오, 비디오 제공업체를 아우르는 단일 API를 제공하면서도, 필요한 경우에는 제공업체별 옵션을 사용할 수 있는 여지를 남겨둡니다.
0.5 릴리스는 해당 레이어를 실제 애플리케이션에 더 적합하게 만듭니다: 스트리밍 응답 (streamed responses), 대화 기록 (conversation history), 더 강력한 스키마 (schema) 지원, 요청 관찰 (request observation), 더 나은 테스트 더블 (test doubles), 더 안전한 응답 처리, 그리고 더 많은 제공업체 커버리지 등이 포함됩니다.
composer require aimeos/prisma
API 형태 (The API shape)
Prisma는 프레임워크에 구애받지 않는 (framework-agnostic) PHP 8.2+ 패키지입니다. MIT 라이선스를 따르며, 내부적으로 Guzzle을 사용하고, 제공업체 유형 전반에 걸쳐 호출 패턴을 일관되게 유지합니다.
use Aimeos\
Prisma\
Prisma;
$text = Prisma::text()
...
제공업체 이름은 바뀌지만, 이를 둘러싼 애플리케이션의 형태는 바뀌지 않습니다.
스트리밍은 핵심 API에 속해야 합니다
사용자 대상 도구의 경우, 전체 모델 응답을 기다리는 것은 종종 잘못된 상호작용입니다. Prisma 0.5는 스트리밍을 별도의 통합 경로로 취급하는 대신, 텍스트 기능으로서 stream()을 추가했습니다.
use Aimeos\
Prisma\
Prisma;
$response = Prisma::text()
...
스트리밍은 write()와 동일한 구성 인터페이스를 유지합니다: 모델 선택, 시스템 프롬프트 (system prompts), 도구 (tools), 이전 메시지, 그리고 제공업체 옵션이 모두 동일한 제공업체 객체를 통해 전달됩니다.
Laravel에서는 이를 response()->eventStream()에 직접 전달할 수 있습니다:
use Aimeos\
Prisma\
Prisma;
use Illuminate\
Support\
Facades\
Route;
...
한 가지 운영 규칙이 있습니다: 본문(body)에서 파생된 메타데이터를 읽기 전에 스트림(stream)을 먼저 소비해야 합니다. 사용법(Usage), 인용(citations), 도구 단계(tool steps), 종료 사유(finish reason), 그리고 응답 메타데이터(response metadata)는 스트림이 모두 비워진 후에야 완성됩니다. 헤더(headers)에서 가져오는 속도 제한(Rate-limit) 데이터는 즉시 사용할 수 있습니다.
두 번째 추상화 없는 대화 기록 (Conversation history)
대화 기록(Chat history)은 이제 withMessages()에 저장됩니다. write(), stream(), 또는 structure()에 전달되는 현재 프롬프트(prompt)가 다음 사용자 턴(user turn)이 됩니다.
use Aimeos\Prisma\Prisma;
$response = Prisma::text()
...
멀티모달(multimodal) 제공업체의 경우, 각 제공업체의 파일 지원 여부에 따라 사용자 턴에 파일을 포함할 수도 있습니다.
구조화된 출력(Structured output): 가능할 때는 더 엄격하게, 불가능할 때는 명시적으로
구조화된 출력(Structured output)은 코드가 기대하는 바를 명시하고 받은 내용을 확인할 수 있을 때 가장 유용합니다. Prisma 0.5는 이 양면을 모두 개선했습니다.
use Aimeos\Prisma\Prisma;
use Aimeos\Prisma\Schema\Schema;
...
기본적으로 Prisma는 제공업체의 네이티브 구조화된 출력(native structured-output) 모드가 존재하는 경우 이를 사용합니다. 만약 스키마(schema)가 해당 모드를 사용하기에 너무 크거나 계층 구조가 너무 깊다면, ['mode' => 'json']을 전달하십시오. 그러면 Prisma가 프롬프트에 스키마를 포함시키고 반환된 JSON을 파싱합니다.
$response = Prisma::text()
->using('openai', ['api_key' => getenv('OPENAI_API_KEY')])
->structure('Extract a support ticket', $schema, [], ['mode' => 'json']);
스키마 빌더(schema builder)에는 유니온(unions), 재사용 가능한 정의(reusable definitions), 참조(references), 그리고 검증(validation) 기능이 추가되었습니다:
use Aimeos\Prisma\Schema\Schema;
$schema = Schema::for('order', [
...
제공업체에 의해 강제되는 구조화된 출력(Provider-enforced structured output)은 위험을 줄여주지만, 생성된 콘텐츠의 신뢰성을 보장하지는 않습니다. 수신한 형태(shape)를 검증하고, 생성된 값을 사용자가 제공한 입력값과 마찬가지로 주의 깊게 처리하십시오.
더 넓어진 제공업체 커버리지
Prisma 0.5는 이제 텍스트, 이미지, 오디오 및 비디오 워크플로(workflows) 전반에 걸쳐 29개의 제공업체를 지원합니다. 이번 릴리스를 통해 Azure OpenAI 텍스트 지원, VertexAI 텍스트 지원, xAI, ModelsLab, Replicate를 통한 이미지 생성, 그리고 더 많은 제공업체에 걸친 텍스트 임베딩(text embeddings) 지원이 추가되었습니다.
OpenAI 호환 엔드포인트(OpenAI-compatible endpoints)는 여전히 실용적인 탈출구(escape hatch)로 남아 있습니다. 기본 URL(base URL)을 변경함으로써 openai 프로바이더(provider)를 통해 로컬 서버, 내부 게이트웨이 및 프록시 서비스를 사용할 수 있습니다:
$response = Prisma::text()
->using('openai', [
'api_key' => getenv('GATEWAY_API_KEY'),
...
0.5 버전에서는 프로바이더 도구(Provider tools) 또한 더욱 신중하게 동작합니다. Prisma는 프로바이더가 현재 요청 형태(request shape)에 사용할 수 없는 서버 측 도구와 같은 지원되지 않는 조합을 생략할 수 있으며, 이를 통해 모든 애플리케이션이 이러한 예외적인 케이스(edge cases)를 반드시 알 필요가 없도록 합니다.
호출이 발생하는 지점에서의 관찰 가능성 (Observability)
프로덕션 환경의 AI 호출에는 계정 산출(accounting)이 필요합니다. 단순한 응답 문자열만으로는 어떤 모델이 실행되었는지, 요청에 시간이 얼마나 걸렸는지, 실패했는지, 또는 프로바이더가 보고한 사용량(usage)이 무엇인지 알 수 없습니다.
Prisma 0.5는 요청 범위 관찰자(request-scoped observers)를 추가합니다:
use Aimeos\Prisma\Prisma;
use Aimeos\Prisma\Values\Observation;
...
관찰(observation)은 작업(operation), 프로바이더 유형(provider type), 프로바이더 이름(provider name), 모델(model), 지속 시간(duration), 에러 상태(error state), 사용량(usage) 및 메타데이터(metadata)를 기록합니다. 스트리밍 응답(Streamed responses)은 스트림이 완료된 후 관찰되므로, 사용량과 메타데이터가 포함됩니다.
사용량(Usage)과 메타데이터(metadata)에 이름 부여
프로바이더의 사용량 페이로드(usage payloads)는 일관적이지 않습니다. 어떤 API가 응답했느냐에 따라 input_tokens, prompt_tokens, promptTokenCount, inputTokens가 모두 동일한 의미를 가질 수 있습니다.
0.5 버전에서 usage()는 Values\ Usage 객체를 반환합니다:
$usage = $response->usage();
$usage->promptTokens();
...
meta()는 Values\Meta 객체를 반환합니다:
$meta = $response->meta();
$meta->id();
...
두 객체 모두 프로바이더별 필드에 대해 배열 호환성(array-compatible)을 유지합니다:
$rawUsage = $response->usage()->all();
$created = $response->meta()['created'] ?? null;
이러한 결과값을 배열로 타입 힌트(type-hint)하고 있는 기존 코드는 Values\Usage, Values\Meta로 전환하거나, 가공되지 않은 배열(raw array)이 필요한 경우 all()을 호출해야 합니다.
라이브 프로바이더 없이 테스트하기
애플리케이션 테스트 시 올바른 Prisma 호출이 이루어지는지 증명하기 위해 실제 API 키가 필요해서는 안 됩니다. Prisma 0.5는 녹화된 가짜(recording fake) 기능을 추가했습니다:
use Aimeos\Prisma\Prisma;
use Aimeos\Prisma\Responses\TextResponse;
...
프로바이더(provider) 수준의 테스트를 위해, 새로운 테스트 헬퍼(testing helpers)는 모킹(mocked)된 Guzzle 응답을 사용하여 실제 프로바이더 코드를 실행할 수 있습니다. 요청 생성(Request building), 응답 파싱(response parsing), 스트리밍(streaming), 그리고 툴 루프(tool loops)를 테스트 프로세스를 벗어나지 않고도 실행할 수 있습니다.
응답은 JsonSerializable을 구현하므로, 스냅샷 스타일의 단언(snapshot-style assertions)을 간단하게 유지할 수 있습니다:
$payload = $response->jsonSerialize();
더 안전한 응답 경계 (Safer response boundaries)
프로바이더 응답은 스트리밍(streamed)되거나, 프록시(proxied)되거나, 형식이 잘못되었거나(malformed), 단순히 너무 클 수 있습니다. withMaxResponseSize()는 Prisma가 단일 프로바이더 응답에서 읽을 바이트 수를 제한합니다:
$response = Prisma::text()
->using('openai', ['api_key' => getenv('OPENAI_API_KEY')])
->withMaxResponseSize(16 * 1024 * 1024)
...
기본 제한은 프로바이더 응답당 64 MB입니다. 이는 개별 툴 루프(tool-loop) 턴을 포함하여 스트리밍 및 비스트리밍 호출 모두에 적용됩니다.
이번 릴리스는 또한 프로바이더 클래스 이름을 생성하기 전에 프로바이더 유형과 이름을 검증함으로써 프로바이더 검색(provider discovery)을 강화합니다.
커스텀 프로바이더도 이야기의 일부입니다
Prisma는 네임스페이스 관례(namespace convention)에 따라 프로바이더를 결정합니다:
Prisma::text()->using('myprovider', $config);
이는 다음과 같이 매핑됩니다:
Aimeos\Prisma\Providers\Text\Myprovider
새로운 커스텀 프로바이더 가이드에는 프로바이더 검색(provider discovery), 계약(contracts), 응답 객체(response objects), 구조화된 출력(structured output), 툴 루프(tool loops), 비동기 작업(async operations), OpenAI 호환 API, 그리고 테스트에 대한 문서가 포함되어 있습니다.
이는 프로젝트에 내부 게이트웨이(internal gateway), 프라이빗 모델 호스트(private model host), 또는 Prisma가 아직 제공하지 않는 프로바이더가 있는 경우 유용합니다.
업그레이드 (Upgrading)
주요 마이그레이션 포인트는 작지만 확인해 볼 가치가 있습니다. 실시간 텍스트 응답에는 stream()을 사용하세요. 이전 대화 내용을 전달하려면 withMessages()를 통해 전달하세요. 구조화된 출력 (structured output)을 요청하려면 structure()를 호출하고, 파싱된 응답을 읽을 때는 계속해서 structured()를 사용하세요. usage()와 meta()는 값 객체 (value objects)로 취급하거나, 기존 코드가 배열을 기대하는 경우 all()을 호출하세요. 사용량 (usage), 메타데이터 (metadata), 인용 (citations), 도구 단계 (tool steps) 또는 종료 사유 (finish reason)를 읽기 전에 스트리밍된 응답을 모두 소진(drain)하세요. 테스트 종료 시(teardown) Prisma::fake()를 리셋하세요.
링크 (Links)
문서 (Docs): https://php-prisma.org
GitHub: https://github.com/aimeos/prisma
커스텀 프로바이더 (Custom providers): CUSTOM-PROVIDERS.md
Prisma 0.4는 텍스트, 이미지, 오디오 및 비디오 전반에 걸친 광범위한 인터페이스를 구축했습니다. Prisma 0.5는 스트리밍 UI, 관찰 가능한 호출 (observable calls), 더 저렴한 테스트, 더 명확한 스키마 (schemas), 프로바이더 폴백 (provider fallbacks) 및 커스텀 통합을 통해 해당 인터페이스를 프로덕션 환경에서 더 쉽게 실행할 수 있도록 만듭니다.
AI 자동 생성 콘텐츠
본 콘텐츠는 Dev.to AI tag의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기