티스토리 뷰

안녕하세요 :)

오늘은 애플 Foundation Models 프레임워크를 활용해서 간단한 Grammar Correction(문법 교정하는거?)을 만들어보려고 해요

시작하기 전에, Foundation Models를 사용하기 위한 몇 가지 요구사항이 충족되어야 하는데
이 글을 읽기 전에 내 환경에서 사용 가능한지 먼저 확인해 보시는 걸 추천드립니다!


@State 프로퍼티 정의

@State private var userInput: String = ""
@State private var correctionResult: String = ""
@State private var isLoading = false
@State private var errorMessage: String?

총 4개의 @State변수를 사용하고 있어요
userInput: 사용자가 입력한 문자를 담기 위한 변수
correctionResult: 응답 결과를 담을 문자열 변수
isLoading: 요청 중을 나타내는 플래그, progressView 제어
errorMessage: 에러 발생시 에러 메세지를 위한 변수

body

var body: some View {
    VStack(spacing: 16) {
        Text("📝 Enter a sentence you'd like to correct")
            .font(.headline)
            .frame(maxWidth: .infinity, alignment: .leading)
        
        TextEditor(text: $userInput)
            .frame(height: 120)
            .overlay(RoundedRectangle(cornerRadius: 8).stroke(Color.gray.opacity(0.4)))
            .padding(.horizontal, 4)
        
        HStack {
            Button(action: {
                userInput = ""
                correctionResult = ""
                errorMessage = nil
            }) {
                Label("Clear", systemImage: "xmark.circle")
            }
            .buttonStyle(.bordered)
            
            Spacer()
            
            Button(action: {
                Task {
                    await correctSentence()
                }
            }) {
                HStack {
                    if isLoading {
                        ProgressView()
                    } else {
                        Image(systemName: "wand.and.stars")
                        Text("Correct Grammar")
                    }
                }
            }
            .disabled(userInput.trimmingCharacters(in: .whitespacesAndNewlines).isEmpty || isLoading)
            .buttonStyle(.borderedProminent)
        }
        
        if let errorMessage = errorMessage {
            Text(errorMessage)
                .foregroundColor(.red)
        }
        
        if !correctionResult.isEmpty {
            VStack(alignment: .leading, spacing: 8) {
                Text("Correction & Explanation")
                    .font(.headline)
                ScrollView {
                    Text(correctionResult)
                        .frame(maxWidth: .infinity, alignment: .leading)
                }
                .frame(minHeight: 100)
            }
            .padding()
            .background(Color(.systemGray6))
            .cornerRadius(12)
        }
        
        Spacer()
    }
    .padding()
}

body는 크게
타이틀, 입력 필드, 버튼 영역, 결과 출력부분으로 구성되어 있어요
그냥 UI니까 여기는 패스

 

correctSentence()

func correctSentence() async {
    isLoading = true
    correctionResult = ""
    errorMessage = nil

    UIApplication.shared.sendAction(#selector(UIResponder.resignFirstResponder), to: nil, from: nil, for: nil)

    do {
        let instructions = "You are a helpful and knowledgeable English tutor. When a student provides a sentence, check it for grammar mistakes. If there are any, explain what is wrong and provide the corrected sentence. If the sentence is already correct, confirm that it is correct and explain why."
        let session = LanguageModelSession(instructions: instructions)

        let prompt = """
        Please check the following sentence for any grammar mistakes. If there are mistakes, explain them and provide the corrected version. If the sentence is already correct, explain why it is correct.
        \"\(userInput.trimmingCharacters(in: .whitespacesAndNewlines))\"
        """
        
        let response = try await session.respond(to: prompt)
        correctionResult = response.content
    } catch {
        errorMessage = "Failed to get response: \(error.localizedDescription)"
    }

    isLoading = false
}

Correct Grammar 버튼을 탭하면 비동기 함수인 correctSentence()가 호출되는데요
먼저, isLoading을 true로 설정하고 이전에 저장된 correctionResult와 errorMessage를 초기화시켜줍니다
그리고 키보드를 내려주기 위해서 resignFirstResponder()도 호출해 줍니다

이후, LanguageModelSession을 생성하고 instructions을 설정하는데요,
instruction은 대충
너는 친절하고 똑똑한 영어 튜터이고 문법 오류가 있는지 확인해 주고
오류가 있다면 왜 잘못되었는지와 올바른 문장을 제시해 주고,
문법 오류가 없다면 그 문장이 맞다는 것을 확인해 줘 뭐 이런 내용을 담았고
사용자 입력을 포함한 구체적인 prompt도 비슷하게 작성해 줬어요

작성한 prompt를 LLM에 전달하고 응답을 기다려요
응답이 오면, 그 내용을 correctionResult에 반영해 화면에 표시되게 해줘요
만약 에러가 발생하면 catch블록이 실행되어 errorMessage에 오류 내용을 저장하게 됩니다

여튼 결과를 표시하거나 오류 메세지를 출력한 후 로딩 상태를 false로 변경해 줍니다


+ 왜 instruction이랑 prompt랑 비슷한데 분리해놨냐?
instruction이랑 prompt가 비슷해 보이지만, 역할이 조금 달라요
instruction는 모델의 역할이나 동작 방식을 정의하는데 좀 더 포커스를 두고
prompt는 실제 유저의 질문 또는 입력을 반영해서 구체적인 요청을 전달해요

WWDC25 비디오에 보니까 둘을 분리하는 것이 더 좋은 아웃풋을 낸다고 하더라구요? 


이 모든 코드를 조합하면 아래와 같이 간단한 Grammar Correction을 만들어 볼 수 있어요

전체 코드는 여기에 올려뒀어요!
https://github.com/kimhyeri/FoundationModelsPlayground

 

GitHub - kimhyeri/FoundationModelsPlayground: A collection of examples using Apple’s FoundationModels framework

A collection of examples using Apple’s FoundationModels framework - kimhyeri/FoundationModelsPlayground

github.com

 

공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2026/02   »
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
글 보관함