함수 인터페이스로 LLM 등록하기: 기존 방식
함수 인터페이스(Function interface)는 함수의 입력, 출력과 오류 계약을 정의합니다. 기존 LLM 등록 방식은 ChatCompletion 인터페이스를 구현한 함수를 AIP가 발견하여 모델로 사용하는 구조입니다. 온프레미스, 자체 클라우드 또는 다른 플랫폼에서 미세 조정한 모델을 연결할 수 있습니다.
이 방식은 TypeScript v1에서만 지원합니다. 같은 방식의 TypeScript v2 구현은 없으며, 2026년 3월부터는 등록 모델이 권장 방식입니다. 기존 함수 인터페이스 방식으로 새 연결을 만들기 전에는 Palantir 지원팀과 적용 여부를 확인해야 합니다.
연결 방식
| 방법 | 동작 |
|---|---|
| 웹훅 | Data Connection에 웹훅을 만들고 TypeScript 함수에서 호출 |
| 직접 소스 호출 | REST API 소스를 가져와 소스의 HTTP 클라이언트로 호출 |
AIP Logic에서 웹훅으로 OpenAI 모델을 호출하려면 다음 절차에 따라 함수를 구성합니다. Pipeline Builder의 기존 BYOM 경로는 웹훅을 지원하지 않으므로 직접 소스 호출 방식을 사용해야 합니다.
시작 전에 소스와 네트워크 정책을 구성할 수 있어야 하며 TypeScript 함수 저장소를 사용할 수 있어야 합니다. 아래의 소스와 함수 이름은 예시입니다.
REST API 소스 설정
- Data Connection → New Source에서
REST API를 검색합니다. - Protocol sources → REST API를 선택합니다.
- Connect to your data source에서 Foundry worker를 선택합니다.
- 소스 이름과 저장 위치를 정합니다. 예를 들어 표시 이름은
MyOpenAI로 지정할 수 있습니다. - 연결 정보를 구성합니다.
| 항목 | 예시 값 |
|---|---|
| Domain base URL | https://api.openai.com |
| Authentication | Bearer token |
| Bearer token | 고객의 OpenAI API 키 |
| Port | 443 |
| 추가 비밀정보 | APIKey에 같은 API 키 저장 |
API 키는 모델 제공자 계정에서 발급받고 소스의 비밀정보에 저장합니다. 코드나 로그에 키 값을 직접 넣지 않습니다.
Network connectivity → Request and self-approve new policy에서 https://api.openai.com으로의 외부 통신 정책을 구성합니다. 필요한 권한이 없으면 관리자 또는 Palantir 담당자에게 정책 구성을 요청합니다.
내보내기와 코드 가져오기
- AIP Logic에 사용하려면 Enable exports to this source without markings validations를 활성화합니다.
- Pipeline Builder에 사용하려면 Enable exports to this source를 활성화합니다. 해당 기존 연동은 베타이며 인스턴스에 제공되지 않을 수 있습니다.
- Allow this source to be imported into code repositories를 활성화합니다.
- Allow this source to be imported into pipelines를 활성화합니다.
소스의 Connection settings → Code import configuration에서 코드에 사용할 API 이름을 확인합니다. 아래 코드는 API 이름을 OpenAI로 지정한 경우입니다. 표시 이름 MyOpenAI와 코드의 식별자를 구분해야 합니다.
설정을 마치고 Continue → Get started로 소스를 생성합니다. 보안 표지 검증 없이 내보내기를 허용하는 범위와 외부 제공자의 데이터 처리 조건도 검토해야 합니다.
웹훅 만들기
Source overview → Create webhook에서 표시 이름을 Create Chat Completion, API 이름을 CreateChatCompletion으로 지정합니다.
요청 구성
호출은 POST https://api.openai.com/v1/chat/completions입니다. 다음 cURL 형식을 Import call from cURL에 넣어 요청 구성을 시작할 수 있습니다. 이는 웹훅 가져오기용이며 인증은 앞서 설정한 소스의 Bearer 인증으로 제공합니다.
curl 'https://api.openai.com/v1/chat/completions' \
--request POST \
--header 'Content-Type: application/json' \
--data '{"model":"gpt-4o","messages":[{"role":"user","content":"안녕하세요"}]}'
입력 매개변수는 다음과 같이 구성합니다.
| 이름 | 자료형 |
|---|---|
model | String |
messages | List of Record. 각 레코드에 String 형식의 role, content |
Body의 Raw JSON 편집기에서 @를 사용해 매개변수를 참조하고, model과 messages 필드에 각각 연결합니다.
응답 구성
첫 번째 호출의 응답에서 Extract by key를 사용하여 choices와 usage를 추출합니다.
| 출력 | 구조 |
|---|---|
choices | 레코드 목록. 각 항목에 Integer index, 레코드 message. message에 String role과 텍스트 응답 content |
usage | 레코드. Integer prompt_tokens, completion_tokens, total_tokens |
입력과 출력 구성을 마친 뒤 웹훅의 API 유형을 반드시 Read API로 설정합니다. Write API 웹훅은 @OntologyEditFunction()에서만 호출할 수 있으므로 여기서 만드는 @ChatCompletion() 함수에는 사용할 수 없습니다. Read API는 HTTP 메서드가 GET이어야 한다는 뜻은 아닙니다.
웹훅을 시험하고 저장합니다. 시험은 외부 모델을 실제로 호출하므로 제공자의 사용량과 비용이 발생할 수 있습니다.
함수 저장소에 리소스 가져오기
TypeScript v1 함수 저장소를 만들고 Resource imports → Add에서 다음을 가져옵니다.
CreateChatCompletion웹훅을 가진 REST API 소스ChatCompletion함수 인터페이스
두 리소스가 모두 목록에 있는지 확인합니다.
리소스를 가져오면 Task Runner가 localDev를 다시 실행하여 코드 바인딩을 생성합니다. 화면 아래의 Task Runner에서 완료 여부를 확인합니다.
인터페이스를 선택하면 가져올 타입과 함수 시그니처를 확인할 수 있습니다.
ChatCompletion 구현
AIP Logic은 이 인터페이스를 구현한 함수를 검색합니다. @ChatCompletion()은 구현 관계를 선언하고 컴파일 시 계약을 검사하게 합니다. 일반 @Function() 데코레이터를 추가할 필요는 없습니다.
입력 이름과 순서도 계약에 포함되므로 messages, params를 그대로 사용합니다. 다음 구현은 텍스트 대화의 세 역할을 변환하고 gpt-4o를 호출합니다. 추가 생성 설정인 params를 외부 요청에 전달하지 않는 메시지 기반 예시입니다.
import { isErr, UserFacingError } from "@foundry/functions-api";
import { OpenAI } from "@foundry/external-systems/sources";
import { ChatCompletion } from "@palantir/languagemodelservice/contracts";
import {
ChatMessageRole,
FunctionsGenericChatCompletionRequestMessages,
FunctionsGenericChatCompletionResponse,
GenericCompletionParams,
} from "@palantir/languagemodelservice/api";
export class MyFunctions {
@ChatCompletion()
public async myChatCompletion(
messages: FunctionsGenericChatCompletionRequestMessages,
params: GenericCompletionParams,
): Promise<FunctionsGenericChatCompletionResponse> {
const result = await OpenAI.webhooks.CreateChatCompletion.call({
model: "gpt-4o",
messages: messages.map(message => ({
role: convertRole(message.role),
content: message.content,
})),
});
if (isErr(result)) {
throw new UserFacingError("외부 모델 웹훅 호출에 실패했습니다.");
}
const output = result.value.output;
const completion = output.choices[0]?.message.content;
if (typeof completion !== "string") {
throw new UserFacingError("모델이 텍스트 응답을 반환하지 않았습니다.");
}
return {
completion,
tokenUsage: {
promptTokens: output.usage.prompt_tokens,
completionTokens: output.usage.completion_tokens,
maxTokens: output.usage.total_tokens,
},
};
}
}
function convertRole(role: ChatMessageRole): "system" | "user" | "assistant" {
switch (role) {
case "SYSTEM": return "system";
case "USER": return "user";
case "ASSISTANT": return "assistant";
default: throw new UserFacingError(`지원하지 않는 메시지 역할: ${role}`);
}
}
웹훅은 성공 또는 실패를 나타내는 결과 객체를 반환하므로 isErr로 검사합니다. 텍스트 응답이 없으면 오류로 처리합니다. 이 구현은 텍스트 완성용이며 도구 호출이나 지원하지 않는 메시지 역할을 일반 텍스트 응답으로 변환하지 않습니다.
시험과 게시
코드를 저장하고 함수 미리보기로 동작을 확인한 뒤 버전을 태그하여 게시합니다. 아래 Functions 탭의 Published에서 함수를 선택하고 JSON 입력 방식으로 시험할 수 있습니다.
메시지 입력의 예시는 다음과 같습니다.
{
"messages": [
{ "role": "USER", "content": "안녕하세요" }
]
}
params 입력은 가져온 인터페이스의 형식에 맞게 구성합니다. 위 구현은 이 값의 추가 설정을 요청에 사용하지 않습니다.
게시한 함수는 AIP Logic의 Use LLM → Registered에서 선택합니다. 기존 등록 모델 사용에서는 Pipeline Builder의 직접 소스 호출과 처리량 제한 오류 전달을 설명합니다.