함수 결과를 청크로 스트리밍
Python과 TypeScript v2 함수는 결과를 청크(Chunk)로 나누어 전달할 수 있습니다. 소비자는 전체 결과가 완성되기 전에 받은 값을 처리할 수 있습니다.
Python은 Iterable[T] 반환 타입과 yield, TSv2는 async generator와 AsyncIterable<T> 및 yield를 사용합니다.
숫자를 순차 반환
Python 예제는 0부터 n-1까지 값을 1초 간격으로 반환합니다.
import time
from typing import Iterable
from functions.api import function
@function
def my_lazy_number_generator(n: int) -> Iterable[int]:
for i in range(n):
time.sleep(1)
yield i
TSv2의 myLazyNumberGenerator.ts입니다.
import { Integer } from "@osdk/functions";
export default async function* myLazyNumberGenerator(n: Integer): AsyncIterable<Integer> {
for (let i = 0; i < n; i++) {
await new Promise(resolve => setTimeout(resolve, 1_000));
yield i;
}
}
스트리밍이라고 함수 실행시간 한도가 없어지는 것은 아닙니다.
언어 모델 스트리밍 준비
AIP가 활성화되어 있고 AIP builder 기능을 사용할 권한이 필요합니다. 함수 저장소의 Resource imports > Platform SDK에서 Add > Models로 OpenAI 호환 스트리밍 모델을 선택하고 고유 별칭을 구성합니다.
아래 gpt55는 저장소에 구성할 예제 별칭 이름이며 특정 모델을 모든 플랫폼 인스턴스에서 사용할 수 있다는 의미가 아닙니다. 코드와 실제 별칭을 일치시켜야 합니다. openai 같은 타사 라이브러리는 기본 설치된 것으로 가정하지 말고 Libraries에 추가합니다. TypeScript는 @osdk/language-models, Python은 foundry-platform-sdk의 언어 모델 도구를 사용합니다.
다음 두 구현은 대안이며 같은 온톨로지의 createChatCompletion API 이름으로 동시에 게시할 수는 없습니다. OSDK로 호출하려면 읽기 전용 쿼리의 API 이름 요건을 충족하고 소비 SDK에 해당 쿼리를 가져와야 합니다.
Python 모델 함수
from typing import Iterable
from openai import OpenAI
from functions.api import function
from functions.aliases import model
from foundry_sdk.v2.language_models import (
get_openai_base_url,
get_foundry_token,
get_http_client,
)
@function(api_name="createChatCompletion")
def create_chat_completion(prompt: str) -> Iterable[str]:
client = OpenAI(
api_key=get_foundry_token(preview=True),
base_url=get_openai_base_url(preview=True),
http_client=get_http_client(preview=True),
)
stream = client.chat.completions.create(
model=model("gpt55").rid,
messages=[{"role": "user", "content": prompt}],
stream=True,
)
for event in stream:
if event.choices:
content = event.choices[0].delta.content
if content:
yield content
TypeScript v2 모델 함수
typescript-functions/src/functions/createChatCompletion.ts에 작성합니다. PlatformClient는 Foundry가 런타임에 전달하는 인증된 클라이언트입니다.
import { PlatformClient } from "@osdk/client";
import OpenAI from "openai";
import { Aliases } from "@osdk/functions";
import { getFoundryToken, getOpenAiBaseUrl, createFetch } from "@osdk/language-models";
export const config = { apiName: "createChatCompletion" };
export default async function* createChatCompletion(
client: PlatformClient,
prompt: string
): AsyncIterable<string> {
const oaiClient = new OpenAI({
apiKey: await getFoundryToken(client),
baseURL: getOpenAiBaseUrl(client),
fetch: createFetch(client),
});
const stream = await oaiClient.chat.completions.create({
model: Aliases.model("gpt55").rid,
messages: [{ role: "user", content: prompt }],
stream: true,
});
for await (const event of stream) {
const content = event.choices[0]?.delta?.content;
if (content) {
yield content;
}
}
}
역할 정보나 사용량처럼 텍스트가 없는 청크는 문자열로 내보내지 않습니다. 모델 요청 오류는 호출자에게 전파됩니다. 이 코드를 실행하면 실제 모델 요청과 관련 사용량이 발생합니다.
OSDK에서 호출
스트리밍 함수의 OSDK 실행은 Beta입니다. 태그와 게시 및 SDK 가져오기를 끝낸 뒤 React 앱, Workshop 사용자 지정 위젯 또는 다른 함수에서 사용할 수 있습니다.
다음 소비 함수들은 인증과 생성된 쿼리 바인딩을 가진 실제 client를 인수로 받습니다. 수신한 청크를 그대로 순회할 수 있는 인터페이스로 제공합니다. 예를 들어 prompt에 Where is Mount Everest?를 전달할 수 있습니다.
Python은 AllowBetaFeatures 문맥 안에서 생성된 streaming 메서드를 호출합니다.
from typing import Iterable
from foundry_sdk_runtime import AllowBetaFeatures
from ontology_sdk import FoundryClient
def receive_chat_completion(client: FoundryClient, prompt: str) -> Iterable[str]:
with AllowBetaFeatures():
with client.ontology.queries.create_chat_completion_streaming(prompt=prompt) as stream:
yield from stream
TypeScript 소비 코드는 앱의 모듈에서 사용할 수 있습니다. 함수의 구현 파일이 아니라 소비 앱의 생성 SDK에서 createChatCompletion 정의를 가져옵니다.
import { Client } from "@osdk/client";
import { createChatCompletion } from "@ontology/sdk";
import { __EXPERIMENTAL__NOT_SUPPORTED_YET__executeStreamingFunction } from "@osdk/api/unstable";
export async function* receiveChatCompletion(
client: Client,
prompt: string
): AsyncIterable<string> {
const stream = client(__EXPERIMENTAL__NOT_SUPPORTED_YET__executeStreamingFunction)
.executeStreamingFunction(createChatCompletion, { prompt });
for await (const text of stream) {
yield text;
}
}
소비 앱은 받은 청크를 화면이나 처리 로직에 전달합니다.