{"id":2194,"date":"2026-03-12T08:00:00","date_gmt":"2026-03-12T07:00:00","guid":{"rendered":"https:\/\/olgamironczuk.pl\/?p=2194"},"modified":"2026-07-09T05:52:41","modified_gmt":"2026-07-09T04:52:41","slug":"warkan-swiadomy-kosztowo-asystent-ai-dla-bloga","status":"publish","type":"post","link":"https:\/\/olgamironczuk.pl\/en\/warkan-swiadomy-kosztowo-asystent-ai-dla-bloga\/","title":{"rendered":"Warkan \u2013 a Cost-Efficient AI Assistant for the Blog"},"content":{"rendered":"<div class=\"wp-block-columns is-layout-flex wp-container-core-columns-is-layout-8f761849 wp-block-columns-is-layout-flex\">\n<div class=\"wp-block-column is-vertically-aligned-center is-layout-flow wp-block-column-is-layout-flow\" style=\"flex-basis:33.33%\"><div class=\"wp-block-image\">\n<figure class=\"aligncenter size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"426\" height=\"240\" src=\"https:\/\/olgamironczuk.pl\/wp-content\/uploads\/2026\/03\/vieo_portfolio.gif\" alt=\"\" class=\"wp-image-2206\"\/><\/figure>\n<\/div><\/div>\n\n\n\n<div class=\"wp-block-column is-layout-flow wp-block-column-is-layout-flow\" style=\"flex-basis:66.66%\">\n<p class=\"has-small-font-size wp-block-paragraph\"><strong>Project:&nbsp;<\/strong>Warkan \u2013 a Cost-Efficient AI Assistant for the Blog<br><strong>Tools:&nbsp;<\/strong>Python, FastAPI, scikit-learn (TF-IDF), REST API, WordPress API, Cloudflare Workers AI<br><strong>Description:&nbsp;<\/strong>A custom blog chatbot built on a Retrieval-Augmented Generation (RAG) architecture that combines semantic search with responses generated by a language model.<br><strong>Objective:<\/strong>&nbsp;The goal was to build an assistant that answers only using the blog\u2019s real content, while maintaining control over context, system logic, and the cost of model queries.<strong><br>Data:&nbsp;<\/strong>The data is sourced from blog posts dynamically fetched through the WordPress REST API.<br><strong>Repository:<\/strong> <img decoding=\"async\" style=\"width:26px; height:auto; vertical-align:middle; position:relative; top:0px; margin:0 6px 0 6px;\" src=\"http:\/\/olgamironczuk.pl\/wp-content\/uploads\/2026\/01\/github-mark.png\" alt=\"GitHub\"> <a href=\"https:\/\/github.com\/Waderlla\/Warkan_-_Cost-Aware_AI_Assistant_for_Blog_Search\" data-type=\"link\" data-id=\"https:\/\/github.com\/Waderlla\/Warkan_-_Cost-Aware_AI_Assistant_for_Blog_Search\" target=\"_blank\" rel=\"noreferrer noopener\">See on GitHub <\/a><\/p>\n\n\n\n<div class=\"wp-block-buttons is-content-justification-right is-layout-flex wp-container-core-buttons-is-layout-89b4c9e9 wp-block-buttons-is-layout-flex\">\n<div class=\"wp-block-button btn-olive\"><a class=\"wp-block-button__link wp-element-button\" href=\"https:\/\/olgamironczuk.pl\/en\/warkan\/\">Try Warkan<\/a><\/div>\n<\/div>\n\n\n\n<div style=\"height:17px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n<\/div>\n<\/div>\n\n\n\n<!--more Czytaj wi\u0119cej-->\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">Introduction<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\" style=\"font-size:15px\">Warkan is a backend application designed to search blog content and generate summaries based on the most relevant posts.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\" style=\"font-size:15px\">The solution does not rely solely on a generative language model. A key component is the retrieval layer, which selects the relevant context before it is passed to the model. This ensures that responses are grounded in specific content rather than generated freely.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\" style=\"font-size:15px\">The project runs as a public web application connected to the website.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Data<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\" style=\"font-size:15px\">The data is sourced from blog posts dynamically fetched through the WordPress REST API.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\" style=\"font-size:15px\">The scope of processed information includes:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li style=\"font-size:15px\">post title,<\/li>\n\n\n\n<li style=\"font-size:15px\">excerpt,<\/li>\n\n\n\n<li style=\"font-size:15px\">full content,<\/li>\n\n\n\n<li style=\"font-size:15px\">URL address.<\/li>\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\" style=\"font-size:15px\">The content is cleaned of HTML and converted into plain text before further analysis.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Solution Architecture<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\" style=\"font-size:15px\">The project was designed as a lightweight Retrieval-Augmented Generation (RAG) architecture consisting of three layers.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\" style=\"font-size:16px\"><strong>1) Data Layer<\/strong><\/p>\n\n\n\n<p class=\"wp-block-paragraph\" style=\"font-size:15px\">The application retrieves posts from a selected blog category and stores them in the server\u2019s memory.<br>The index is built based on the article\u2019s title, excerpt, and full content.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\" style=\"font-size:15px\">A TTL cache mechanism is used to define the maximum lifetime of the index. Once it expires, the data is refreshed.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\" style=\"font-size:16px\"><strong>2) Retrieval Layer<\/strong><\/p>\n\n\n\n<p class=\"wp-block-paragraph\" style=\"font-size:15px\">Based on the content, a TF-IDF index is created using the scikit-learn library.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\" style=\"font-size:15px\">The user\u2019s query is transformed into the same vector representation, and cosine similarity is then calculated against all posts.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\" style=\"font-size:15px\">Only the most relevant results (Top-K) that meet the minimum similarity threshold are returned.<br>Additionally, a contextual snippet is generated around the matched keyword.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\" style=\"font-size:16px\"><strong>3) Generation Layer<\/strong><\/p>\n\n\n\n<p class=\"wp-block-paragraph\" style=\"font-size:15px\">Only the selected search results along with their contextual snippets are passed to the language model.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\" style=\"font-size:15px\">The prompt was designed to:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li style=\"font-size:15px\">prevent the addition of new sources,<\/li>\n\n\n\n<li style=\"font-size:15px\">enforce the exact number of described results,<\/li>\n\n\n\n<li style=\"font-size:15px\">control the length of the response,<\/li>\n\n\n\n<li style=\"font-size:15px\">maintain a consistent response language.<\/li>\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\" style=\"font-size:15px\">This approach reduces the risk of hallucinations and increases the system\u2019s predictability.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Design Decisions<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\" style=\"font-size:15px\">The project implements solutions that improve stability and control over system behavior:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li style=\"font-size:15px\">separation of the retrieval layer from the generation layer,<\/li>\n\n\n\n<li style=\"font-size:15px\">limiting the number of results passed to the model,<\/li>\n\n\n\n<li style=\"font-size:15px\">a minimum similarity threshold,<\/li>\n\n\n\n<li style=\"font-size:15px\">control over the length of the provided context,<\/li>\n\n\n\n<li style=\"font-size:15px\">handling situations where the API returns no response,<\/li>\n\n\n\n<li style=\"font-size:15px\">storing the index in memory to reduce operational costs.<\/li>\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\" style=\"font-size:15px\">The priority was ensuring system predictability and maintaining conscious control over queries sent to the language model.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Results<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\" style=\"font-size:15px\">Application:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li style=\"font-size:15px\">dynamically retrieves and indexes blog content,<\/li>\n\n\n\n<li style=\"font-size:15px\">searches posts based on semantic similarity,<\/li>\n\n\n\n<li style=\"font-size:15px\">generates concise summaries based exclusively on the retrieved content,<\/li>\n\n\n\n<li style=\"font-size:15px\">operates as a public component of the website,<\/li>\n\n\n\n<li style=\"font-size:15px\">includes a mechanism that controls costs and the frequency of data refresh.<\/li>\n\n\n\n<li><\/li>\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\">Further Development<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\" style=\"font-size:15px\">Planned extensions:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li style=\"font-size:15px\">multilingual support,<\/li>\n\n\n\n<li style=\"font-size:15px\">more precise context filtering.<\/li>\n<\/ul>\n\n\n\n<div style=\"height:63px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<figure class=\"wp-block-video aligncenter wolf-portfolio-video\"><video height=\"1080\" style=\"aspect-ratio: 1920 \/ 1080;\" width=\"1920\" autoplay loop muted src=\"https:\/\/olgamironczuk.pl\/wp-content\/uploads\/2026\/03\/vieo_portfolio.webm\" playsinline><\/video><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\"><\/p>","protected":false},"excerpt":{"rendered":"<p>Projekt:&nbsp;Warkan &#8211; \u015awiadomy kosztowo asystent AI dla blogaNarz\u0119dzia:&nbsp;Python, FastAPI, scikit-learn (TF-IDF), REST API, WordPress API, Cloudflare Workers AIOpis:&nbsp;Autorski chatbot blogowy oparty na architekturze Retrieval-Augmented Generation (RAG), \u0142\u0105cz\u0105cy wyszukiwanie semantyczne z generowaniem odpowiedzi przez model j\u0119zykowy.Cel:&nbsp;Stworzenie asystenta, kt\u00f3ry odpowiada wy\u0142\u0105cznie na podstawie rzeczywistych tre\u015bci bloga, z kontrol\u0105 kontekstu, logiki dzia\u0142ania i koszt\u00f3w zapyta\u0144 do modelu.Dane:&nbsp;\u0179r\u00f3d\u0142em danych&#8230;<\/p>","protected":false},"author":1,"featured_media":2206,"comment_status":"closed","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[33,38,21,17,32],"tags":[],"class_list":["post-2194","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-ai","category-automatyzacja","category-projekty","category-python","category-rest-api"],"_links":{"self":[{"href":"https:\/\/olgamironczuk.pl\/en\/wp-json\/wp\/v2\/posts\/2194","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/olgamironczuk.pl\/en\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/olgamironczuk.pl\/en\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/olgamironczuk.pl\/en\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/olgamironczuk.pl\/en\/wp-json\/wp\/v2\/comments?post=2194"}],"version-history":[{"count":10,"href":"https:\/\/olgamironczuk.pl\/en\/wp-json\/wp\/v2\/posts\/2194\/revisions"}],"predecessor-version":[{"id":2308,"href":"https:\/\/olgamironczuk.pl\/en\/wp-json\/wp\/v2\/posts\/2194\/revisions\/2308"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/olgamironczuk.pl\/en\/wp-json\/wp\/v2\/media\/2206"}],"wp:attachment":[{"href":"https:\/\/olgamironczuk.pl\/en\/wp-json\/wp\/v2\/media?parent=2194"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/olgamironczuk.pl\/en\/wp-json\/wp\/v2\/categories?post=2194"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/olgamironczuk.pl\/en\/wp-json\/wp\/v2\/tags?post=2194"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}