앱을 만들 때 AI가 ‘생각’하는 방식에 대한 단순한 멘탈 모델
토큰, 컨텍스트, 도구, 테스트로 설명하는 AI의 코드·결정 생성 방식에 대한 명확한 멘탈 모델과 한계 및 실무적 프롬프트 팁.

앱 제작자 관점에서 본 “AI가 생각한다”는 의미
사람들이 “AI가 생각한다”고 말할 때 보통은 질문을 이해하고 추론해서 답을 내린다는 뜻을 떠올립니다.
텍스트 기반 현대 모델(LLM)에는 더 유용한 멘탈 모델이 있습니다: 모델은 다음에 올 텍스트를 예측합니다.
이 표현은 시시해 보일 수 있지만, “다음 텍스트”가 얼마나 많은 것을 만들어낼 수 있는지 보면 달라집니다. 모델이 학습한 패턴이 충분히 많으면, 다음 단어(그리고 그 다음 단어, 또 그다음)를 예측하는 것만으로 설명, 계획, 코드, 요약, 심지어 앱에서 쓸 수 있는 구조화된 데이터까지 생성할 수 있습니다.
목표: 수학이 아닌 실무자용 모델
좋은 AI 기능을 만들기 위해 기저 수학을 알 필요는 없습니다. 필요한 것은 동작을 예측할 실용적인 방식입니다:
- 같은 프롬프트가 왜 다른 답을 줄 수 있는지
- 답이 확신에 차 보이는데도 왜 틀릴 수 있는지
- 작은 프롬프트 변경이 결과를 왜 크게 바꾸는지
- 언제 더 세게 묻지 말고 외부 데이터나 도구를 추가해야 하는지
이 글은 바로 그런 모델입니다: 과장도, 깊은 기술 논문도 아니라 신뢰할 수 있는 제품 경험을 설계하는 데 도움이 되는 개념들입니다.
앱에서의 “생각하기” 모습
앱 제작자 관점에서 모델의 ‘생각’은 입력(프롬프트, 사용자 메시지, 시스템 규칙, 검색된 콘텐츠)에 반응해 생성하는 텍스트입니다. 모델은 기본적으로 사실을 확인하지 않고, 웹을 탐색하지 않으며, 당신의 데이터베이스에 무엇이 있는지를 알지 못합니다—그 정보를 전달하지 않는 한요.
기대치를 적절히 설정하세요: LLM은 초안 작성, 변환, 분류, 코드와 유사한 출력 생성에 매우 유용합니다. 그러나 마법처럼 항상 진실을 말해주진 않습니다.
우리가 사용할 구성 요소들
멘탈 모델을 몇 가지 부분으로 나누겠습니다:
- 토큰(모델이 예측하는 텍스트 조각)
- 컨텍스트 윈도우(한번에 ‘기억’할 수 있는 것)
- 확률(출력의 변동 이유)
- 도구와 검색(모델을 실제 작업과 사실에 연결하는 방법)
- 피드백과 평가(출력을 신뢰 가능하게 만드는 방법)
이 개념들로 프롬프트, UI, 안전장치를 설계하면 AI 기능이 일관되고 신뢰받는 느낌을 줄 수 있습니다.
핵심 루프: 다음 토큰 예측
사람들이 AI가 “생각한다”고 말하면 사람이 하는 식으로 추론한다고 상상하기 쉽습니다. 더 유용한 모델은 간단합니다: 아주 빠른 자동완성(autocomplete)을 토큰 단위로 반복하는 것입니다.
토큰이란 무엇인가?
토큰은 모델이 다루는 텍스트의 단위입니다. 때로는 전체 단어(“apple”), 때로는 단어의 일부(“app” + “le”), 때로는 구두점, 때로는 공백일 수 있습니다. 토크나이저에 따라 분할 방식이 달라지지만 요점은 모델이 문장을 깔끔하게 처리하는 것이 아니라 토큰을 처리한다는 것입니다.
다음 토큰을 예측하고 반복하기
모델의 핵심 루프는 다음과 같습니다:
- 당신이 준 토큰(프롬프트와 이전 대화)을 읽는다.
- 가장 그럴듯한 다음 토큰을 예측한다.
- 그 토큰을 텍스트에 덧붙인다.
- 새로 길어진 텍스트를 입력으로 삼아 다시 실행한다.
그게 전부입니다. 모든 단락, 목록, ‘추론’ 체인은 이 다음 토큰 예측을 여러 번 반복해 만든 결과입니다.
“생각” = 안내된 자동완성
모델은 방대한 텍스트를 학습했기 때문에 설명이 어떻게 흐르는지, 공손한 이메일이 어떻게 쓰이는지, 버그 수정을 보통 어떻게 서술하는지 같은 패턴을 학습합니다. 질문하면 학습한 패턴에 맞고 제공된 컨텍스트와 일치하는 답을 생성합니다.
이 때문에 틀릴 때도 자신감 있고 일관되게 들릴 수 있습니다: 모델은 현실을 확인하려고 최적화된 것이 아니라 다음에 올 텍스트를 예측하도록 최적화되어 있기 때문입니다.
코드도 토큰입니다
코드는 모델에게 특별한 것이 아닙니다. JavaScript, SQL, JSON, 에러 메시지 모두 토큰의 연속입니다. 모델이 유용한 코드를 생성할 수 있는 것은 일반적인 코딩 패턴을 학습했기 때문이지, 팀의 엔지니어처럼 당신의 앱을 진짜로 ‘이해’해서가 아닙니다.
답은 어디에서 오는가: 훈련에서 배운 패턴
사람들이 “모델은 그 답을 어디서 얻었나?”라고 물을 때, 가장 유용한 모델은: 모델은 방대한 예시에서 패턴을 학습했고, 이제 그 패턴을 재조합해 다음에 올 텍스트를 생성한다는 것입니다.
훈련은 암기가 아니라 패턴 학습
훈련 중 모델은 많은 텍스트 조각(책, 기사, 코드, 문서, Q&A 등)을 보여주며 간단한 작업을 반복 연습합니다: 주어진 텍스트에서 다음 토큰을 예측하는 것. 예측이 틀리면 학습 과정이 내부 파라미터를 조금씩 조정해 다음 번에는 더 나은 예측이 나오게 합니다.
시간이 지나며 이 조정들이 누적되어 모델은 다음과 같은 관계들을 인코딩합니다:
- 개념이 보통 어떻게 설명되는지(“컨텍스트 윈도우는…”)
- 어떤 용어들이 함께 등장하는지(API, 인증, 토큰 등)
- 답의 전형적 구조(정의, 단계, 예시)
- 코드의 패턴(SQL 쿼리 작성 방식 등)
왜 일반화할 수 있는가
모델은 통계적 규칙성을 학습하므로 고정된 한 문장을 암기하는 것이 아니라 패턴을 새로 결합할 수 있습니다. "개념을 설명하는 예시"를 많이 보고 "당신의 앱 상황"을 많이 보면, 둘을 합쳐 맞춤형 응답을 생성할 수 있습니다.
이 때문에 LLM은 틈새 제품에 대한 온보딩 이메일을 그럴듯하게 작성하거나 일반적인 API 통합 설명을 특정 스택에 맞게 조정할 수 있습니다. 모델은 단일 문단을 검색해오는 것이 아니라 학습한 패턴에 맞는 새 연속을 생성하는 것입니다.
내장된 정확한 데이터베이스가 아니다
훈련 데이터에 특정 사실(예: 요금제나 내부 정책)이 포함되었다 하더라도 모델이 그것을 신뢰성 있게 ‘조회’할 수 있다고 가정하면 안 됩니다. 훈련은 지식 기반을 인덱싱하는 방식이 아니라 압축과 비슷합니다: 많은 예시가 가중치로 응축되어 미래 예측에 영향을 줍니다.
따라서 모델은 유사한 문맥에서 보통 나타나는 것에 근거해 세부 정보를 추측하고 자신 있게 말할 수 있습니다.
패턴은 유용하지만 항상 옳지는 않다
패턴 학습은 유창하고 관련 있는 텍스트를 생성하는 데 강력하지만, 유창함이 진실과 같지는 않습니다. 모델은 다음과 같은 오류를 범할 수 있습니다:
- 비슷하게 들리는 개념을 섞음
- 누락된 구체 정보를 가장 그럴듯한 추측으로 채움
- 오래되었거나 문맥에 맞지 않는 세부 정보 제공
앱 제작자에게 핵심은: LLM의 답은 보통 학습된 패턴에서 나오지, 검증된 사실에서 나오지 않는다는 점입니다. 정확성이 중요하면 출력물을 자체 데이터와 검사로 근거화해야 합니다(나중 섹션에서 다룹니다).
확률, 무작위성, 그리고 왜 답이 달라지는가
LLM이 응답을 쓸 때 단 하나의 ‘정답 문장’을 데이터베이스에서 꺼내는 것이 아닙니다. 각 단계에서 모델은 가능한 다음 토큰들의 범위를 예측하고, 각 토큰에 확률을 할당합니다.
모델이 항상 가장 가능성이 높은 단일 토큰만 선택하면 결과는 매우 일관되겠지만 반복적으로 단조롭고 어색할 수 있습니다. 대부분 시스템은 대신 확률에서 샘플링을 사용해 제어된 무작위성을 도입합니다.
“창의성 vs 일관성” 조절
두 가지 설정이 출력의 다양성에 영향을 줍니다:
- Temperature: 높일수록 확률이 넓게 퍼져 다양성이 커지고, 낮추면 상위 선택지에 집중되어 일관성이 높아집니다.
- Top‑p (nucleus sampling): 누적 확률이 p가 될 때까지 가장 작은 토큰 집합만 고려합니다(예: 0.9). 낮은 top‑p는 더 안전하고 예측 가능한 선택으로 좁힙니다.
앱을 만들 때 이 노브는 예술적 의미의 ‘창의성’보다 다음 중 선택하는 문제입니다:
- 안정적이고 반복 가능한 표현(고객 지원, 정책, 요약에 적합)
- 광범위한 탐색(브레인스토밍, 네이밍, 다양한 대안 모색에 유용)
확신에 찬 표현이 틀릴 수 있다
모델은 그럴듯한 텍스트를 만들어내는 것을 최적화하므로 근거가 부족해도 단정적으로 말할 수 있습니다. 표현의 확신은 증거가 아닙니다. 그래서 사실 기반 작업에는 종종 근거(검색)나 검증 단계가 필요합니다.
간단한 예: 같은 함수를 여러 방식으로 쓸 수 있다
LLM에 “배열에서 중복을 제거하는 JavaScript 함수를 써줘”라고 하면 다음과 같은 여러 정답을 받을 수 있습니다. 모두 유효합니다:
// Option A: concise
const unique = (arr) => [...new Set(arr)];
// Option B: explicit
function unique(arr) {
return arr.filter((x, i) => arr.indexOf(x) === i);
}
샘플링 설정에 따라 스타일(간결 vs 명시적), 성능·가독성의 트레이드오프, 엣지 케이스 처리 방식 등이 달라질 수 있습니다. 모델이 ‘마음대로 바꾼’ 것이 아니라 여러 높은 확률의 연속 중에서 선택한 것입니다.
컨텍스트 윈도우: AI의 작업 기억
AI 모델이 ‘대화를 기억한다’고 말할 때 실제로는 컨텍스트—지금 볼 수 있는 텍스트(최신 메시지, 시스템 지시, 대화의 일부)—를 말합니다. 컨텍스트 윈도우를 넘어간 내용은 모델의 시야에서 사라집니다.
컨텍스트 윈도우란?
컨텍스트 윈도우는 모델이 한 번에 고려할 수 있는 텍스트의 고정 한계입니다. 대화가 충분히 길어지면 초기 부분이 이 창 밖으로 밀려 나가 보이지 않게 됩니다.
그래서 다음과 같은 현상이 발생합니다:
- 초기에 언급한 요구사항을 잊어버림(“친근한 톤 사용”, “JSON만 반환” 등)
- 이전 결정과 모순되는 답변(다른 변수명, 바뀐 가정)
- 작은 오해들이 쌓여 대화가 서서히 표류함
요약 없이 긴 대화가 표류하는 이유
대화를 계속 이어가면 최근의 대화가 공간을 차지합니다. 중요한 제약이 최근 메시지에 밀려나면 모델은 남아 있는 것만으로 무엇이 중요한지 추론해야 합니다—그 결과 자신 있게 보이지만 핵심 세부를 놓칠 수 있습니다.
실용적인 해결책은 주기적 요약입니다: 목표, 결정사항, 제약을 간결한 블록으로 정리해 다시 주입하세요. 앱에서는 자동 ‘대화 요약’을 만들어 프롬프트에 넣는 방식으로 구현합니다.
프롬프트 팁: 제약은 출력 바로 앞에 배치하세요
모델은 출력을 생성할 바로 앞에 있는 지시를 따르는 경향이 있습니다. 따라서 반드시 지켜야 할 규칙(형식, 톤, 엣지케이스)은 프롬프트의 끝부분—"이제 답을 생성하라" 바로 전—에 두세요.
앱을 설계할 때는 어떤 정보를 항상 컨텍스트에 두어야 하는지(요구사항, 사용자 선호, 스키마)를 결정하고 채팅 이력을 자르거나 간결한 요약을 추가해 보존하세요. 프롬프트 구조에 관해 더 알고 싶다면 /blog/prompting-as-interface-design을 참고하세요.
AI가 왜 틀릴 수 있는가: 유창한 텍스트 vs 현실
LLM은 유능한 개발자가 줄 법한 답처럼 들리게 텍스트를 만들어내는 데 매우 능숙합니다. 그러나 “들어맞는 소리”가 항상 “정확한 답”은 아닙니다. 모델은 다음 토큰을 예측할 뿐, 당신의 코드베이스나 의존성, 실제 동작을 확인하지 않습니다.
기본적으로 실행하지는 않는다
모델이 제안한 수정이나 리팩터, 새 함수는 여전히 텍스트일 뿐입니다. 명시적으로 도구를 연결하지 않으면 앱을 실제로 실행하거나 패키지를 임포트하거나 API를 호출하거나 프로젝트를 컴파일하지 않습니다.
핵심 대조:
- 유창한 텍스트: "이건 타당해 보입니다."
- 실행으로 검증됨: "코드가 컴파일되고, 테스트를 통과하며, 기대한 동작을 합니다."
앱 개발에서 흔한 실패 유형
AI가 실수할 때는 예측 가능한 방식으로 실패합니다:
- 지어낸 API나 파라미터(환각된 라이브러리 메소드, 잘못된 함수 시그니처)
- 잘못된 엣지 케이스(빈 상태, 시간대, null 처리, 페이징 경계)
- 누락된 임포트나 설정(빠진 의존성, 잘못된 파일 경로, 누락된 환경 변수)
- 미묘한 논리 오류(오프바이원, 잘못된 불리언 조건, 일관성 없는 명명)
- 구형 가정(프레임워크 동작 변경, deprecated된 설정)
이 오류들은 주변 설명이 일관되게 보이기 때문에 발견하기 어려울 수 있습니다.
경험적 규칙: 검증 후 신뢰하라
AI 출력을 동료가 로컬에서 실행해보지 않은 빠른 초안으로 취급하세요. 신뢰도는 다음을 수행한 후에 급격히 높아집니다:
- 단위/통합 테스트 실행
- 린트/포맷/빌드 확인
- 실제 입력으로 결과 검증
테스트가 통과하지 않으면 모델의 답은 출발점일 뿐이며 최종 수정이 아닙니다.
도구는 단어를 행동으로 바꾸고 추측을 줄인다
언어 모델은 무엇이 가능할지 제안하는 데 좋지만, 그 자체로는 여전히 텍스트만 생성합니다. 도구는 AI 기반 앱이 그 제안을 검증된 행동으로 바꾸게 해줍니다: 코드 실행, 데이터베이스 쿼리, 문서 검색, 외부 API 호출 등.
실무에서 도구는 무엇을 의미하나
앱 워크플로에서 도구는 보통 다음과 같습니다:
- 코드 실행(파이썬 스니펫 실행, 프로젝트 컴파일, 마이그레이션 수행)
- 문서 검색(내부 지식베이스, 제품 매뉴얼, API 레퍼런스)
- API 호출(결제, 이메일, CRM, 기능 플래그, 분석)
- 파일 읽기/쓰기(설정 편집, 테스트 파일 생성)
중요한 변화는 모델이 결과를 ‘안다고 주장’하는 수준을 넘어서 실제로 확인할 수 있게 된다는 점입니다.
루프: 제안 → 실행 → 조정
유용한 멘탈 모델은 다음과 같습니다:
- 모델이 제안한다(“비활성 사용자 찾으려면 이 SQL을 실행하세요…”)
- 도구가 실행한다(쿼리가 실행되고, 테스트가 돌아가고, 문서가 반환됨)
- 모델이 조정한다(에러 메시지, 쿼리 결과, 실패한 테스트에 기반해 수정)
이 방식이 추측을 줄이는 핵심입니다. 린터가 사용하지 않는 임포트를 보고하면 모델이 코드를 업데이트합니다. 단위 테스트가 실패하면 실패 원인에 맞춰 반복합니다(혹은 왜 못 고치는지 설명합니다).
실제 앱에 해당하는 예
- 데이터베이스 쿼리: 모델이 SQL 초안을 작성하면 DB 도구가 행 수나 에러를 반환하고 모델이 안전하게 쿼리를 수정합니다.
- 린트/포맷: 모델이 코드를 수정한 뒤
eslint/ruff/prettier를 실행해 스타일과 문제를 잡습니다. - 단위 테스트: 모델이 함수와 테스트를 작성하고 테스트를 실행해 실패가 나오면 엣지 케이스를 고칩니다.
권한: 도구를 프로덕션 액세스처럼 다루기
도구는 강력하지만 위험할 수 있습니다. 최소 권한 원칙을 따르세요:
- 기본적으로 AI에 읽기 전용 권한을 주세요(특히 DB).
- API 키는 필요한 권한과 환경으로 범위를 좁히세요.
- 삭제, 환불, 이메일 전송 같은 파괴적 작업은 확인을 요구하세요.
도구가 모델을 더 ‘똑똑하게’ 만들진 않지만 출력이 검증 가능해져 앱의 AI는 더 근거 있게 동작합니다.
검색(RAG): 모델에 올바른 사실을 제공하기
모델은 볼 수 있는 텍스트를 요약·정리·추론하는 데 강력합니다. 하지만 최신 제품 변경사항, 회사 정책, 특정 고객의 계정 정보 같은 것을 자동으로 알지는 못합니다. RAG(검색 증강 생성)는 간단한 해결책입니다: 먼저 관련 사실을 가져오고, 그 다음 모델이 그 사실을 사용해 글을 쓰게 하세요.
쉬운 설명의 RAG
RAG는 ‘오픈북 AI’로 생각하세요. 모델에게 기억에 의존해 답하게 하지 말고, 앱이 관련된 신뢰할 만한 문단(스니펫)을 검색해 프롬프트에 추가합니다. 모델은 제공된 자료에 기반해 응답을 생성합니다.
언제 써야 하나
정확성이 외부 정보에 달려 있을 때 RAG를 기본으로 쓰는 것이 좋습니다:
- 제품 문서, 릴리스 노트, 도움말 기사
- 내부 정책(환불, 보안 규칙, 컴플라이언스 문구)
- 사용자별 데이터(주문, 티켓, 계정 설정)
- 전체 코퍼스를 프롬프트에 모두 넣기 어려울 때
제품 가치가 “우리 비즈니스에 맞는 정확한 답”에 달려 있다면, RAG는 모델이 추측하기를 바라는 것보다 훨씬 안전합니다.
기본 흐름
- 검색: 사용자의 질문을 검색 쿼리로 바꿔 내용 저장소(문서, DB, 벡터 인덱스)에서 상위 관련 청크를 가져옵니다.
- 스니펫/출처 표시: 해당 청크들을 제목, 타임스탬프, 식별자와 함께 모델 입력에 포함해 “어디서 왔는지”를 보여줄 수 있습니다.
- 생성: 모델에게 제공된 컨텍스트만 사용해 답을 만들고, 컨텍스트에 충분한 정보가 없으면 그렇게 명시하게 하세요.
가장 큰 한계
RAG의 성능은 검색 결과 품질에 달려 있습니다. 검색 단계에서 오래되었거나 관련 없는 자료가 올라오면 모델은 자신 있게 잘못된 답을 할 수 있습니다—이제는 잘못된 출처에 ‘근거’를 둔 상태로요. 실제로 검색(청크 분할, 메타데이터, 최신성, 랭킹)을 개선하면 프롬프트 조정보다 정확도가 더 크게 올라갑니다.
에이전트: 모델이 다단계 워크플로를 수행할 때
“에이전트”는 모델이 루프를 돌며 계획을 세우고, 한 단계 실행하고, 결과를 보고 다음 행동을 결정하는 방식입니다. 단일 응답을 넘어서 목표 달성을 위해 반복합니다.
가장 단순한 에이전트 사이클
유용한 멘탈 모델은 다음과 같습니다:
Plan → Do → Check → Revise
- Plan: 목표를 몇 단계로 쪼갭니다(“데이터 찾기, 요약, 이메일 초안 작성”).
- Do: 한 단계를 실행합니다—보통 검색, DB 쿼리, 캘린더 API 호출처럼 도구를 사용하거나 초안을 생성합니다.
- Check: 결과를 목표와 비교합니다(“고객의 마지막 인보이스를 실제로 찾았나?”).
- Revise: 계획을 조정하고 다음 단계를 진행합니다.
이 루프가 단일 프롬프트를 작은 워크플로로 바꿉니다. 에이전트가 더 ‘독립적’으로 느껴지는 이유는 모델이 텍스트를 생성하는 것 외에 행동을 선택하고 순서를 정하기 때문입니다.
종료 조건과 가드레일
에이전트에는 언제 멈출지에 대한 명확한 규칙이 필요합니다. 일반적 종료 조건:
- 성공 기준 달성(예: “이메일 초안에 주문 번호와 배송일이 포함됨”)
- 최대 단계 수 도달
- 토큰 예산 또는 시간 초과
- 특정 도구 호출이 반복적으로 실패
가드레일은 루프를 안전하고 예측 가능하게 만드는 제약입니다: 허용된 도구, 허용된 데이터 출처, 인간의 확인 단계, 출력 형식 제한 등입니다.
무한 루프 방지
에이전트는 언제나 “한 단계 더”를 제안할 수 있기 때문에 실패 모드에 대비해야 합니다. 예산, 타임아웃, 단계 제한이 없으면 에이전트는 반복적으로 비슷한 동작을 하며 비용을 쌓을 수 있습니다.
실용적 기본값: 반복을 상한, 모든 행동 로깅, 도구 결과 검증 요구, 부분 답변과 시도한 내역을 함께 실패로 반환하는 방식으로 우아하게 실패 처리하세요. 이는 에이전트를 끝없이 돌리는 것보다 더 나은 제품 설계인 경우가 많습니다.
Koder.ai 같은 플랫폼의 위치
Koder.ai 같은 비브-코딩 플랫폼과 함께 빌드한다면 이 “에이전트 + 도구” 멘탈 모델이 특히 실용적입니다. 단순히 제안을 주고받는 것 이상으로, 어시스턴트가 기능을 기획하고 React/Go/PostgreSQL 또는 Flutter 컴포넌트를 생성하며 스냅샷과 롤백 같은 체크포인트로 빠르게 이동하되 변경 관리를 잃지 않게 돕는 워크플로를 구현할 수 있습니다.
인터페이스 디자인으로서의 프롬프트
LLM을 앱 기능 뒤에 두면 프롬프트는 단순한 텍스트가 아닙니다. 모델과 제품 사이의 인터페이스 계약입니다: 모델이 무엇을 하려는지, 무엇을 사용할 수 있는지, 그리고 당신의 코드가 신뢰성 있게 소비할 수 있도록 어떻게 응답해야 하는지 정의합니다.
좋은 관점은 프롬프트를 UI 폼처럼 다루는 것입니다. 좋은 폼이 애매함을 줄이고 선택을 제약하며 다음 행동을 명확히 하듯, 좋은 프롬프트도 마찬가지입니다.
실용적인 프롬프트 체크리스트
배포 전에 프롬프트가 다음을 분명히 하는지 확인하세요:
- 목표: 성공이 어떤 모습인지(한 문장).
- 입력: 모델이 받는 데이터(무시할 항목 포함).
- 제약: 톤, 안전 규칙, 길이 제한, 반드시/금지 항목.
- 출력 형식: 앱이 파싱할 수 있도록 정확한 구조.
동작을 고정시키려면 예시를 보여라
모델은 패턴을 따릅니다. 원하는 패턴을 ‘가르치는’ 강력한 방법은 좋은 입력과 좋은 출력의 단일 예시를 포함하는 것입니다(특히 엣지 케이스가 있는 작업일 때). 하나의 예시로도 백앤드 왕복을 줄이고 앱이 표시할 수 없는 형식의 출력을 방지할 수 있습니다.
산문보다 구조화된 출력을 선호하라
다른 시스템이 응답을 읽어야 한다면 구조화하세요. JSON, 테이블, 엄격한 목록을 요구하세요.
You are a helpful assistant.
Task: {goal}
Inputs: {inputs}
Constraints:
- {constraints}
Output format (JSON):
{
"result": "string",
"confidence": "low|medium|high",
"warnings": ["string"],
"next_steps": ["string"]
}
이렇게 하면 “프롬프트”가 예측 가능한 인터페이스 설계로 바뀝니다.
필요할 때는 명확한 질문을 요구하라
명시적 규칙을 하나 추가하세요: “핵심 요구사항이 누락된 경우, 답변하기 전에 명확한 질문을 하라.”
이 한 줄은 자신감 있어 보이지만 틀린 출력을 막아줍니다—모델이 추측하지 말고 멈춰서 필요한 필드를 요청하도록 허용(또는 요구)하기 때문입니다.
프롬프트를 빌드 워크플로에 맞춰라
실무에서는 가장 신뢰할 수 있는 프롬프트가 제품의 빌드 및 배포 방식과 일치합니다. 예를 들어 플랫폼이 먼저 기획하고, 변경을 생성하고, 소스 코드를 내보내거나 배포하는 방식을 지원한다면 프롬프트 계약에도 그 단계를 반영하세요(기획 → 변경점/디프 생성 → 확인 → 적용). Koder.ai의 “플래닝 모드”는 프로세스를 명시적 단계로 바꿔 표류를 줄이고 팀이 배포 전 변경사항을 검토하게 하는 좋은 예입니다.
신뢰를 구축하는 방법: 테스트, 평가, 안전한 앱 사용
신뢰는 모델이 자신감 있게 들린다고 해서 생기지 않습니다. AI 출력을 제품의 다른 의존성과 똑같이 측정하고 모니터링하고 제약하는 방식으로 다뤄야 합니다.
중요한 것만 평가하라(모든 것을 평가할 필요는 없다)
우선 앱이 잘 수행해야 하는 소수의 실제 작업을 골라 반복 가능한 검사로 만드세요:
- 골든 프롬프트: 큐레이션한 프롬프트 목록과 기대 특성(가능하면 정확한 정답)을 릴리스 전마다 실행.
- 단위 테스트 스타일 검사: 모델이 구조화된 데이터(JSON, 필드, 결정)를 반환하면 형태, 필수 키, 값의 범위, 허용 값 등을 검증.
- 스팟 체크: 주간 가벼운 대화 검토로 테스트셋이 놓치는 새로운 실패 모드를 포착.
시간 흐름에 따른 신뢰도 측정
"괜찮은가?" 대신 "얼마나 자주 통과하는가?"를 추적하세요. 유용한 지표:
- 골든 프롬프트에 대한 통과율(카테고리별 포함)
- 지난 주(또는 이전 모델 버전)와의 회귀 검사로 무언의 동작 변화를 포착
- 도구 성공률(사용 가능한 결과를 반환한 도구 호출의 비율)
재현을 위한 충분한 로깅
문제가 생겼을 때 재현할 수 있어야 합니다. 다음을 로깅하세요(적절히 마스킹):
- 프롬프트 템플릿과 최종 렌더된 프롬프트
- 모델 이름/버전, temperature, 시스템 지시
- 도구 호출과 결과(입력, 출력, 오류, 지연)
이렇게 하면 "모델이 바뀌었나, 데이터나 도구가 바뀌었나?"를 구분해 디버깅할 수 있습니다.
프로덕션 앱을 위한 안전 기본
몇 가지 기본값만 지켜도 많은 사고를 예방할 수 있습니다:
- 비밀(API 키, 비밀번호, 프라이빗 토큰)을 프롬프트나 채팅 이력에 절대 넣지 마세요.
- 민감한 출력(개인 데이터, 의료/법적 주장, 정책 위반)은 사용자에게 표시하기 전에 필터링/차단하세요.
- 명확한 대체 경로를 추가하세요: 신뢰도가 낮으면 질문을 하거나, 출처를 보여주거나, 인간에게 이관하세요.
자주 묻는 질문
LLM 맥락에서 “AI가 생각한다”는 말은 실제로 무슨 뜻인가요?
보통 모델이 일관성 있고 목표 지향적인 텍스트를 만들어내며, 그 모습이 이해와 추론처럼 보인다는 의미입니다. 실제로 LLM은 다음 토큰 예측(next-token prediction)을 수행합니다: 주어진 프롬프트, 지시문, 제공된 컨텍스트를 바탕으로 가장 그럴듯한 텍스트 연속을 생성합니다.
앱을 만드는 관점에서 유용한 결론은 “생각한다”는 것은 모델의 내부적 보증이 아니라 당신이 설계하고 제약할 수 있는 출력 행동이라는 점입니다.
토큰이 무엇이고 앱 개발자가 왜 신경 써야 하나요?
토큰은 모델이 처리하고 생성하는 텍스트의 단위입니다(단어 전체, 단어의 일부, 구두점, 공백 등). 모델은 문장이 아니라 토큰 단위로 동작하기 때문에 비용, 한계, 자르기(truncation)가 모두 토큰 기반으로 계산됩니다.
실무적 포인트:
- 짧아 보이는 프롬프트도 코드, JSON, 긴 ID 등으로 인해 토큰이 많을 수 있습니다.
- 출력 및 컨텍스트 한계는 토큰 단위로 측정되므로 UI와 프롬프트 설계를 토큰 측면에서 계획하세요.
같은 프롬프트인데 왜 다른 답이 나오나요?
생성은 확률적이기 때문입니다. 각 단계마다 모델은 여러 가능한 다음 토큰에 확률을 부여하고, 대부분의 시스템은 항상 최상위 토큰만 고르지 않고 그 분포에서 샘플링합니다.
출력을 더 반복 가능하게 만들려면:
- temperature를 낮추세요.
- top‑p를 낮추세요.
- 더 엄격한 형식 지시와 예시를 제공하세요.
- 스키마·규칙·제약 같은 필요한 컨텍스트를 제공해 애매함을 줄이세요.
AI가 자신감 있게 말하는데도 틀릴 수 있는 이유는?
LLM은 그럴듯한 텍스트를 생성하도록 최적화되어 있고, 사실 검증을 하도록 설계된 것은 아닙니다. 훈련 데이터에서 자신감 있게 표현하는 패턴을 많이 배웠기 때문에 실제로는 추측인 내용도 단호하게 말할 수 있습니다.
제품 설계에서는 유창함을 “잘 쓴 글”로 보고, 정확성이 중요할 때는 RAG, 도구, 테스트, 승인 절차 등 검증 수단을 추가하세요.
컨텍스트 윈도우가 무엇이고 긴 대화에 어떤 영향을 미치나요?
컨텍스트 윈도우는 모델이 한 번에 볼 수 있는 최대 텍스트 분량(시스템 지시, 대화 이력, 검색된 스니펫 등)입니다. 대화가 길어지면 초기 정보가 윈도우 밖으로 밀려나 모델이 볼 수 없게 됩니다.
완화 방법:
- 결정사항과 요구사항을 요약해 순환적으로 유지하세요.
- 매 턴마다 핵심 제약을 재주입하세요.
- 앱에서 불필요한 채팅 이력을 잘라내세요.
모델이 내 데이터베이스나 코드베이스, 최신 변경사항을 자동으로 알고 있나요?
기본적으로 모델은 웹을 탐색하거나 데이터베이스를 읽거나 코드를 실행하지 않습니다. 프롬프트에 포함한 정보와 명시적으로 연결한 도구만 볼 수 있습니다.
내부 데이터나 최신 정보가 필요하면, 프롬프트에 직접 넣거나 검색(RAG)·도구 호출을 통해 전달하세요.
언제 도구를 사용해야 하나요, 그냥 모델 텍스트에 의존하면 안 되나요?
결과가 검증된 실제 행동이나 확인이 필요할 때는 도구를 사용하세요. 대표적 예:
- 코드가 실제로 작동하는지 확인하려면 테스트/빌드를 실행하세요.
- 실제 집계 수치가 필요하면 DB를 쿼리하세요.
- 최신 문서를 확인하려면 문서 검색을 사용하세요.
유용한 패턴은 제안 → 실행 → 조정입니다. 모델이 제안하면 도구로 결과를 확인하고, 모델이 그 결과를 반영해 수정하게 하세요.
RAG가 무엇이며 언제 구현할 가치가 있나요?
RAG(검색 증강 생성)는 ‘오픈 북’ 방식의 AI입니다: 앱이 관련된 문단(스니펫)을 검색해 모델 입력에 포함시키면 모델이 그 근거로 답을 생성합니다.
RAG를 쓰면 좋을 때:
- 회사 문서, 릴리스 노트, 도움말 등 정확한 회사 문구가 필요할 때
- 정책·환불·컴플라이언스 같은 내부 규정이 중요한 경우
- 사용자별 데이터(주문, 티켓, 계정 등)를 참조해야 할 때
주의: RAG의 정확성은 검색 품질에 달려 있습니다. 검색 단계의 품질을 개선하면 프롬프트 조정보다 정확도가 더 크게 올라갑니다.
AI 에이전트란 무엇이고, 무한 루프 같은 문제를 어떻게 막나요?
에이전트는 LLM이 루프를 돌며 계획을 세우고, 한 단계 실행하고, 결과를 확인하고, 계획을 수정하는 방식입니다. 단일 응답이 아니라 여러 단계로 목표를 달성합니다.
안전장치:
- 반복 횟수·타임아웃 등 예산 한도를 설정하세요.
- 도구 권한을 최소 권한으로 제한하세요.
- 파괴적 작업(삭제, 환불 등)은 확인 절차를 요구하세요.
- 모든 동작을 로깅해 디버깅 가능하게 만드세요.
프로덕션 앱에서 AI 기능을 신뢰할 수 있게 만들려면 어떻게 하나요?
프롬프트를 인터페이스 계약으로 다루세요: 목표, 입력, 제약, 출력 형식을 분명히 정의해 앱이 결과를 신뢰할 수 있게 만드세요.
실용적 신뢰 구축 수단:
- 골든 프롬프트와 회귀 테스트
- 구조화된 출력(JSON 등)에 대한 스키마 검증
- 프롬프트 템플릿, 모델 버전, 도구 호출/결과 로그(민감 정보는 마스킹)
- 신뢰도가 낮을 때는 명확한 대체 경로(질문, 출처 표시, 인간 개입)