본문 바로가기
C.W.K.
Stream
Lesson 02 of 04 · published

못 쓸 호출은 아예 하지 마

~10 min · permission-before-inference, preconditions, dont-waste, gate

Level 0식은 부싯돌
0 XP0/34 lessons0/12 achievements
0/100 XP to next level100 XP to go0% complete
"답을 못 넣을 걸 이미 알면, 물어보지도 마."

시작하기 전에 끝까지 볼 것

한 번 치는 건 짧은 흐름이야. 붙잡고, 물어보고, 넣고. 그중 넣는 단계엔 접근성 권한이 필요하지. 그러니 규율 있게 하려면 그 권한을 맨 앞에서 확인해야 해. 붙잡기가 추론으로 이어지기도 전에. 못 넣으면 모델이 뭐라 하든 이번 치기는 통째로 망한 거니까. 뒤쪽 단계가 요구하는 걸 비싼 단계 앞에서 미리 보는 것, 그게 조심스러운 흐름이랑 값비싼 일 다 해놓고 결승선에서 자빠지는 흐름을 갈라.

못 쓸 호출은 아예 안 해

구체적으로는 이래. 접근성이 안 열려 있으면 Flint 는 모델을 안 불러. 바로 멈추고, 권한이 필요하다고 말하고, 시스템 설정의 접근성 화면을 열어줘. 결과를 받아놓고 나서야 놓을 데가 없다는 걸 깨닫는 짓은 안 하는 거지. 추론엔 시간이 들고 흔히 돈이나 횟수 제한도 걸리는데, 못 쓸 걸 알면서 쓰는 건 그냥 낭비잖아. 게다가 사용자는 결국 어디에도 못 갈 결과를 기다리며 빙글빙글 도는 표시만 쳐다보게 되고.

침
  |
  +-- 접근성 열려 있나?
  |     아니오 -> 멈춘다. 설명하고 설정 화면을 연다. 모델은 안 부른다.
  |     예     -> 계속
  |
  +-- 붙잡기 -> 물어보기 -> 확인 -> 넣기

권한 관문은 추론 앞에 있지 뒤에 있지 않다.

버려진 호출의 값

이건 이미 뒤쪽 절반을 본 생각의 앞쪽 절반이야. 뒤쪽(Track 6)에선, 호출이 이미 끝났는데 자리가 낡아버렸을 때 Flint 가 결과를 버리는 대신 클립보드로 건져냈지. 앞쪽에선, 애초에 못 쓸 걸 아는 호출을 안 하고. 둘 다 같은 규칙에서 나와. 추론 호출은 값이 매겨진 자원이니까 헛되이 쓰지도 말고, 이미 쓴 걸 버리지도 말자는 것. 들어갈 땐 비싼 단계를 지키고, 나올 땐 그 결과를 건지고.

비싼 단계 값을 치르기 전에, 뒤쪽 단계가 요구하는 걸 먼저 확인해. 나중 단계에 꼭 필요한 게 있으면 — 권한이든, 연결이든, 유효한 자리든 — 그 앞의 값비싼 단계를 돌리기 전에 봐. 비싼 일부터 해놓고 나중에 그 요구에서 자빠지면 그 일도 사용자 시간도 다 버리는 거야. 제일 싼 실패는 아무것도 쓰기 전에 알아채는 실패고. 미리 알 수 있는 조건은 흐름 맨 앞으로 옮겨.
권한 없다고 알려줄 땐 알려주기만 하지 말고 길을 터줘. '접근성 권한이 필요합니다' 는 막다른 길이야. 같은 말에 바로 그 설정 화면을 여는 버튼이 붙으면 해결책이 되고. 뭔가 없어서 멈출 땐 보고만 하지 말고 사용자를 해결할 수 있는 자리까지 데려가. 멈춰 세우고 문을 가리키는 확인은 도움이 되고, 멈춰 세우고 어깨만 으쓱하는 확인은 그냥 에러야.

Code

권한 관문, 추론을 쓰기 전에·swift
func runMacro(_ macro: FlintMacro) async {
    // 마지막 단계가 요구하는 걸 맨 처음에 확인한다.
    guard hasAccessibility() else {
        // 붙잡지도, 물어보지도 않는다. 어차피 결과를 못 넣으니까.
        notify("글을 넣으려면 Flint 한테 접근성 권한이 필요해.")
        requestAccessibility()          // 시스템 설정 화면을 연다
        return                          // 모델 호출은 안 쓴다
    }

    guard let target = TargetCapture.snapshot() else { return }  // 보안 칸일 수도
    let prompt = macro.render(input: target.selection ?? "")
    let result = await pippa.applyFree(prompt: prompt,
                                       vault: macro.vaultContextMode)
    Insertion.place(result, into: target)
}

func hasAccessibility() -> Bool { AXIsProcessTrusted() }

External links

Exercise

Flint 가 접근성 권한을 확인할 수 있는 자리가 셋 있어. 앱 켤 때 한 번만, 결과를 넣기 직전에, 그리고 칠 때마다 추론 전에. 각각을 버려지는 모델 호출이랑 사용자 경험 면에서 따져봐. 그다음 이걸 Track 6 의 클립보드 길이랑 이어봐. '못 쓸 호출은 안 한다' 랑 '자리가 낡은 결과는 건져낸다' 가 어떻게 한 규칙의 양쪽 절반이야?
Hint
켤 때 한 번만 보면 낡아. 세션 도중에 권한이 회수될 수 있어서 나중에 친 게 여전히 호출을 버리게 되거든. 넣기 직전에 보면 추론 호출을 통째로 버리고. 칠 때마다 앞에서 보는 게 맞아. 못 넣을 게 확실한데 호출을 안 쓰니까. 이어지는 지점은, 둘 다 추론 호출을 값이 매겨진 자원으로 본다는 거야. 관문은 못 쓸 걸 안 쓰고, 클립보드 길은 이미 쓴 걸 안 버리고. 들어갈 때 지키고 나올 때 건지는 거지.

Progress

Progress is local-only — sign in to sync across devices.
이 페이지에서 버그를 발견하셨거나 피드백이 있으세요?문제 신고

댓글 0

🔔 답글 알림 (로그인 필요)
로그인댓글을 남기려면 로그인해 주세요.

아직 댓글이 없어요. 첫 댓글을 남겨보세요.