{"id":1705,"date":"2026-08-07T01:12:02","date_gmt":"2026-08-07T01:12:02","guid":{"rendered":"https:\/\/vykhodtsev.dev\/?p=1705"},"modified":"2026-08-07T01:41:00","modified_gmt":"2026-08-07T01:41:00","slug":"1705","status":"publish","type":"post","link":"https:\/\/vykhodtsev.dev\/?p=1705","title":{"rendered":"AI SQL Bot"},"content":{"rendered":"\n<p class=\"wp-block-paragraph\"><strong>What does it actually take to build an AI agent that can reason over a relational database?<\/strong><br>A few months ago, I attended a Snowflake presentation where they demonstrated their AI Agent capabilities. I was genuinely impressed by how naturally an AI agent could interact with enterprise data.<br>That presentation inspired me to build a simplified version myself\u2014not to compete with Snowflake, but to better understand how these systems actually work behind the scenes, what challenges arise during development, and how all the components integrate together.<br>Over the past few months, I&#8217;ve been building a Python-based AI Agent with the following architecture:<br>\u2705 Azure OpenAI as the reasoning engine<br>\u2705 Telegram Bot as the user interface<br>\u2705 MySQL (on-premises) as the data source (my personal laptop)<br>\u2705 Recursive AI \u2194 SQL interaction until the final answer is produced<br>This is a personal learning project built using a demo database and publicly available technologies.<br>The agent doesn&#8217;t simply generate a single SQL statement. Instead, it follows an iterative workflow:<br>The user asks a question in Telegram.<br>The application sends the prompt and database schema to Azure OpenAI.<br>The model decides whether it has enough information or needs additional data from the database.<br>If SQL is required, the application executes it against MySQL.<br>The results are returned to the model.<br>The process repeats until the model can produce the final answer.<br>To make this process transparent and easy to debug, every interaction is stored as a structured JSON conversation log. This has been incredibly useful for understanding the model&#8217;s reasoning and troubleshooting complex scenarios.<br>Along the way, I also implemented:<br>\u2022 Automatic database schema discovery<br>\u2022 Role-based access control (Read \/ Write \/ Admin)<br>\u2022 Automatic user provisioning and management<br>\u2022 Conversation and audit logging<br>\u2022 Recursive execution with configurable iteration limits<br>\u2022 SQL execution <br><br><a href=\"https:\/\/www.linkedin.com\/search\/results\/all\/?keywords=%23ai&amp;origin=HASH_TAG_FROM_FEED\"><strong>#AI<\/strong><\/a> <a href=\"https:\/\/www.linkedin.com\/search\/results\/all\/?keywords=%23aiagents&amp;origin=HASH_TAG_FROM_FEED\"><strong>#AIAgents<\/strong><\/a> <a href=\"https:\/\/www.linkedin.com\/search\/results\/all\/?keywords=%23python&amp;origin=HASH_TAG_FROM_FEED\"><strong>#Python<\/strong><\/a> <a href=\"https:\/\/www.linkedin.com\/search\/results\/all\/?keywords=%23azureopenai&amp;origin=HASH_TAG_FROM_FEED\"><strong>#AzureOpenAI<\/strong><\/a> <a href=\"https:\/\/www.linkedin.com\/search\/results\/all\/?keywords=%23mysql&amp;origin=HASH_TAG_FROM_FEED\"><strong>#MySQL<\/strong><\/a> <a href=\"https:\/\/www.linkedin.com\/search\/results\/all\/?keywords=%23snowflake&amp;origin=HASH_TAG_FROM_FEED\"><strong>#Snowflake<\/strong><\/a> <a href=\"https:\/\/www.linkedin.com\/search\/results\/all\/?keywords=%23dataengineering&amp;origin=HASH_TAG_FROM_FEED\"><strong>#DataEngineering<\/strong><\/a> <a href=\"https:\/\/www.linkedin.com\/search\/results\/all\/?keywords=%23generativeai&amp;origin=HASH_TAG_FROM_FEED\"><strong>#GenerativeAI<\/strong><\/a> <a href=\"https:\/\/www.linkedin.com\/search\/results\/all\/?keywords=%23llm&amp;origin=HASH_TAG_FROM_FEED\"><strong>#LLM<\/strong><\/a> <a href=\"https:\/\/www.linkedin.com\/search\/results\/all\/?keywords=%23openai&amp;origin=HASH_TAG_FROM_FEED\"><strong>#OpenAI<\/strong><\/a> <a href=\"https:\/\/www.linkedin.com\/search\/results\/all\/?keywords=%23automation&amp;origin=HASH_TAG_FROM_FEED\"><strong>#Automation<\/strong><\/a> <a href=\"https:\/\/www.linkedin.com\/search\/results\/all\/?keywords=%23sql&amp;origin=HASH_TAG_FROM_FEED\"><strong>#SQL<\/strong><\/a> <a href=\"https:\/\/www.linkedin.com\/search\/results\/all\/?keywords=%23enterpriseai&amp;origin=HASH_TAG_FROM_FEED\"><strong>#EnterpriseAI<\/strong><\/a> <a href=\"https:\/\/www.linkedin.com\/search\/results\/all\/?keywords=%23softwareengineering&amp;origin=HASH_TAG_FROM_FEED\"><strong>#SoftwareEngineerin<\/strong><\/a><br><\/p>\n\n\n\n<figure data-spectra-id=\"spectra-msi90btb-d3etux\" class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"754\" height=\"307\" src=\"https:\/\/vykhodtsev.dev\/wp-content\/uploads\/2026\/08\/image-1.png\" alt=\"image\" class=\"wp-image-1707\" title=\"AI SQL Bot\" srcset=\"https:\/\/vykhodtsev.dev\/wp-content\/uploads\/2026\/08\/image-1.png 754w, https:\/\/vykhodtsev.dev\/wp-content\/uploads\/2026\/08\/image-1-300x122.png 300w\" sizes=\"auto, (max-width: 754px) 100vw, 754px\" \/><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\"><\/p>\n","protected":false},"excerpt":{"rendered":"<p>What does it actually take to build an AI agent that can reason over a relational database?A few months ago, I attended a Snowflake presentation where they demonstrated their AI Agent capabilities. I was genuinely impressed by how naturally an AI agent could interact with enterprise data.That presentation inspired me to build a simplified version [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":1706,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"site-sidebar-layout":"default","site-content-layout":"","ast-site-content-layout":"default","site-content-style":"default","site-sidebar-style":"default","ast-global-header-display":"","ast-banner-title-visibility":"","ast-main-header-display":"","ast-hfb-above-header-display":"","ast-hfb-below-header-display":"","ast-hfb-mobile-header-display":"","site-post-title":"disabled","ast-breadcrumbs-content":"","ast-featured-img":"","footer-sml-layout":"","ast-disable-related-posts":"","theme-transparent-header-meta":"","adv-header-id-meta":"","stick-header-meta":"","header-above-stick-meta":"","header-main-stick-meta":"","header-below-stick-meta":"","astra-migrate-meta-layouts":"set","ast-page-background-enabled":"default","ast-page-background-meta":{"desktop":{"background-color":"","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""},"tablet":{"background-color":"","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""},"mobile":{"background-color":"","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""}},"ast-content-background-meta":{"desktop":{"background-color":"var(--ast-global-color-5)","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""},"tablet":{"background-color":"var(--ast-global-color-5)","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""},"mobile":{"background-color":"var(--ast-global-color-5)","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""}},"footnotes":""},"categories":[1],"tags":[],"class_list":["post-1705","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-uncategorized"],"spectra_blocks_featured_image_url":{"thumbnail":{"url":"https:\/\/vykhodtsev.dev\/wp-content\/uploads\/2026\/08\/image-150x150.png","width":150,"height":150},"medium":{"url":"https:\/\/vykhodtsev.dev\/wp-content\/uploads\/2026\/08\/image-300x200.png","width":300,"height":200},"medium_large":{"url":"https:\/\/vykhodtsev.dev\/wp-content\/uploads\/2026\/08\/image-768x512.png","width":768,"height":512},"large":{"url":"https:\/\/vykhodtsev.dev\/wp-content\/uploads\/2026\/08\/image-1024x682.png","width":1024,"height":682},"full":{"url":"https:\/\/vykhodtsev.dev\/wp-content\/uploads\/2026\/08\/image.png","width":1280,"height":853}},"spectra_blocks_author_info":{"display_name":"Aleksei","avatar_url":"https:\/\/secure.gravatar.com\/avatar\/198b25ea575ebb3cbd0934cb05fd942d0f256a65d3ff388a161c857e00b092bf?s=96&d=mm&r=g","author_link":"https:\/\/vykhodtsev.dev\/?author=1","description":""},"_links":{"self":[{"href":"https:\/\/vykhodtsev.dev\/index.php?rest_route=\/wp\/v2\/posts\/1705","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/vykhodtsev.dev\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/vykhodtsev.dev\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/vykhodtsev.dev\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/vykhodtsev.dev\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=1705"}],"version-history":[{"count":5,"href":"https:\/\/vykhodtsev.dev\/index.php?rest_route=\/wp\/v2\/posts\/1705\/revisions"}],"predecessor-version":[{"id":1725,"href":"https:\/\/vykhodtsev.dev\/index.php?rest_route=\/wp\/v2\/posts\/1705\/revisions\/1725"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/vykhodtsev.dev\/index.php?rest_route=\/wp\/v2\/media\/1706"}],"wp:attachment":[{"href":"https:\/\/vykhodtsev.dev\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=1705"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/vykhodtsev.dev\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=1705"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/vykhodtsev.dev\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=1705"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}