모호한 데이터베이스 질문 처리
명확화 질문, 스키마 구분, 여러 테이블 조인 추론을 다룹니다.
모호한 데이터베이스 질문 처리은(는) CoddyKit의 무료 AI Agents 강의입니다. 이것은 4개 중 4번째 강의입니다. 아래에서 전체 강의를 무료로 읽을 수 있으며, 내장 코드 에디터와 24/7 AI 튜터와 함께 브라우저에서 직접 실습할 수 있습니다. 이 강의는 AI Agents 학습 경로의 일부이며, 진행 상황이 웹과 CoddyKit 앱에 동기화됩니다. AI Agents 강의에는 총 4개의 강의가 포함되어 있습니다.
NL-to-SQL의 모호성 문제
자연어에는 본질적으로 모호성이 있습니다. 누군가 “최근 주문을 보여 주세요”라고 말하면, 사람은 다음과 같이 묻습니다. 누구를 기준으로 최근인가요? 어느 기간인가요? 어떻게 정렬할까요?
기본값을 조용히 가정하는 에이전트는 사용자가 예상하지 못한 결과를 내놓습니다. 좋은 에이전트는 모호성을 감지하고 구체적인 확인 질문을 합니다.
모호성의 유형
데이터베이스 맥락에서 모호한 질문은 일반적으로 다음 네 가지 범주로 나뉩니다:
- 시간 관련 모호성: '최근', '최신', '오래된', '올해'
- 범위 모호성: '상위 고객' — 어떤 지표를 기준으로 상위인가요?
- 테이블 모호성: 질문에 답할 수 있는 테이블이 여러 개임
- 필터 모호성: '활성 사용자' — 무엇을 기준으로 활성 상태를 정의하나요?
# Examples of each type
ambiguous_examples = {
'temporal': 'Show me recent orders', # last 7 days? 30 days? 1 year?
'scope': 'Who are the top customers?', # by revenue, order count, or recency?
'table': 'Show me user activity', # from users, sessions, or audit_log?
'filter': 'List all active products' # active = in_stock? not discontinued?
}
if __name__ == '__main__':
print('Types of ambiguous questions:')
for kind, example in ambiguous_examples.items():
print(f' {kind}: "{example}"')
LLM으로 모호성 감지
모호성 규칙을 코드에 고정하는 대신 LLM에 모호성을 감지하도록 요청하십시오. 스키마를 제공하고 다음과 같이 물어보십시오. 확정적인 SQL 쿼리를 생성할 만큼 이 질문이 명확한가요?
import json
AMBIGUITY_CHECK_PROMPT = '''You are a SQL assistant. Given a database schema and a user question,
determine if the question is clear enough to write a single correct SQL query.
Schema:
{schema}
Question: {question}
Respond with JSON:
- If clear: {{"ambiguous": false, "sql": "SELECT ..."}}
- If ambiguous: {{"ambiguous": true, "clarification": "What time range counts as recent?",
"options": ["Last 7 days", "Last 30 days", "Last 90 days"]}}
JSON:'''
def check_and_generate(question, schema):
response = llm_call(AMBIGUITY_CHECK_PROMPT.format(
schema=schema, question=question
))
return json.loads(response)명확화 반복
모호성이 감지되면 명확화 반복을 시작하십시오. 사용자에게 구체적인 질문을 하고 답변을 받은 다음, 보강된 맥락을 사용해 SQL 생성을 다시 시도합니다.
반복은 2번의 명확화 단계로 제한하십시오. 질문을 너무 많이 하면 사용자가 불편해합니다.
def nl_to_sql_with_clarification(user_question, schema, conn, ask_user_fn):
for attempt in range(2): # max 2 clarification rounds
result = check_and_generate(user_question, schema)
if not result.get('ambiguous'):
# Clear question — execute
rows = execute_query(conn, result['sql'])
return format_results(rows, user_question)
# Ambiguous — ask user
clarification = result['clarification']
options = result.get('options', [])
user_reply = ask_user_fn(clarification, options)
# Enrich the question with the answer
user_question = f'{user_question} ({clarification}: {user_reply})'
print(f'Enriched question: {user_question}')
# After 2 rounds, generate with best guess
return check_and_generate(user_question, schema)'최근'의 시간적 모호성 해소
'최근', '최신', '이번 주', '새로운'과 같은 시간 관련 단어는 매우 흔하게 사용됩니다. 모호한 용어를 기본 시간 범위에 대응시키는 전용 시간 해석기를 구축하되, 신뢰도가 낮을 때는 LLM이 질문할 수 있도록 하십시오.
from datetime import datetime, timedelta
TEMPORAL_DEFAULTS = {
'recent': 7, # days
'latest': 1, # days
'new': 30,
'old': 365,
'this week': 7,
'this month': 30,
'this year': 365
}
def resolve_temporal(question):
lower = question.lower()
for term, days in TEMPORAL_DEFAULTS.items():
if term in lower:
since = (datetime.now() - timedelta(days=days)).strftime('%Y-%m-%d')
return question + f" ('{term}' means since {since})"
return question
print(resolve_temporal('Show me recent orders'))
# Show me recent orders ('recent' means since 2024-05-22)스키마 모호성 해소: 여러 테이블
질문에 답할 수 있는 테이블이 여러 개라면 에이전트는 어느 테이블이 가장 적절한지 판단해야 합니다. 예를 들어 '사용자 활동'은 sessions, audit_log 또는 user_events에 있을 수 있습니다.
TABLE_SEMANTIC_MAP = {
'user activity': ['sessions', 'user_events', 'audit_log'],
'purchases': ['orders', 'transactions', 'invoices'],
'product catalog': ['products', 'items', 'listings'],
'sign-ups': ['users', 'registrations', 'accounts']
}
def disambiguate_tables(question, schema_dict, ask_user_fn):
lower = question.lower()
for concept, tables in TABLE_SEMANTIC_MAP.items():
if concept in lower:
available = [t for t in tables if t in schema_dict]
if len(available) > 1:
chosen = ask_user_fn(
f"Which table should I query for '{concept}'?",
available
)
return question + f" (use the {chosen} table)"
return question
if __name__ == '__main__':
def ask_user_fn(prompt, options):
print(f'{prompt} -> choosing "{options[0]}" (demo default)')
return options[0]
demo_schema = {'sessions': [], 'transactions': [], 'orders': []}
resolved = disambiguate_tables('Show me user activity', demo_schema, ask_user_fn)
print('Resolved question:', resolved)
'상위 N' 범위 모호성 처리
'상위 고객', '최고의 제품', '가장 활동적인 사용자'라는 표현은 모두 어떤 지표를 기준으로 하는지 알아야 합니다. 한 가지를 조용히 선택하지 말고 사용자에게 지표 선택지를 제시하십시오.
RANKING_AMBIGUITY_PROMPT = '''The question asks for a ranking but the metric is unclear.
Question: {question}
Table columns available: {columns}
List 2-3 reasonable ranking metrics as a JSON array of objects:
[{{"label": "By total revenue", "sql_expr": "SUM(total) DESC"}},
{{"label": "By order count", "sql_expr": "COUNT(*) DESC"}}]
JSON:'''
def resolve_ranking(question, columns, ask_user_fn):
import json
response = llm_call(RANKING_AMBIGUITY_PROMPT.format(
question=question, columns=columns
))
options = json.loads(response)
labels = [o['label'] for o in options]
chosen_label = ask_user_fn('How should I rank the results?', labels)
chosen = next(o for o in options if o['label'] == chosen_label)
return question + f" (rank by: {chosen['sql_expr']})", chosen['sql_expr']지능적인 기본값 제공
매번 사용자에게 묻는 것은 귀찮을 수 있습니다. 더 현명한 방법은 합리적인 기본값을 선택하고, 실행한 다음, 무엇을 가정했는지 사용자에게 알리는 것입니다. 다음과 같은 메모를 포함하십시오. ‘최근’은 최근 30일을 의미한다고 가정했습니다. 다른 기간을 의미하셨나요?
def nl_to_sql_with_assumptions(question, schema, conn):
# Resolve common ambiguities with defaults
enriched = resolve_temporal(question)
result = check_and_generate(enriched, schema)
if result.get('ambiguous'):
# Still ambiguous — pick default option
options = result.get('options', ['the most common interpretation'])
default = options[0]
enriched = enriched + f' ({result["clarification"]}: {default})'
result = check_and_generate(enriched, schema)
rows = execute_query(conn, result['sql'])
answer = format_results(rows, question)
# Append assumption note
if enriched != question:
assumption = enriched[len(question):].strip().strip('()')
answer += f'\n\n[Note: I assumed {assumption}]'
return answer열 수준의 모호성
때로는 모호성이 열 수준에서 발생합니다. '날짜순으로 정렬된 주문을 보여 주세요'라고 하면 어떤 날짜를 의미할까요? created_at, updated_at, shipped_at 또는 delivery_date 중 어느 것일까요?
LLM을 돕고 열 수준의 모호성을 줄이려면 스키마 주입에 열 설명을 포함하십시오.
COLUMN_DESCRIPTIONS = {
('orders', 'created_at'): 'When the order was placed',
('orders', 'updated_at'): 'When the order was last modified',
('orders', 'shipped_at'): 'When the order was shipped to customer',
('orders', 'delivery_date'): 'Expected or actual delivery date'
}
def format_columns_with_descriptions(table, columns):
parts = []
for col in columns:
desc = COLUMN_DESCRIPTIONS.get((table, col['name']), '')
label = f"{col['name']} ({col['type']})"
if desc:
label += f' [{desc}]'
parts.append(label)
return ', '.join(parts)
if __name__ == '__main__':
demo_columns = [
{'name': 'created_at', 'type': 'timestamp'},
{'name': 'shipped_at', 'type': 'timestamp'},
{'name': 'total', 'type': 'float'},
]
print(format_columns_with_descriptions('orders', demo_columns))
모호성 해결 기록
각 유형의 모호성이 얼마나 자주 발생하는지, 어떤 기본값이나 명확화가 선택되었는지 추적하십시오. 이 데이터는 기본값을 개선하고 시간이 지남에 따라 필요한 질문 수를 줄이는 데 도움이 됩니다.
import json
from datetime import datetime
ambiguity_log = []
def log_ambiguity(original_question, clarification, resolution, method):
ambiguity_log.append({
'timestamp': datetime.now().isoformat(),
'question': original_question,
'clarification': clarification,
'resolution': resolution,
'method': method # 'asked_user' | 'default' | 'llm_inferred'
})
# Periodically analyze to improve defaults
def analyze_ambiguity_log():
from collections import Counter
types = Counter(entry['clarification'] for entry in ambiguity_log)
print('Most common ambiguities:')
for q, count in types.most_common(5):
print(f' {count}x: {q}')
if __name__ == '__main__':
log_ambiguity('Show recent orders', 'temporal', 'last 30 days', 'default')
log_ambiguity('Show recent orders', 'temporal', 'last 7 days', 'asked_user')
log_ambiguity('Top customers', 'scope', 'by revenue', 'llm_inferred')
analyze_ambiguity_log()
여러 차례에 걸친 대화 맥락
채팅 인터페이스에서는 이전 대화 차례가 맥락을 제공합니다. 사용자가 이미 “2024년 4분기 데이터를 보고 있어요”라고 말했다면, 이후의 '최근 주문' 관련 질문에는 고정된 30일이 아니라 해당 기간을 기본값으로 사용해야 합니다.
def nl_to_sql_with_context(question, schema, conn, conversation_history):
context_prompt = ''
if conversation_history:
context_prompt = 'Previous conversation context:\n'
for turn in conversation_history[-3:]: # last 3 turns
context_prompt += f"User: {turn['user']}\n"
if 'assumption' in turn:
context_prompt += f"Assumption made: {turn['assumption']}\n"
full_prompt = context_prompt + f'Current question: {question}'
result = check_and_generate(full_prompt, schema)
conversation_history.append({
'user': question,
'sql': result.get('sql', ''),
'assumption': result.get('assumption', '')
})
return result지식 확인
NL-to-SQL 에이전트가 시간 관련 모호성(예: '최근 주문')을 감지했을 때 권장되는 전략은 무엇입니까?
복습: 모호한 질문 처리
NL-to-SQL의 모호성은 시간, 범위, 테이블, 필터의 네 가지 형태로 나타납니다. 가장 좋은 전략은 지능적인 기본값('최근'을 자동으로 최근 30일로 해석), LLM 기반 모호성 감지, 질문이 실제로 불명확할 때의 구체적인 명확화를 결합하는 것입니다.
항상 사용자에게 가정을 알리십시오. 대화 기록을 맥락으로 사용하고, 시간이 지남에 따라 기본값을 개선할 수 있도록 모호성 해결 내용을 기록하십시오.
AI 튜터와 함께 AI Agents을(를) 배우세요 — 무료
브라우저에서 실제 코드를 작성하고 실행하며, 24/7 AI 튜터로부터 즉각적인 도움을 받고, 웹이나 앱에서 중단한 부분부터 계속 학습하세요.
- 코스
- 60
- 레슨
- 239
자주 묻는 질문
“모호한 데이터베이스 질문 처리” 강의는 무료인가요?
네 — “모호한 데이터베이스 질문 처리” 전체 내용을 이 웹사이트에서 무료로 읽을 수 있습니다. 인터랙티브하게 실습하려면(내장 코드 에디터와 24/7 AI 튜터), CoddyKit PRO로 업그레이드하면 AI Agents 강의 전체를 잠금 해제할 수 있습니다. AI Agents 강의에는 총 4개의 강의가 포함되어 있습니다.
“모호한 데이터베이스 질문 처리”에서 뭘 배우나요?
명확화 질문, 스키마 구분, 여러 테이블 조인 추론을 다룹니다. 브라우저에서 직접 실행하는 실습 코드로 AI Agents을(를) 배우며, 24/7 AI 튜터가 강의를 진행하면서 질문에 답변해줍니다.
AI Agents을(를) 시작하는 데 경험이 필요한가요?
사전 경험은 필요하지 않습니다. CoddyKit의 AI Agents은(는) 초급자부터 고급 학습자까지를 위해 구성되어 있으므로, 여기서 시작하거나 처음부터 시작할 수 있으며 자신의 속도대로 진행할 수 있습니다. 이것은 4개 중 4번째 강의입니다.
“모호한 데이터베이스 질문 처리” 강의는 얼마나 걸리나요?
대부분의 CoddyKit 강의는 약 5~10분이 소요됩니다. 각 강의는 간결하고 인터랙티브하여 꾸준한 진행이 가능하며, 웹과 앱에서 중단한 부분부터 바로 시작할 수 있습니다.
이 AI Agents 강의에서 코드를 작성하고 실행할 수 있나요?
네. 모든 AI Agents 강의에는 내장 코드 에디터가 포함되어 있으므로, 브라우저에서 바로 실제 코드를 작성하고 실행한 후 즉시 AI 피드백을 받을 수 있습니다 — 로컬 설정이 필요 없습니다.
이 강의의 모든 강의
- NL-to-SQL 에이전트 작동 원리
- 스키마 이해 및 주입
- SQL 쿼리 생성 및 검증
- 모호한 데이터베이스 질문 처리