Apple Foundation Models
Apple Foundation Models
Claude for Foundation Models는 Apple의 Foundation Models 프레임워크에서 Claude를 서버 측 언어 모델로 쓸 수 있게 해 주는 Swift 패키지예요. 이 패키지가 Claude를 프레임워크의 LanguageModel 프로토콜에 맞춰 주기 때문에, Apple 온디바이스 모델에 쓰는 것과 똑같은 LanguageModelSession API로 Claude를 다룰 수 있어요. respond(to:), 스트리밍, 가이드 생성(guided generation), 도구 호출 모두 같은 방식으로 동작해요.
요청은 앱에서 Claude API로 직접 나가요. Apple은 요청 경로에 끼어들지 않고 프롬프트나 응답도 보지 못해요. 사용량은 표준 API 요금으로 사용자의 Anthropic 계정에 청구되니까, 조직에 사용 가능한 크레딧 잔액이나 활성 결제 수단이 필요해요. 앱이 언제 Claude를 쓸지, 언제 Apple 온디바이스 모델을 쓸지 결정해요. 각 세션에 원하는 모델을 넘기면 되죠.
참고: 베타. 이 패키지는 OS 27 베타에서 도입된 Foundation Models 서버 측 언어 모델 API를 대상으로 해요. 베타 동안 API가 바뀔 수 있어요.
출처: 문서
본문
요구 사항
- iOS 27, macOS 27, visionOS 27 또는 watchOS 27 (전부 베타): 서버 측 언어 모델을 지원하는 Foundation Models 프레임워크가 있는 OS 릴리스
- Xcode 27 (베타)
- 개발용 Claude API 키 — Claude Console에서 받아요. 프로덕션 옵션은 인증을 참고하세요.
패키지 설치
Package.swift에 패키지를 추가해요.
dependencies: [
.package(url: "https://github.com/anthropics/ClaudeForFoundationModels.git", from: "0.1.0")
]
Xcode에서는 File > **Add Package Dependencies…**로 가서 저장소 URL을 입력하면 돼요.
그 다음 타깃의 dependencies에 ClaudeForFoundationModels를 추가하고 FoundationModels와 함께 import해요.
import FoundationModels
import ClaudeForFoundationModels
빠른 시작
ClaudeLanguageModel이 진입점이에요. LanguageModelSession에 넘기고, 다른 Foundation Models 프로바이더와 똑같이 세션을 사용하면 돼요.
import FoundationModels
import ClaudeForFoundationModels
let model = ClaudeLanguageModel(
name: .sonnet5,
auth: .apiKey(ProcessInfo.processInfo.environment["ANTHROPIC_API_KEY"] ?? "")
)
let session = LanguageModelSession(model: model)
let response = try await session.respond(to: "Plan a 4-day trip to Buenos Aires.")
print(response.content)
초기화자는 baseURL(기본값 https://api.anthropic.com), timeout, serverTools(아래 서버 측 도구 참고)도 받아요.
완전한 예제 프로그램은 저장소의 Examples/ClaudeExample에서 볼 수 있어요. 터미널로 채팅 턴을 스트리밍하는 실행 가능한 커맨드라인 타깃이고, --search 플래그로 그 턴의 서버 측 웹 검색을 켤 수 있어요. 실행하려면 macOS 27 호스트가 필요해요.
모델 고르기
모델 식별자는 ClaudeModel의 값이에요. 컴파일돼 있는 상수를 쓰거나, 아직 컴파일돼 있지 않은 ID는 명시적 능력(capabilities)으로 직접 만들어 써요 (아래 Capabilities 참고).
ClaudeLanguageModel(name: .opus5_5, auth: auth)
상수는 API 모델 ID를 그대로 반영하고(.opus5는 claude-opus-5) 각 모델의 능력을 담고 있어요. 새 모델은 패키지 릴리스에서 새 상수로 추가돼요. Xcode에서 ClaudeModel을 확인하면 현재 목록을 볼 수 있고, 모델 개요에서 모델을 비교할 수 있어요.
Capabilities
각 ClaudeModel은 받아들이는 것을 선언해요: 샘플링 파라미터, effort 레벨, 적응형 사고(adaptive thinking), 구조화 출력, 이미지 입력. 패키지는 이 정보로 어떤 요청 필드를 보낼지 결정해요. 모델이 거부하는 필드를 보내면 하드 에러가 발생하기 때문이죠. 상수는 올바른 능력을 담고 있어요. 컴파일돼 있지 않은 ID라면 모델이 받아들이는 것을 직접 선언해 주세요(추측하는 단축어는 의도적으로 없어요).
let model = ClaudeModel(
id: "claude-experimental-x",
capabilities: .init(samplingParams: false, effortLevels: [.low, .high])
)
ClaudeLanguageModel(name: model, auth: auth)
Effort
모든 요청에 Claude effort 레벨을 고정하려면 fixedEffort:를 쓰세요. 프레임워크의 요청별 reasoning 힌트보다 우선해요. 프레임워크의 명명된 reasoning 레벨은 high에서 멈추니까, 한 요청에 더 많은 effort를 원한다면 Claude effort를 지정하는 커스텀 reasoning 레벨(.custom("xhigh") 또는 .custom("max"))을 넘기세요. 직접 매핑돼요. effort를 보내지 않으면 API 기본값은 high예요.
ClaudeLanguageModel(name: .opus5_5, auth: auth, fixedEffort: .xhigh)
레벨은 모델이 받아들이는 것이어야 해요. 각 ClaudeModel은 자기 모델이 다섯 레벨(low, medium, high, xhigh, max) 중 어떤 걸 받는지(받는다면) 선언해요. 어떤 모델은 effort를 아예 받지 않기도 해요.
Claude를 쓸 때 vs 온디바이스 모델
Apple 온디바이스 모델은 빠르고, 프라이빗하고, 오프라인에서도 동작하지만 가벼운 작업에 맞춰져 있어요. 더 큰 컨텍스트, 프론티어 추론, 웹 검색·코드 실행 같은 서버 측 도구가 필요할 땐 Claude로 올리세요. 둘 다 같은 LanguageModelSession API를 쓰니까 model: 인자만 바꿔서 전환하면 돼요.
인증
auth: 파라미터로 자격 증명을 설정해요. .appAttest는 백엔드 없이 출시할 때, .proxied는 자체 백엔드를 경유할 때, .apiKey는 개발 중에 반복할 때 써요.
App Attest
앱의 각 설치본은 Apple의 App Attest 서비스를 사용해 자신이 등록한 앱의 진짜 수정되지 않은 빌드임을 증명해요. 그러면 Anthropic이 기기에 단기 접근 토큰을 발급하고, 사용량은 워크스페이스에 청구돼요. 앱에 API 키가 들어 있지 않고, 운영할 프록시도 없어요.
App Attest 인증은 앱이 Claude API를 직접 호출할 때만 쓸 수 있어요. Amazon Bedrock, Google Cloud, Microsoft Foundry에서는 사용할 수 없어요.
백엔드 없이 출시하려면 .appAttest를 쓰세요.
ClaudeLanguageModel(
name: .sonnet5,
auth: .appAttest(clientID: "clid_...")
)
참고: App Attest는 실제 기기가 필요해요. 시뮬레이터나 Secure Enclave가 없는 하드웨어는 App Attest를 수행할 수 없어요. 시뮬레이터에서 반복할 땐
.apiKey, 기기에서 실행할 땐.appAttest를 쓰세요.
App Attest를 설정하려면 Apple Developer Team ID와 조직에서 admin, owner 또는 primary owner 역할이 필요해요. Xcode 프로젝트를 구성하고 Claude Console에서 앱을 등록해요.
- Xcode의 Signing & Capabilities에서 앱 타깃에 App Attest 능력을 추가해요.
- Claude Console의 워크스페이스 설정에서 App integrations를 열어요.
- Create app integration을 클릭하고 이름, Apple Developer Team ID, 하나 이상의 bundle ID(최대 32개)를 입력해요.
- 통합의 Overview 탭에서 client ID(
clid_...)를 복사해 앱의 Claude 구성에 넘겨요.
앱이 기기에서 Claude를 처음 사용할 때, 앱이 Anthropic에 챌린지를 요청하고 Apple의 DCAppAttestService로 기기를 증명한 뒤 검증된 증명(attestation)을 접근 토큰으로 교환해요. Claude for Foundation Models 패키지가 이 흐름을 자동으로 실행하고 토큰이 만료되면 새로 요청해요. 직접 작성할 증명 코드는 없어요.
토큰은 워크스페이스로 범위가 제한되고 한 시간 후 만료되며 Messages API 호출만 승인해요. 최종 사용자 신원을 담고 있지는 않아요. App Attest는 사용하는 사람이 아니라 앱을 식별하니까, 사용자별 로직은 앱에서 처리해야 해요.
손상됐거나 폐기된 앱을 중지하려면 통합을 취소해요. Claude Console의 워크스페이스 설정에서 App integrations를 열고 통합을 선택한 뒤 Revoke를 클릭하고 확인해요. 통합을 취소하면 미결 토큰도 취소되고, 등록된 기기는 더 이상 새 토큰을 요청할 수 없어요. 취소는 영구적이므로 접근을 복원하려면 새 앱 통합을 만들어야 해요.
프록시 (프로덕션)
프로덕션에서는 자체 백엔드를 경유하는 .proxied로 요청을 라우팅해요. baseURL의 릴레이가 서버 측에서 Claude API 자격 증명을 추가하므로 앱에는 키가 들어 있지 않아요. 제공한 headers는 모든 요청에 실리므로 프록시가 호출자를 인증할 수 있어요. 필요 없으면 [:]를 넘기세요.
ClaudeLanguageModel(
name: .sonnet5,
auth: .proxied(headers: ["X-App-Token": "..."]),
baseURL: URL(string: "https://api.yourapp.com/claude")!
)
프록시는 표준 Messages API 요청을 받아 x-api-key 헤더를 붙이고 https://api.anthropic.com으로 전달해요.
API 키 (개발)
개발 중에는 API 키를 직접 넘겨요.
ClaudeLanguageModel(name: .sonnet5, auth: .apiKey("YOUR_API_KEY"))
경고: 앱에 번들된 키는 배포 바이너리에서 추출될 수 있고, 추출한 사람은 사용자 계정으로 청구되는 요청을 만들 수 있어요.
.apiKey는 개발 전용으로만 쓰고, 릴리스 전에 App Attest나 프록시로 전환하세요.
스트리밍
streamResponse(to:)는 응답을 점진적으로 반환해요. 각 요소는 지금까지의 응답 전체 스냅샷이지 델타가 아니에요.
let stream = session.streamResponse(to: "Summarize today's top science stories.")
for try await partial in stream {
print(partial.content)
}
구조화 출력
@Generable로 타입을 주석하고 generating:으로 요청해요. 모델이 구조화 출력을 통해 그 타입의 값을 반환해요.
@Generable
struct Trip {
@Guide(description: "Destination city") var destination: String
@Guide(description: "Length in days") var days: Int
}
let response = try await session.respond(to: "Plan a trip to Tokyo.", generating: Trip.self)
print(response.content.destination)
구조화 출력은 능력에 포함된 모델이 필요해요(컴파일돼 있는 상수는 전부 그렇죠). 선택한 모델이 지원하지 않으면 패키지는 조용히 성능을 낮추는 대신 LanguageModelError.unsupportedGenerationGuide를 던져요.
도구 사용
클라이언트 측 도구
프레임워크의 tools: 배열은 그대로 동작해요. 타입을 Tool에 맞추고 LanguageModelSession에 넘기면, Claude가 호출할 때 프레임워크가 기기에서 그 도구를 실행해요. Claude와 도구 사용 참고.
let session = LanguageModelSession(model: model, tools: [FindRestaurantsTool()])
서버 측 도구
서버 도구(웹 검색, 웹 fetch, 코드 실행)는 단일 왕복으로 Anthropic 인프라에서 실행돼요. 기기에서 프레임워크가 실행할 것이 없어요. 각 모델마다 serverTools:로 구성해요.
let model = ClaudeLanguageModel(
name: .sonnet5,
auth: auth,
serverTools: [
.webSearch(maxUses: 5),
.codeExecution,
]
)
.webSearch와 .webFetch는 선택적으로 allowedDomains, blockedDomains, maxUses를 받아요. 서버 도구 활동은 ClaudeServerToolSegment 커스텀 세그먼트로 트랜스크립트에 나타나요.
참고:
serverTools는LanguageModelSession이 아니라ClaudeLanguageModel에 구성해요. 세션 타입이 Apple 것이기 때문이죠. 대화마다 다른 서버 도구 세트를 쓰려면ClaudeLanguageModel인스턴스를 여러 개 만들면 돼요.
이미지
능력에 이미지 입력이 포함된 모델은 프레임워크의 비전 능력을 선언해요. 프레임워크의 표준 세션 API로 이미지 콘텐츠를 넘기면 패키지가 Claude API의 이미지 형식으로 변환해요. 이미지 요구 사항은 Vision 참고.
오류 처리
패키지는 맞는 경우 Claude API 오류를 Apple의 LanguageModelError 케이스에 매핑해요. 컨텍스트 창 초과는 .contextSizeExceeded, HTTP 429는 .rateLimited, 구성된 타임아웃을 지난 요청은 .timeout으로 나타나요. 프레임워크에 대응이 없는 프로바이더 오류는 ClaudeError로 나타나요. 패턴 매칭으로 제품 흐름을 만들 수 있어요.
do {
let response = try await session.respond(to: prompt)
print(response.content)
} catch ClaudeError.missingCredential {
// Prompt for an API key.
} catch let error as LanguageModelError {
// Framework-shaped errors (rate limits, guardrails, context length, decoding).
} catch {
// Transport errors.
}
흔한 패턴은 .rateLimited를 잡아 그 턴을 SystemLanguageModel로 폴백하거나, 요청을 큐에 넣거나, 재시도 선택지를 보여주는 거예요.
기능 지원
패키지는 Foundation Models 프로바이더 프로토콜이 표현할 수 있는 Messages API 능력을 드러내요. Apple 프로토콜에 표현이 없는 기능은 이 경로로 쓸 수 없어요. 그런 기능은 다음과 같아요.
- 프롬프트 캐싱 제어 (패키지는 프롬프트 캐싱을 자동으로 적용해요. 캐시 TTL과 breakpoint 배치는 구성할 수 없어요)
- 중지 시퀀스(Stop sequences)
- 배치 처리(Batch processing)
- Files API
- 토큰 카운팅
- 베타 헤더
추가 자료
| 레퍼런스 | 다루는 내용 |
|---|---|
| Apple Foundation Models 문서 | LanguageModelSession, @Generable, Transcript, Tool 등 프레임워크 표면 전체 |
GitHub의 ClaudeForFoundationModels |
소스, 실행 가능한 예제, 이슈 트래커 |
| Claude API 레퍼런스 | 기반이 되는 Messages API |
패키지는 Apache 2.0 라이선스예요. 버그 보고는 GitHub 이슈로 환영해요. 베타 기간 동안 외부 풀 리퀘스트는 받지 않아요.