Azure OpenAI, LangChain 및 Function Calling을 활용한 안전한 AI 데이터베이스 어시스턴트 구축
Source: Dev.to
원시 CSV 파일부터 프로덕션 수준의 AI 어시스턴트까지—안전하게 데이터를 조회하고 SQL을 환상(허위) 없이 실행합니다.
이 글에서는 다음을 활용해 AI 기반 데이터 분석가를 구축한 과정을 살펴봅니다:
- Azure OpenAI
- LangChain
- LangGraph
- Function Calling
- SQLite
이 어시스턴트는 다음을 수행할 수 있습니다:
- pandas를 사용해 CSV 데이터 분석
- SQL 데이터베이스를 안전하게 쿼리
- 미리 정의된 백엔드 함수를 자동으로 선택
- 결과를 명확히 설명
- 환상(허위)과 위험한 SQL을 방지
🧩 문제 설명
AI 모델과 데이터베이스를 사용할 때 흔히 발생하는 문제는 다음과 같습니다:
- ❌ 허위(환각) SQL 쿼리
- ❌ 안전하지 않은
eval또는 원시 SQL 실행 - ❌ 모델이 접근할 수 있는 범위에 대한 제어 부족
- ❌ 결과가 어떻게 계산되었는지에 대한 설명 부족
목표: 다음을 수행하는 AI 어시스턴트를 구축합니다:
- COVID 데이터에 대한 분석 질문에 답변
- 허용된 도구만 사용
- 절대 추측하지 않음
- 모든 답변을 설명
📊 Dataset
우리는 COVID all‑states history dataset를 사용하며, 다음을 포함합니다:
statedatehospitalizedIncreasepositiveIncrease- …and more
데이터셋은 처음에 다음과 같이 사용됩니다:
- A pandas DataFrame
- A SQLite database
🧱 Architecture Overview
User Question
↓
Azure OpenAI (Assistant / LangChain)
↓
Tool Selection (Function / SQL / DataFrame)
↓
Safe Backend Execution
↓
Result
↓
Final Explanation
Key idea:
- The model decides WHAT to do. → 모델은 무엇을 할지 결정합니다.
- Your backend decides HOW it is done. → 백엔드는 어떻게 수행할지를 결정합니다.
🔹 파트 1: LangChain을 통한 Azure OpenAI와 대화
AzureChatOpenAI를 사용하여 Azure OpenAI에 연결합니다:
llm = AzureChatOpenAI(
azure_endpoint="https://.cognitiveservices.azure.com/",
api_key="YOUR_API_KEY",
api_version="2024-12-01-preview",
model="gpt-4o-mini"
)
정상 동작 확인
response = llm.invoke([
HumanMessage(content="Hello, Azure OpenAI via LangChain!")
])
print(response.content)
🔹 Part 2: DataFrame Agent (CSV Analysis)
CSV 파일을 pandas에 로드하고 제어된 계산을 도구를 통해 노출합니다.
DataFrame Tool
@tool
def run_df(query: str) -> str:
"""Run Python code on the global dataframe `df` and return the result."""
return str(eval(query))
⚠️ Note: In production, replace
evalwith a restricted execution layer.
Enforcing Tool Usage
llm_with_tools = llm.bind_tools([run_df])
프롬프트는 모델에게 다음과 같이 강제합니다:
- 도구 사용
- 실제 pandas 계산 수행
- 결과 설명
🔹 Part 3: CSV → SQL (SQLite) 이동
CSV를 SQLite로 변환:
engine = create_engine("sqlite:///./db/test.db")
df.to_sql(
name="all_states_history",
con=engine,
if_exists="replace",
index=False
)
이제 동일한 데이터셋을 SQL로 조회할 수 있습니다.
🔹 파트 4: LangGraph와 SQL 에이전트
LangGraph를 사용하여 ReAct 에이전트를 생성합니다:
agent_executor_SQL = create_react_agent(
model=llm,
tools=toolkit.get_tools()
)
시스템 프롬프트는 다음을 강제합니다:
- 유효한 테이블만
- 특정 열만
- 허위값 금지
- Markdown 전용 출력
🔹 Part 5: 함수 호출 (Raw SQL 사용 안 함)
모델이 SQL을 생성하도록 하는 대신, 미리 승인된 백엔드 함수를 정의합니다.
Example Functions
def get_hospitalized_increase_for_state_on_date(state_abbr, specific_date):
...
def get_positive_cases_for_state_on_date(state_abbr, specific_date):
...
Function Registry (Critical!)
FUNCTION_MAP = {
"get_hospitalized_increase_for_state_on_date": get_hospitalized_increase_for_state_on_date,
"get_positive_cases_for_state_on_date": get_positive_cases_for_state_on_date,
}
This ensures:
- ✅ Only allowed functions run
- ❌ No arbitrary code execution
🔹 Part 6: Azure OpenAI 함수 호출 (Assistant API 없음)
Use Chat Completions + functions:
response = client.chat.completions.create(
model="gpt-4o-mini",
messages=messages,
functions=functions,
function_call="auto"
)
If the model calls a function:
- 인수 추출
FUNCTION_MAP을 통해 라우팅- 백엔드 로직 실행
- 결과를 다시 전송
- 최종 근거 있는 답변 얻기
🔹 파트 7: Assistant API (지속적인 컨텍스트)
어시스턴트 생성
assistant = client.beta.assistants.create(
name="Covid Data Assistant",
model="gpt-4o-mini",
tools=[{"type": "function", "function": fn} for fn in functions]
)
어시스턴트 루프 (핵심 개념)
while True:
run_status = client.beta.threads.runs.retrieve(...)
if run_status.status == "requires_action":
# extract function name
# dispatch via FUNCTION_MAP
# submit tool output
elif run_status.status == "completed":
break
어시스턴트는 대화 컨텍스트를 기억하면서도 도구 사용을 엄격히 제한하고 안전한 실행을 보장합니다.
🧠 Key Takeaways
- ✅ What This Design Solves
- Prevents SQL hallucinations
- Enforces backend safety
- Keeps AI answers grounded in data
- Scales cleanly as tools grow
🧩 멘탈 모델
| 레이어 | 책임 |
|---|---|
| LLM | 추론 및 의도 |
| Assistant | 도구 선택 |
| Backend | 데이터 접근 |
| Function Map | 보안 |
🎯 언제 무엇을 사용해야 할까?
| 사용 사례 | 최선의 선택 |
|---|---|
| 일회성 쿼리 | Chat + function calling |
| 다중 회전 분석 | Assistant API |
| CSV 탐색 | DataFrame tools |
| 프로덕션 DB | Predefined SQL functions |
🚀 최종 생각
이 접근 방식은 실제 프로덕션 AI 시스템이 구축되는 방식을 반영합니다:
- AI가 무엇을 결정
- 백엔드가 어떻게 제어
핵심 이점:
- 데이터는 권위 있게 유지됩니다
- 설명은 투명하게 유지됩니다
나와 연결하기
함께 멋진 데이터‑science와 AI 프로젝트를 배우고 만들어요!
- LinkedIn:
- GitHub:
📩 아래 댓글 언제든 환영합니다!
