https://eglife.tistory.com/340
PostgreSQL, LLM 연결(5)
PostgreSQL Openai or Llama 연결 Settinghttps://eglife.tistory.com/338 PostgreSQL, LLM 연결(4)1.https://github.com/cloudquery/pg_gpt2.https://github.com/prabin-acharya/pg_gpt3.https://github.com/JelteF/pg_human4. https://github.com/pramsey/pgsql-opena
eglife.tistory.com
현재 검토중인 Model이 Llama3 중 Parameter 8b(The smallest) Model을 다루고 있기 때문에,
이 놈의 Promtpt format을 확인해보려고 한다.
https://www.llama.com/docs/model-cards-and-prompt-formats/meta-llama-3/
Llama 3 | Model Cards and Prompt formats
Special Tokens used with Llama 3. A prompt should contain a single system message, can contain multiple alternating user and assistant messages, and always ends with the last user message followed by the assistant header.
www.llama.com
실제 나의 local 환경에서 Llama model의 Paramter를 확인해보면 아래와 같다.
>>> /show template
{{ if .System }}<|start_header_id|>system<|end_header_id|>
{{ .System }}<|eot_id|>{{ end }}{{ if .Prompt }}<|start_header_id|>user<|end_header_id|>
{{ .Prompt }}<|eot_id|>{{ end }}<|start_header_id|>assistant<|end_header_id|>
{{ .Response }}<|eot_id|>
보기엔 햇갈려보이지만, 그냥 System prompt 따로, User prompt가 따로있는 구조라고 보면 된다.
이것을 좀 자세히 풀어서 쓰면 요렇게 볼 수 있다.
<|begin_of_text|><|start_header_id|>system<|end_header_id|>
{instruction}
Context
{Context}
<|eot_id|><|start_header_id|>user<|end_header_id|>
{qustion}
<|eot_id|><|start_header_id|>assistant<|end_header_id|>
LLM 종류마다 Prompt를 다루는 Template이 조금씩 다를 것이니 잘 참고해야 한다.
나의 경우(Llama3) 아래와 같이 Template 작업을 진행했다.
"{"
"\"model\":\"llama3:latest\","
"\"prompt\":\""
"<|begin_of_text|>"
"<|start_header_id|>system<|end_header_id|>"
"You are a helpful AI assistant for converting SQL query to English text. "
"Here are all the DB tables: %s."
"The user wants only a short summarized explanation (<= 2 sentences),So please produce the minimal English text only, without extra introductions or disclaimers."
"<|eot_id|>"
"<|start_header_id|>user<|end_header_id|>"
"SQL: %s"
"<|eot_id|>"
"<|start_header_id|>assistant<|end_header_id|>"
"Text: "
"\","
"\"max_tokens\":128"
"}"
즉, system prompt 부분에다가 LLM의 역할과 Default로 제공할 수 있는 DB의 Schema를 모두 제공하였고
User Prompt 부분에 User의 Input을 집어 넣었다.
그 뒤에, assistant 부분은 Output 부분이라 신경쓰지 않아도 될 거 같고 max_tokens 저 부분도 그냥 있으나 없으나 같은데 집어넣었다.
일단 쉬운(?) DB와 쉬운(?) query에 대해선 적절히 답변하는 것을 볼 수 있었다.
NL -> SQL | SQL -> NL |
test=# select llama_nl2sql('find all names of deparments'); | test=# select llama_sql2nl('select emp_id from emp;'); |
![]() |
![]() |
다소 허접하지만, 이 정도면 많이 진취적으로 발전한 것이라고 생각한다 .. ㅎㅎ
아래 쪼오금 더 복잡한 Query로도 실험해봤다.
1) SQL -> NL | 2) NL -> SQL |
select e.emp_name,d.dept_name from emp as e join dept as d on e.dept_id = d.dept_id where e.salary > 60000; |
![]() |
![]() |
NL2SQL에선 alias를 지정할 때 as를 쓴다던가, 부등호 ( > , < ) 표시가 누락된 거 외에 대충 맥락은 맞게 SQL Query를 반환했다. Fine-tuning 전혀 없는 모델 치곤 나쁘지 않은 성능이다.
두 번 째 Test Query :
select location, avg(salary) from emp join dept on emp.dept_id = dept.dept_id where dept_name <> 'IT' group by dept.location; |
TEST를 진행해본다.
1) SQL -> NL | 2) NL -> SQL |
select location, avg(salary) from emp join dept on emp.dept_id = dept.dept_id where dept_name <> 'IT' group by dept.location; |
여기서 'IT' 이 부분은 Syntax Error를 피하기 위해서 ''IT'' 이렇게 작은 따옴표를 2번씩 써줘서 Escape해줘야 한다.
![]() |
![]() |
-> Table Alias 처리하는 것만 좀 Tuning되면 얼추 정답은 유추함.
To do -> PSQL 내부에서 Table간 PK/FK 정보도 전할 수 있으려나?
-->psql tool 中 pg_dump를 이용해 Table DDL만 복제해도 그 안에 어지간한 Schema 접오는 다 있다.->GPT검색
KCC논문제출하고 온다고 Update가 좀 늦었다. PostgreSQL을 다루지 않은 주제라 그런가 간만에 PostgreSQL 동네로 돌아오니 뭐가 뭔지 모르겠다. Update가 필요허다..!
일단 DB내 Table/Column 목록을 보는 쿼리는 아래와 같다.
SELECT
concat(table_name,
'(',
string_agg(column_name, ', ' ORDER BY ordinal_position),
')') AS table_def
FROM information_schema.columns
WHERE table_schema NOT IN ('pg_catalog', 'information_schema')
GROUP BY table_name
ORDER BY table_name;
PostgreSQL이고, EMP/DEPT Table 환경 기준 실행결과는 아래와 같다.
Primary Key(PK) 목록을 보는 코드
SELECT
tc.table_name,
string_agg(kcu.column_name, ', ' ORDER BY kcu.ordinal_position) AS pk_cols
FROM information_schema.table_constraints tc
JOIN information_schema.key_column_usage kcu
ON tc.constraint_name = kcu.constraint_name
AND tc.table_schema = kcu.table_schema
WHERE tc.constraint_type = 'PRIMARY KEY'
AND tc.table_schema NOT IN ('pg_catalog', 'information_schema')
GROUP BY tc.table_name
ORDER BY tc.table_name;
Foreign Key(FK) 목록을 보는 코드
SELECT
tc.table_name AS src_table,
kcu.column_name AS src_column,
ccu.table_name AS tgt_table,
ccu.column_name AS tgt_column
FROM information_schema.table_constraints tc
JOIN information_schema.key_column_usage kcu
ON tc.constraint_name = kcu.constraint_name
AND tc.table_schema = kcu.table_schema
JOIN information_schema.constraint_column_usage ccu
ON ccu.constraint_name = tc.constraint_name
AND ccu.table_schema = tc.table_schema
WHERE tc.constraint_type = 'FOREIGN KEY'
AND tc.table_schema NOT IN ('pg_catalog', 'information_schema')
ORDER BY src_table, kcu.ordinal_position;
결론적으로 Llama에 전달되는 Table Schema는 아래와 같다.
dept(dept_id, dept_name, location) emp(emp_id, emp_name, salary, dept_id) PK: dept(dept_id) emp(emp_id) FK: emp(dept_id)->dept(dept_id)
일단 요기까지..!
더 무엇을 알아보고, 무엇을 개발해봐야 할 지 논의가 必

'Data Science > Research' 카테고리의 다른 글
SQL<->NL transfer in PostgreSQL 뭘 더 해야 할까? (0) | 2025.05.12 |
---|---|
Llama3 Prompt Engineering(7) (1) | 2025.04.30 |
SQL2NL Prompt Engineering - KCC(4) Last (0) | 2025.04.18 |
SQL2NL Prompt Engineering - KCC(3) (0) | 2025.04.14 |
English Natural Language Evaluation Matrix (0) | 2025.04.10 |