LLMs and SQL
Quick Summary
LangChain은 SQL 환각과 컨텍스트 길이 제약, 실행 오류에 대응하기 위해 스키마·표본 데이터 제공, 조회 결과 제한, 오류 기반 쿼리 수정을 제시한다.
🖼️ 인포그래픽

🖼️ 4컷 인포그래픽

💡 한 줄 요약
LangChain은 SQL 환각과 컨텍스트 길이 제약, 실행 오류에 대응하기 위해 스키마·표본 데이터 제공, 조회 결과 제한, 오류 기반 쿼리 수정을 제시한다.
📌 핵심 요약
- LLM은 SQL을 작성할 수 있지만 존재하지 않는 테이블·컬럼을 생성하거나 잘못된 쿼리와 예상 밖의 결과를 내놓을 수 있으며, 데이터베이스 정보를 제공할 때도 컨텍스트 길이 제약이 따른다.
- 원문에 인용된 Rajkumar 등의 OpenAI Codex 연구에서는 CREATE TABLE 형식의 스키마 설명이 가장 좋은 성능을 보였고, 예시 데이터는 3행이 최적이었으며 더 많은 데이터가 성능을 낮추기도 했다.
- LangChain은 스키마와 표본 행을 자동으로 제공하며, 사용자 정의 테이블 정보로 대표적인 데이터 형식을 보완하거나 LLM에 보이는 컬럼을 제한하고 실제 데이터 대신 모의 데이터를 제시할 수 있다.
- 조회 결과가 다음 LLM 입력 한도를 넘지 않도록 필요한 컬럼과 반환 행 수를 제한하며, 국가별 총매출 예시에서는 top_k로 관리하는 한도에 따라 상위 10개 결과를 반환한다.
- 오류가 발생하면 원래 쿼리와 오류 로그를 LLM에 전달해 수정을 시도한다. Track.ArtistId 오류 예시는 Album을 경유하는 조인으로 바뀌기 시작하지만, 제공된 원문이 잘려 최종 실행 성공은 확인되지 않는다.
🧩 주요 포인트
- CREATE TABLE과 대표 표본으로 실제 구조·값을 설명 → SQL 생성의 근거를 강화하되, 3행 연구 결과와 사용자 정의 정보의 필요성을 함께 고려.
- 컨텍스트 길이 제약이 데이터베이스 설명과 조회 결과 모두에 적용 → 입력 정보의 선별과 필요한 컬럼·반환 행 수 제한을 함께 다룰 필요.
- 오류 로그를 활용한 쿼리 수정 → 실패 후 재시도가 가능하지만, Track.ArtistId 사례의 불완전한 기록만으로 복구 성공을 단정할 수 없음.
🧠 상세 정리
1. 자연어로 SQL 데이터에 접근하려는 배경
2023년 3월 13일 LangChain 팀이 공개한 이 글은 SQL 통합에 참여한 커뮤니티 구성원 Francisco Ingham과 Jon Luo의 경험을 바탕으로 작성됐다. 기업의 가치 있는 데이터 상당 부분이 전통적으로 SQL 데이터베이스에 저장되어 있으며, 이를 조회하고 이해하도록 돕는 비즈니스 인텔리전스 도구가 널리 사용된다는 배경에서 출발한다. LLM이 SQL을 이해하고 작성할 수 있게 되면서 자연어로 데이터베이스와 상호작용하는 방식도 가능해졌지만, 실제 데이터에 맞는 쿼리를 안정적으로 만드는 데는 별도의 문제가 따른다. LangChain은 이러한 접근을 지원하는 여러 SQL 체인과 SQL 에이전트를 제공하며, 글에는 파이썬과 자바스크립트 구현에 관한 링크가 제시된다.
2. 환각, 컨텍스트 길이, 실행 실패라는 세 가지 문제
첫 번째 문제는 LLM이 실제로 존재하지 않는 테이블이나 컬럼을 만들어 내는 환각으로, SQL 형태를 갖춘 문장이라도 대상 데이터베이스에서는 유효하지 않을 수 있다는 점이다. 이를 줄이려면 데이터베이스에 무엇이 존재하는지 알려주고 그 정보에 맞춰 쿼리를 작성하도록 해야 한다. 그러나 데이터베이스의 정보를 모두 전달하려 하면 모델이 처리할 수 있는 텍스트 양을 제한하는 컨텍스트 길이 문제가 발생한다. 세 번째로는 이러한 정보를 제공하더라도 모델이 잘못된 SQL을 작성하거나 실행 가능한 쿼리에서 예상과 다른 결과를 얻을 수 있다. 따라서 원문은 데이터베이스 설명, 전달 정보의 크기 조절, 실패 이후의 수정이라는 서로 연결된 과제를 구분해 다룬다.
3. 데이터 분석가의 탐색과 수정 과정을 활용
원문은 해결책을 찾기 위해 사람이 비즈니스 질문에 답하려고 데이터베이스를 조회하는 과정을 살펴본다. 데이터 분석가는 본격적인 쿼리를 작성하기 전에 테이블 스키마를 확인하거나 일부 행을 조회해 실제 데이터의 구조와 표현 방식을 익힌다. 이 과정에서 모든 데이터나 수천 행을 한꺼번에 읽기보다는 탐색 결과를 상위 일부 행으로 제한하거나 요약 통계를 확인한다. 오류가 발생했을 때도 작업을 바로 포기하지 않고 오류에서 원인을 파악한 뒤 쿼리를 다시 작성한다. 이러한 행동을 LLM의 작업 과정에 반영하는 것이 글의 기본 접근이며, 이후 설명되는 스키마와 표본 제공, 결과 크기 제한, 오류 기반 수정은 각각 이 분석 과정의 일부에 대응한다.
4. CREATE TABLE로 스키마와 관계를 전달
데이터베이스를 프롬프트로 설명할 때는 테이블 구조, 데이터 예시, 해당 데이터베이스에 적합한 쿼리 예시 등을 포함할 수 있으며, 원문은 Chinook 데이터베이스를 사례로 사용한다. 과거 LangChain은 테이블 이름과 컬럼 이름, 각 컬럼의 자료형을 나열하는 방식으로 구조를 제공했다. 원문에 인용된 Rajkumar 등의 연구는 여러 프롬프트 구성을 비교했으며, OpenAI Codex에 CREATE TABLE 명령을 제공했을 때 가장 좋은 성능을 얻었다고 보고한다. 이 형식은 컬럼 이름과 자료형뿐 아니라 기본 키와 외래 키, 참조 관계까지 함께 표현한다. 제시된 Track 테이블 정의에는 MediaType, Genre, Album을 참조하는 외래 키가 포함되어 있어, 단순한 컬럼 목록보다 테이블 사이의 관계를 구체적으로 전달한다.
5. 표본 데이터 3행의 효과와 정보량의 한계
스키마에 실제 데이터 예시를 더하면 모델이 컬럼에 저장된 값의 표현 방식을 이해하는 데 도움이 된다. 예를 들어 Track의 Composer 컬럼에서 작곡가를 검색하려면 이름이 전체 이름인지 약어인지, 여러 표현이 함께 사용되는지를 아는 것이 유용하다. 원문에 인용된 연구에서는 CREATE TABLE 설명 뒤에 SELECT 문과 표본 행을 제공했을 때 일관된 성능 향상이 나타났으며, 예시 3행이 최적이고 정보를 더 추가하면 성능이 떨어지기도 했다. LangChain은 이러한 연구 결과를 기본 설정에 반영했으며, 예제에서는 sample_rows_in_table_info를 3으로 지정한다. 출력된 표본은 전체 이름으로 나열된 작곡가, 값이 없는 경우, 약어와 여러 구분 기호가 포함된 경우를 보여주며, 구조 설명만으로는 알 수 없는 데이터 형태를 보완한다.
6. 사용자 정의 정보로 대표성과 데이터 노출 조절
자동으로 선택한 첫 몇 행이 데이터의 중요한 특징을 보여주지 못한다면 직접 작성한 테이블 설명과 표본으로 이를 대체할 수 있다. Track의 Composer 컬럼에서는 여러 작곡가를 쉼표 대신 슬래시로 구분하는 사례가 111번째 행에서 처음 나타나므로, 첫 3행만 제공하는 설정으로는 이 형식을 전달하지 못한다. 원문은 슬래시가 들어간 표본을 직접 포함하고 TrackId, Name, Composer만 제시하는 사용자 정의 정보의 예를 보여준다. 이 기능은 대표적인 값의 표현을 보완하는 동시에 LLM에 보이는 컬럼을 제한하는 데도 사용할 수 있다. 또한 API로 보내고 싶지 않은 민감한 데이터가 있다면 실제 데이터 대신 모의 데이터를 제공할 수 있다고 설명하며, 이는 모델에 전달하는 설명과 표본을 구성하는 기능으로 제시된다.
7. 후속 LLM 입력을 고려한 조회 결과 제한
체인이나 에이전트에서 SQL 조회 결과는 다른 LLM 호출의 입력으로 사용되므로, 반환 결과가 너무 크면 다음 모델의 입력 한도를 초과할 수 있다. 원문은 이를 방지하기 위해 필요한 컬럼을 최소한으로 선택하고 반환 행 수도 적절히 제한하도록 LLM에 지시하는 방식을 권한다. 국가별 총매출과 가장 많이 지출한 고객의 국가를 묻는 예시에서는 국가 수를 질문에 명시하지 않았지만, 쿼리가 매출을 내림차순으로 정렬하고 LIMIT 10을 적용한다. 실제 쿼리는 Invoice와 Customer를 연결해 국가별 합계를 계산하며, 관측 결과에서는 미국이 약 523.06으로 가장 높은 값을 보인다. 이 예시의 반환 개수 한도는 top_k 매개변수로 관리할 수 있으며, 데이터베이스 설명뿐 아니라 실행 결과의 크기도 컨텍스트 제약에 맞춰 조절해야 한다는 논점을 보여준다.
8. 오류 로그를 통한 수정 시도와 사례의 확인 범위
원문은 생성된 SQL이 잘못되어 실행 중 오류가 발생하면 원래 쿼리와 오류 로그를 LLM에 보내 원인을 이해하고 수정하도록 하는 접근을 설명한다. 제시된 사례에서는 Track에 없는 ArtistId 컬럼으로 Artist와 직접 조인하려다 해당 컬럼이 없다는 오류가 발생한다. 이후 query_checker_sql_db를 호출하지만, 제시된 검사 도구의 출력에는 여전히 Track.ArtistId를 참조하는 같은 문제가 남아 있다. 그다음 query_sql_db에 전달하기 시작한 쿼리는 Artist와 Album을 먼저 연결하고 다시 Track을 연결하는 형태로 바뀐다. 다만 제공된 원문은 이 조인 조건을 작성하는 도중 끝나므로 완성된 쿼리와 재실행 결과는 확인할 수 없으며, 여기서 확인되는 것은 오류를 활용한 수정 시도와 조인 경로의 변경까지다.
🧾 핵심 주장 / 시사점
- 데이터베이스 설명의 효과는 정보량만으로 결정되지 않는다. 3행 표본의 연구 결과와 111번째 행에 나타나는 표현 차이는 간결함과 대표성을 함께 고려해야 함을 보여준다.
- 컨텍스트 관리는 쿼리 생성 전의 스키마·표본 선택과 실행 후의 결과 제한을 모두 포함한다.
- 오류를 전달해 수정하는 절차와 실제 복구 성공은 구분해야 한다. 제공된 사례에서는 검사 도구 출력에 문제가 남아 있고 최종 실행 결과도 제시되지 않는다.
✅ 액션 아이템
- CREATE TABLE과 3행 표본을 바탕으로 데이터베이스 설명을 구성하고, 대표성이 부족한 부분은 사용자 정의 테이블 정보로 보완.
- 컨텍스트 길이 제약에 맞춰 필요한 컬럼과 반환 행 수를 제한하고 top_k 설정을 검토.
- Track.ArtistId 같은 실행 오류는 원래 쿼리와 오류 로그를 활용해 수정을 시도하고, 재실행 결과로 복구 여부를 확인.
❓ 열린 질문
- 3행 표본이 실제 데이터의 표현을 충분히 보여주지 못할 때 사용자 정의 테이블 정보에 어떤 예시를 포함해야 할까?
- 국가별 총매출 조회에서 top_k로 제한한 상위 10개 결과가 질문에 답하기에 충분한가?
- Track.ArtistId 오류 이후 Album을 경유하도록 변경한 쿼리의 최종 실행 결과는 무엇인가?