티스토리 뷰

Tool Calling이란?
Foundation Models에 외부 도구를 알려주고, 모델이 이를 직접 호출할 수 있도록 해주는 기능이에요

 

왜 Tool calling이 필요한가?
일반적인 언어 모델은 학습된 시점의 지식에 한정되어 있어요
하지만 Tool calling을 활용하면 실시간 정보도 가져올 수 있고, 날씨, 지도, 캘린더 등 디바이스 기능을 활용할 수 있어요

 

protocol Tool
Tool은 프로토콜을 살펴보면 Sendable프로토콜을 준수하고 있어요
이유는 Foundation Models 프레임워크가 Tool을 concurrency 환경에서 실행하기 때문이에요

protocol Tool<Arguments, Output> : Sendable

따라서 Tool은 스레드-세이프하게 사용되도록 보장되어야 해요


애플 문서에 있는 예제를 조금 바꿔서 테스트해볼게요

 

FindContacts

struct FindContacts: Tool {
    let name = "findContacts"
    let description = "Find a specific number of contacts"

    @Generable
    struct Arguments {
        @Guide(description: "The number of contacts to get", .range(1...10))
        let count: Int
    }

    func call(arguments: Arguments) async throws -> ToolOutput {
        let contacts: [CNContact] = [
            mockContact(given: "Ellie", family: "Kim"),
            mockContact(given: "Ellie", family: "Lee"),
            mockContact(given: "Ellie", family: "Choi")
        ]
        let count = min(arguments.count, contacts.count)
        let names = contacts.prefix(count).map { "\($0.givenName) \($0.familyName)" }

        return ToolOutput(names.joined(separator: ", "))
    }

    private func mockContact(given: String, family: String) -> CNContact {
        let contact = CNMutableContact()
        contact.givenName = given
        contact.familyName = family
        return contact.copy() as! CNContact
    }
}

Tool프로토콜을 준수하는 구조체 FindContacts를 만들어줘요
Tool이 받을 입력 값인 Arguments를 정의해 줄게요

@Generable 매크로를 사용하면, 모델이 해당 타입의 인스턴스를 자동으로 생성할 수 있어요
또한, @Guide 매크로를 활용해 count에 대한 설명도 추가했어요
(@Generable, @Guide 잘 모르겠으면 참고)

call(arguments: Arguments) async throws -> ToolOutput는 Tool이 호출될 때 실행되는 비동기 함수예요
이 예제에서는 테스트 용으로 mockContact 3개 추가해 놨는데
실제 구현에서는 Contact 권한을 요청하고, 실제 디바이스의 연락처 정보를 불러오는 로직으로 대체하면 돼요

 

sendPrompt()
모델 세션을 생성할 때 사용할 Tool로 FindContacts를 같이 넣어줘요
이렇게 모델이 응답할 때 이 Tool을 쓸 수 있다는 걸 알려주는 거예요

func sendPrompt() async {
    let session = LanguageModelSession(tools: [FindContacts()])
    let prompt = "Can you give me 2 contacts?"
    
    do {
        let result = try await session.respond(to: prompt)
        print(result.content)
    } catch {
        return
    }
}

그리고 프롬프트를 전달하면, 모델은 FindContacts Tool을 활용해 아래와 같이 Ellie Kim, Ellie Lee를 생성해줘요

 

전체적인 Flow
1. FindContacts Tool을 사용할 수 있도록 모델 세션을 생성
2. Can you give me 2 contacts?라는 prompt 전달
3. 모델은 이 요청을 확인하고 Tool을 사용할지 말지 판단
4. 모델이 Tool호출이 필요하다고 판단되면 FindContacts.call 함수 실행
5. 반환된 결과를 바탕으로 응답 생성


resource:
https://developer.apple.com/documentation/foundationmodels/expanding-generation-with-tool-calling
https://developer.apple.com/documentation/foundationmodels/tool
https://developer.apple.com/videos/play/wwdc2025/259/

 

공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2026/01   »
1 2 3
4 5 6 7 8 9 10
11 12 13 14 15 16 17
18 19 20 21 22 23 24
25 26 27 28 29 30 31
글 보관함