1"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([["3461"],{9222(e,t,n){n.r(t),n.d(t,{metadata:()=>a,default:()=>d,frontMatter:()=>r,contentTitle:()=>i,toc:()=>u,assets:()=>o});var a=JSON.parse('{"id":"sql-llm/SQL-LLM Translator","title":"Natural Language Database Query Tool","description":"A small portfolio project demonstrating a two-way LLM pipeline: natural language \u2192 SQL \u2192 results \u2192 natural language.","source":"@site/docs/sql-llm/SQL-LLM Translator.md","sourceDirName":"sql-llm","slug":"/sql-llm/SQL-LLM Translator","permalink":"/ai-solutions-consultant/docs/sql-llm/SQL-LLM Translator","draft":false,"unlisted":false,"tags":[],"version":"current","frontMatter":{},"sidebar":"tutorialSidebar","previous":{"title":"Future Strategy and Scale","permalink":"/ai-solutions-consultant/docs/jetkvm_llm/Future Strategy and Scale"},"next":{"title":"Code","permalink":"/ai-solutions-consultant/docs/sql-llm/Code"}}'),l=n(4848),s=n(8453);let r={},i="Natural Language Database Query Tool",o={},u=[{value:"What it does",id:"what-it-does",level:2},{value:"Project structure",id:"project-structure",level:2},{value:"Notes:",id:"notes",level:2}];function c(e){let t={code:"code",h1:"h1",h2:"h2",header:"header",li:"li",ol:"ol",p:"p",ul:"ul",...(0,s.R)(),...e.components};return(0,l.jsxs)(l.Fragment,{children:[(0,l.jsx)(t.header,{children:(0,l.jsx)(t.h1,{id:"natural-language-database-query-tool",children:"Natural Language Database Query Tool"})}),"\n",(0,l.jsx)(t.p,{children:"A small portfolio project demonstrating a two-way LLM pipeline: natural language \u2192 SQL \u2192 results \u2192 natural language."}),"\n",(0,l.jsx)(t.p,{children:"This is a quick demonstration of not just prompting Claude, but showcasing how to validate Claude output against a deterministic schema. This way we can work with databases where accuracy and trust are paramount."}),"\n",(0,l.jsx)(t.p,{children:"For production and future development, this query tool can be extended to local LLM models or gated online LLM models."}),"\n",(0,l.jsx)(t.h2,{id:"what-it-does",children:"What it does"}),"\n",(0,l.jsxs)(t.ol,{children:["\n",(0,l.jsx)(t.li,{children:'You ask a question in plain English (e.g. "which clients have overdue invoices over 1000 euros?")'}),"\n",(0,l.jsx)(t.li,{children:"Claude translates the question into a SQL query against a mock accounting database"}),"\n",(0,l.jsx)(t.li,{children:"The query runs against a local SQLite database"}),"\n",(0,l.jsx)(t.li,{children:"Claude translates the raw SQL results back into a plain-language answer"}),"\n",(0,l.jsx)(t.li,{children:"The UI shows all three layers: question, SQL, and answer."}),"\n",(0,l.jsx)(t.li,{children:"The result can be verified, not just trusted blindly."}),"\n"]}),"\n",(0,l.jsx)(t.h2,{id:"project-structure",children:"Project structure"}),"\n",(0,l.jsxs)(t.ul,{children:["\n",(0,l.jsxs)(t.li,{children:[(0,l.jsx)(t.code,{children:"setup_database.py"})," \u2014 creates and seeds the SQLite database (Step 1)"]}),"\n",(0,l.jsxs)(t.li,{children:[(0,l.jsx)(t.code,{children:"engine.py"})," \u2014 the core NL\u2192SQL\u2192NL pipeline logic (Step 2)"]}),"\n",(0,l.jsxs)(t.li,{children:[(0,l.jsx)(t.code,{children:"app.py"})," \u2014 Streamlit interface (Step 3)"]}),"\n"]}),"\n",(0,l.jsx)(t.h2,{id:"notes",children:"Notes:"}),"\n",(0,l.jsxs)(t.ul,{children:["\n",(0,l.jsx)(t.li,{children:"The tool deliberately shows the generated SQL alongside the answer. So we purposefully let a human verify the query is actually correct before trusting the answer."}),"\n",(0,l.jsx)(t.li,{children:"We constrain the SQL generation to a known schema so it doesn't hallucinate tables or columns that don't exist"}),"\n",(0,l.jsx)(t.li,{children:"We split the request into two separate calls with different jobs (generation vs. summarization) rather than one messy prompt trying to do both"}),"\n",(0,l.jsx)(t.li,{children:"We test a handful of edge-case questions (ambiguous wording, questions\nwith no matching data, multi-table joins) and document any cases where\nthe generated SQL was wrong."}),"\n",(0,l.jsx)(t.li,{children:"For a real deployment handling actual client financial data, a\nlocal or EU-hosted model would likely be the more compliance-appropriate\nchoice given data residency expectations in Finnish/EU accounting\ncontexts. This version uses Claude for reliability during prototyping."}),"\n"]})]})}function d(e={}){let{wrapper:t}={...(0,s.R)(),...e.components};return t?(0,l.jsx)(t,{...e,children:(0,l.jsx)(c,{...e})}):c(e)}},8453(e,t,n){n.d(t,{R:()=>r,x:()=>i});var a=n(6540);let l={},s=a.createContext(l);function r(e){let t=a.useContext(s);return a.useMemo(function(){return"function"==typeof e?e(t):{...t,...e}},[t,e])}function i(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(l):e.components||l:r(e.components),a.createElement(s.Provider,{value:t},e.children)}}}]);
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.