<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>LLM on Ash Tewari</title><link>https://www.tewari.info/tag/llm/</link><description>Recent content in LLM on Ash Tewari</description><generator>Hugo -- gohugo.io</generator><language>en-US</language><lastBuildDate>Fri, 25 Sep 2026 02:56:11 +0000</lastBuildDate><atom:link href="https://www.tewari.info/tag/llm/feed.xml" rel="self" type="application/rss+xml"/><item><title>Agentic finetuning using a custom harness</title><link>https://www.tewari.info/2026/09/24/agentic-finetuning-using-a-custom-harness/</link><pubDate>Fri, 25 Sep 2026 02:56:11 +0000</pubDate><guid>https://www.tewari.info/2026/09/24/agentic-finetuning-using-a-custom-harness/</guid><description>&lt;p&gt;The goal was to figure out whether a small model running on my own hardware could do the job of intent classification and structured parameter extraction  well enough for one of my use-cases - read a request like &amp;ldquo;add 8 spare tent stakes to the camping box&amp;rdquo; and turn it into something the application can act on.&lt;/p&gt;&#10;&lt;p&gt;I created an agentic fine-tuning and evaluation loop with a custom evaluation harness: an AI agent proposes one change at a time, a custom evaluation harness measures it against a frozen test set, and every run gets appended to a log with its settings, result and next decision. The agent does the all the work of dataset generation, training, evaluation and diagnosis.&lt;/p&gt;&#10;&lt;h2 id="setup"&gt;Setup&#10;&lt;/h2&gt;&lt;p&gt;I built a fixed test set of 45 requests covering nine intents, five cases each, and froze it. Every model, change and training run was measured against those same 45 cases. The output metrics of each run were: intent accuracy, meaning did it pick the right action, and parameter accuracy, meaning did it extract the right details. A third important number is: fallbacks, the count of cases where the model declined to answer and returned &amp;ldquo;unclear.&amp;rdquo;&lt;/p&gt;&#10;&lt;p&gt;The OpenAI baseline (gpt-5.6-luna) was created and frozen. It scored 93.33% intent and 71.11% parameter accuracy with no fallbacks.&lt;/p&gt;&#10;&lt;p&gt;All local training ran on a consumer RTX 3060, in &lt;a class="link" href="https://learn.microsoft.com/en-us/windows/wsl/about" target="_blank" rel="noopener"&#10; &gt;WSL2&lt;/a&gt; with &lt;a class="link" href="https://docs.nvidia.com/cuda/wsl-user-guide/" target="_blank" rel="noopener"&#10; &gt;CUDA&lt;/a&gt;. &lt;a class="link" href="https://arxiv.org/abs/2106.09685" target="_blank" rel="noopener"&#10; &gt;LoRA&lt;/a&gt; &lt;a class="link" href="https://www.cactuscompute.com/blog/finetuning-needle" target="_blank" rel="noopener"&#10; &gt;fine-tuning&lt;/a&gt;, rank 16, alpha 32, learning rate 1e-4, batch size 4. A 15-epoch run takes about 20 minutes.&lt;/p&gt;&#10;&lt;p&gt;The entire source, including training data, eval harness, scripts and agent skill is on GitHub - &lt;a class="link" href="https://github.com/ashtewari/needle-tuner" target="_blank" rel="noopener"&#10; &gt;needle-tuner&lt;/a&gt;.&lt;/p&gt;&#10;&lt;figure&gt;&lt;img src="https://www.tewari.info/wp-content/needle-finetune-gpu-usage.png"&gt;&#10;&lt;/figure&gt;&#10;&#10;&lt;h2 id="part-1---needle2"&gt;Part 1 - needle2&#10;&lt;/h2&gt;&lt;p&gt;The first local comparison with &lt;a class="link" href="https://cactuscompute.com/blog/needle-2" target="_blank" rel="noopener"&#10; &gt;needle2&lt;/a&gt; model from &lt;a class="link" href="https://cactuscompute.com/needle" target="_blank" rel="noopener"&#10; &gt;Cactus&lt;/a&gt;. It scored 4.44% intent accuracy. The problem turned out to be how I was asking the question. I had given the model one abstract, generic &amp;ldquo;classify this&amp;rdquo; tool. I replaced it with eight concrete tools, one for each real action the application supports.&lt;/p&gt;&#10;&lt;p&gt;The result went to 62.22% intent and 68.89% parameter accuracy.&lt;/p&gt;&#10;&lt;p&gt;With this reasonable starting point, I &lt;a class="link" href="https://www.cactuscompute.com/blog/finetuning-needle" target="_blank" rel="noopener"&#10; &gt;fine-tuned&lt;/a&gt; on a small purpose-built training set and ran a structured loop: change one thing, measure against the frozen test set, write down the result.&lt;/p&gt;&#10;&lt;table&gt;&#10;&#9;&lt;thead&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;th&gt;Needle2 configuration&lt;/th&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;th&gt;Intent&lt;/th&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;th&gt;Parameter&lt;/th&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&lt;/thead&gt;&#10;&#9;&lt;tbody&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Base model, redesigned tools, no training&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;62.22%&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;68.89%&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Best fine-tuned run (5 epochs, rank 8)&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;64.44%&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;62.22%&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Longer training (30 epochs)&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;57.78%&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;64.44%&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Heavier defaults&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;42.22%&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;51.11%&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&lt;/tbody&gt;&#10;&lt;/table&gt;&#10;&lt;p&gt;The best training result gained two points on intent accuracy over no training at all, and lost six on parameters. More training made things worse. The heaviest run also refused to answer far more often, with 15 fallbacks against 9 for the untrained model. The results were noisy enough to make any single comparison suspect. Two runs of the identical best configuration measured 64.44% and 60.00%, so I stopped treating one good run as evidence of anything. Validation loss kept improving while held-out accuracy got worse. Had I watched the training dashboard instead of the frozen test set, I would have shipped a regression. I stopped at this point.&lt;/p&gt;&#10;&lt;h2 id="part-2---needle3"&gt;Part 2 - needle3&#10;&lt;/h2&gt;&lt;p&gt;A new version of the model family had shipped in the mean time, with a different architecture and a different native engine. Untrained, &lt;a class="link" href="https://cactuscompute.com/needle" target="_blank" rel="noopener"&#10; &gt;needle3&lt;/a&gt; measured 71.11% intent and 66.67% parameter accuracy with 7 fallbacks. I modified the agentic loop to support the new model and executed again.&lt;/p&gt;&#10;&lt;p&gt;A one-epoch smoke test scored 68.89% and 73.33%, which is one run on one epoch and proves nothing on its own. A full 30-epoch run at the wrapper defaults scored 71.11% and 66.67%, identical to the untrained base. However, the per-intent breakdown had shifted underneath, some intents up and some down, while the totals stayed flat. Validation loss bottomed out at epoch 13 and climbed for the remaining 17 epochs while training loss kept falling. Same &lt;a class="link" href="https://developers.google.com/machine-learning/crash-course/overfitting" target="_blank" rel="noopener"&#10; &gt;overfitting&lt;/a&gt; pattern &lt;a class="link" href="https://cactuscompute.com/blog/needle-2" target="_blank" rel="noopener"&#10; &gt;needle2&lt;/a&gt; had shown.&lt;/p&gt;&#10;&lt;h2 id="the-issue"&gt;The issue&#10;&lt;/h2&gt;&lt;p&gt;Instead of tuning another hyperparameter, I stopped reading aggregate scores and started reading individual failures.&lt;/p&gt;&#10;&lt;p&gt;The training data and the held-out test set agreed on which intent was correct. They disagreed on the convention for writing the parameters down.&lt;/p&gt;&#10;&lt;p&gt;The first problem was descriptive adjectives. For delete requests, the test set strips condition words from item names, so &amp;ldquo;the broken toaster&amp;rdquo; is expected to yield &amp;rsquo;toaster&amp;rsquo;. All 12 authored delete rows in my training data did the opposite, keeping &amp;lsquo;cracked mixing bowl&amp;rsquo; and &amp;rsquo;expired pain reliever&amp;rsquo; intact.&lt;/p&gt;&#10;&lt;p&gt;The second problem was a wrong key name. For inventory-viewing requests, the training data used a &amp;rsquo;location&amp;rsquo; key for the container slot while every other intent, and the test set, used &amp;lsquo;boxLabel&amp;rsquo;. It also carried a &amp;lsquo;scope&amp;rsquo; key that appears in zero held-out cases.&lt;/p&gt;&#10;&lt;p&gt;The model was learning my convention faithfully and being marked wrong for it, on 100% of those cases. That also explains why longer training hurt: more epochs meant learning the wrong answer more thoroughly.&lt;/p&gt;&#10;&lt;h2 id="the-fix"&gt;The Fix&#10;&lt;/h2&gt;&lt;p&gt;I corrected 12 delete rows and 20 view-inventory rows, regenerated the derived datasets, re-pinned the integrity hashes and re-ran the validation suite. No hyperparameter change and dropped Epoch count from 30 to 15, taken from the previous run&amp;rsquo;s validation-loss minimum.&lt;/p&gt;&#10;&lt;p&gt;Result: 82.22% intent and 75.56% parameter accuracy, 6 fallbacks.&lt;/p&gt;&#10;&lt;table&gt;&#10;&#9;&lt;thead&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;th&gt;Run&lt;/th&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;th&gt;Intent&lt;/th&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;th&gt;Parameter&lt;/th&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;th&gt;Fallbacks&lt;/th&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&lt;/thead&gt;&#10;&#9;&lt;tbody&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Needle2 base&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;62.22%&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;68.89%&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;9&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Needle2 best fine-tune&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;64.44%&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;62.22%&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;not recorded&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Needle3 base&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;71.11%&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;66.67%&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;7&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Needle3 fine-tuned, original data, 30 epochs&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;71.11%&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;66.67%&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;6&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Needle3 fine-tuned, corrected data, 15 epochs&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;82.22%&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;75.56%&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;6&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;OpenAI (frozen baseline)&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;93.33%&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;71.11%&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;0&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&lt;/tbody&gt;&#10;&lt;/table&gt;&#10;&lt;p&gt;That is 11 points of intent accuracy over its own base model and 20 over &lt;a class="link" href="https://cactuscompute.com/blog/needle-2" target="_blank" rel="noopener"&#10; &gt;needle2&lt;/a&gt;&amp;rsquo;s base. It is also the first time a local model beat the hosted API on parameter accuracy, 75.56% against 71.11%. Intent accuracy is still 11 points behind.&lt;/p&gt;&#10;&lt;p&gt;The per-intent movement matches the diagnosis. Delete went from 80%/40% to 100%/80%. Search went from 60%/60% to 100%/100%. Update improved as well, since the bare-noun convention is shared by every intent that names an item.&lt;/p&gt;&#10;&lt;p&gt;&lt;a class="link" href="https://developers.google.com/machine-learning/crash-course/overfitting" target="_blank" rel="noopener"&#10; &gt;Validation loss&lt;/a&gt; behaved differently too. With the corrected data it declined every one of the 15 epochs, with none of the mid-run turnaround the unfixed run showed. The contradictory labels had been generating the &lt;a class="link" href="https://developers.google.com/machine-learning/crash-course/overfitting" target="_blank" rel="noopener"&#10; &gt;overfitting&lt;/a&gt; signal themselves.&lt;/p&gt;&#10;&lt;h2 id="next"&gt;Next&#10;&lt;/h2&gt;&lt;p&gt;Parameter extraction already beats the API. Intent classification is 11 points behind, and most of the remaining gap sits in one diagnosed failure mode: deciding whether a vague request is actionable.&lt;/p&gt;&#10;&lt;p&gt;The next lever is contrastive training examples sitting right on that boundary. After that the options get expensive: changes to how the model produces its answers, training that explicitly teaches it what a wrong answer looks like, or a different architecture.&lt;/p&gt;&#10;&lt;p&gt;Hyperparameter tuning and the size of the training dataset should also be revisited to explore further improvements to intent classification.&lt;/p&gt;&#10;&lt;p&gt;Because the same 45 cases were used to decide which experiment to run next, they are now a &lt;a class="link" href="https://developers.google.com/machine-learning/crash-course/overfitting/dividing-datasets" target="_blank" rel="noopener"&#10; &gt;model-selection set rather than an unbiased final exam&lt;/a&gt;. Before anyone calls this production-ready it has to be tested against a separate set of cases it has never influenced.&lt;/p&gt;&#10;&lt;p&gt;The project also produced a reproducible pipeline along the way. A frozen test set, hash-pinned datasets, a documented training process, a log of every attempt including the failures, and a default path that validates without training and without calling paid APIs. That infrastructure is the reason the annotation issue was discoverable at all.&lt;/p&gt;&#10;</description></item><item><title>WhichBox - AI Assistant App</title><link>https://www.tewari.info/2024/08/04/whichbox-ai-assistant-app/</link><pubDate>Sun, 04 Aug 2024 17:37:56 +0000</pubDate><guid>https://www.tewari.info/2024/08/04/whichbox-ai-assistant-app/</guid><description>&lt;p&gt;Do you remember which one of those boxes in the garage has your old phone? Or that toy your child wants to play with again? Or the tripod you need for your weekend trip? Oh what about that massager that you could really use right now! You would probably have to dig through those boxes to find it. Same problem when moving. There are always some boxes that you don&amp;rsquo;t want to open right away, but you wish you could open just the right one when you need something.&lt;/p&gt;&#10;&lt;p&gt;I have created &lt;a class="link" href="https://whichbox.streamlit.app/" target="_blank" rel="noopener"&#10; &gt;WhichBox&lt;/a&gt;- your AI Assistant to find that box. It uses latest Vision AI models to help you find things quickly. Here&amp;rsquo;s what you do -&lt;/p&gt;&#10;&lt;ol&gt;&#10;&lt;li&gt;Take pictures of the content inside each labelled box to create an inventory.&lt;/li&gt;&#10;&lt;li&gt;Use WhichBox to easily identify the box containing the item you are looking for.&lt;/li&gt;&#10;&lt;/ol&gt;&#10;&lt;p&gt;You can check it out here - &lt;a class="link" href="https://whichbox.streamlit.app/" target="_blank" rel="noopener"&#10; &gt;https://whichbox.streamlit.app/&lt;/a&gt;&lt;/p&gt;&#10;&lt;p&gt;The demo has four photos of labelled boxes with some content in them. Note that there can be multiple photos of the same box. You can take photos as you are filling up the box to capture things at the bottom.&lt;/p&gt;&#10;&lt;figure&gt;&lt;img src="https://www.tewari.info/wp-content/image-47.png"&gt;&#10;&lt;/figure&gt;&#10;&#10;&lt;p&gt;You can ask for a specific thing, like &amp;ldquo;Find Fitbit&amp;rdquo; or just &amp;ldquo;fitbit&amp;rdquo;&lt;/p&gt;&#10;&lt;figure&gt;&lt;img src="https://www.tewari.info/wp-content/image-48.png"&gt;&#10;&lt;/figure&gt;&#10;&#10;&lt;p&gt;You can go for a general category, like &amp;ldquo;Camera Equipment&amp;rdquo;&lt;/p&gt;&#10;&lt;figure&gt;&lt;img src="https://www.tewari.info/wp-content/image-49.png"&gt;&#10;&lt;/figure&gt;&#10;&#10;&lt;p&gt;You can get all boxes containing &amp;ldquo;USB Adapters&amp;rdquo;&lt;/p&gt;&#10;&lt;figure&gt;&lt;img src="https://www.tewari.info/wp-content/image-50.png"&gt;&#10;&lt;/figure&gt;&#10;&#10;&lt;p&gt;You can look for &amp;ldquo;Groot&amp;rdquo; or if you can&amp;rsquo;t remember the name of a specific toy then you can look for &amp;ldquo;all toys of movie characters&amp;rdquo;&lt;/p&gt;&#10;&lt;figure&gt;&lt;img src="https://www.tewari.info/wp-content/image-51.png"&gt;&#10;&lt;/figure&gt;&#10;&#10;&lt;p&gt;For now, you can bring your own API Key and use your own photos to try this out.&lt;/p&gt;&#10;&lt;p&gt;WhichBox : &lt;a class="link" href="https://whichbox.streamlit.app/" target="_blank" rel="noopener"&#10; &gt;https://whichbox.streamlit.app/&lt;/a&gt;&lt;/p&gt;&#10;</description></item><item><title>AI Powered Bookshelf</title><link>https://www.tewari.info/2024/04/28/ai-powered-bookshelf/</link><pubDate>Mon, 29 Apr 2024 00:25:55 +0000</pubDate><guid>https://www.tewari.info/2024/04/28/ai-powered-bookshelf/</guid><description>&lt;p&gt;Bookshelf is a Generative AI application built as a rudimentary, but fairly capable, &lt;a class="link" href="https://docs.llamaindex.ai/en/stable/use_cases/q_and_a/" target="_blank" rel="noopener"&#10; &gt;RAG&lt;/a&gt; implementation written in &lt;a class="link" href="https://www.python.org/doc/" target="_blank" rel="noopener"&#10; &gt;python&lt;/a&gt;. It can use an open source LLM model (running locally or in the cloud) or a GPT model via OpenAI&amp;rsquo;s API.&lt;/p&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;The application is created using &lt;a class="link" href="https://streamlit.io/" target="_blank" rel="noopener"&#10; &gt;streamlit&lt;/a&gt;.&lt;/li&gt;&#10;&lt;li&gt;I used &lt;a class="link" href="https://www.llamaindex.ai/" target="_blank" rel="noopener"&#10; &gt;llama-index&lt;/a&gt; for orchestrating the loading of documents into the &lt;a class="link" href="https://en.wikipedia.org/wiki/Vector_database" target="_blank" rel="noopener"&#10; &gt;vector database&lt;/a&gt;. Only TokenTextSplitter is currently used. It does not optimize for PDF, html and other formats.&lt;/li&gt;&#10;&lt;li&gt;&lt;a class="link" href="https://www.trychroma.com/" target="_blank" rel="noopener"&#10; &gt;ChromaDb&lt;/a&gt; is the vector database to store the embedding vectors and metadata of the document nodes.&lt;/li&gt;&#10;&lt;li&gt;You can use any open source embeddings model from &lt;a class="link" href="https://huggingface.co/models?other=embeddings" target="_blank" rel="noopener"&#10; &gt;HuggingFace&lt;/a&gt;.&lt;/li&gt;&#10;&lt;li&gt;Bookshelf will automatically use the GPU when creating local embeddings, if the GPU is available on your machine.&lt;/li&gt;&#10;&lt;li&gt;You can use &lt;a class="link" href="https://platform.openai.com/docs/guides/embeddings" target="_blank" rel="noopener"&#10; &gt;OpenAI embeddings&lt;/a&gt; as well. There is no way to use a specific OpenAI embedding model or configure the parameters yet.&lt;/li&gt;&#10;&lt;li&gt;Use OpenAI API or any OpenAI compatible LLM API (using &lt;a class="link" href="https://lmstudio.ai/" target="_blank" rel="noopener"&#10; &gt;LMStudio&lt;/a&gt;, &lt;a class="link" href="https://ollama.com/" target="_blank" rel="noopener"&#10; &gt;Ollama&lt;/a&gt; or &lt;a class="link" href="https://github.com/oobabooga/text-generation-webui" target="_blank" rel="noopener"&#10; &gt;text-generation-webui&lt;/a&gt;) of your choice.&lt;/li&gt;&#10;&lt;li&gt;There is a live demo on streamlit cloud - &lt;a class="link" href="https://bookshelf.streamlit.app/" target="_blank" rel="noopener"&#10; &gt;https://bookshelf.streamlit.app/&lt;/a&gt;&lt;/li&gt;&#10;&lt;li&gt;The demo allows only OpenAI integration. You can run it locally for accessing Open Source embedding models and LLMs.&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&#10; &lt;blockquote&gt;&#10; &lt;p&gt;Live demo - &lt;a class="link" href="https://bookshelf.streamlit.app/" target="_blank" rel="noopener"&#10; &gt;https://bookshelf.streamlit.app/&lt;/a&gt;&lt;/p&gt;&#10;&#10; &lt;/blockquote&gt;&#10;&lt;p&gt;You will need your OpenAI api key for the demo.&lt;/p&gt;&#10;&lt;figure&gt;&lt;img src="https://www.tewari.info/wp-content/image-39.png"&gt;&#10;&lt;/figure&gt;&#10;&#10;&lt;p&gt;If you are running it locally, you will have the option of using an Open Source LLM instance via an API Url. In the screenshot, I am using an open source Embedding Model from HuggingFace (sentence-transformers/all-mpnet-base-v2) and The local LLM server at http://localhost:1234/v1&lt;/p&gt;&#10;&lt;figure&gt;&lt;img src="https://www.tewari.info/wp-content/image-40.png"&gt;&#10;&lt;/figure&gt;&#10;&#10;&lt;p&gt;Collections tab shows all collections in the database. It also shows the names of all the files in the selected collection. You can inspect individual chunks for the metadata and text of each chunk. You can delete all contents of the collection &lt;strong&gt;(&lt;/strong&gt; &lt;strong&gt;there is no warning&lt;/strong&gt; &lt;strong&gt;)&lt;/strong&gt;.&lt;/p&gt;&#10;&lt;figure&gt;&lt;img src="https://www.tewari.info/wp-content/image-38.png"&gt;&#10;&lt;/figure&gt;&#10;&#10;&lt;p&gt;You can modify the collection name to create a new collection. Multiple files can be uploaded at the same time. You can specify if you want to extract metadata from the file contents. &lt;strong&gt;Enabling this option can add significant cost&lt;/strong&gt; because it employs Extractors which use LLM to generate title, summaries, keywords and questions for each document.&lt;/p&gt;&#10;&lt;figure&gt;&lt;img src="https://www.tewari.info/wp-content/image-41.png"&gt;&#10;&lt;/figure&gt;&#10;&#10;&lt;p&gt;On the Retrieve tab, you can query chunks which are semantically related to your query.&lt;/p&gt;&#10;&lt;figure&gt;&lt;img src="https://www.tewari.info/wp-content/image-43.png"&gt;&#10;&lt;/figure&gt;&#10;&#10;&lt;p&gt;On the Prompt tab, you can prompt your LLM. The context as well as the Prompt Template is editable.&lt;/p&gt;&#10;&lt;figure&gt;&lt;img src="https://www.tewari.info/wp-content/image-44.png"&gt;&#10;&lt;/figure&gt;&#10;&#10;&lt;p&gt;Here is an example of using the context retrieved from chunks in the Vector database to query the LLM.&lt;/p&gt;&#10;&lt;figure&gt;&lt;img src="https://www.tewari.info/wp-content/image-45.png"&gt;&#10;&lt;/figure&gt;&#10;&#10;&lt;p&gt;This inference was performed using &lt;a class="link" href="https://huggingface.co/microsoft/Phi-3-mini-4k-instruct-gguf" target="_blank" rel="noopener"&#10; &gt;Phi3&lt;/a&gt; model running locally on LMStudio.&lt;/p&gt;&#10;&lt;figure&gt;&lt;img src="https://www.tewari.info/wp-content/image-46.png"&gt;&#10;&lt;/figure&gt;&#10;&#10;&lt;p&gt;Code is on Github - &lt;a class="link" href="https://github.com/ashtewari/bookshelf" target="_blank" rel="noopener"&#10; &gt;https://github.com/ashtewari/bookshelf&lt;/a&gt;&lt;/p&gt;&#10;&lt;p&gt;Have fun!&lt;/p&gt;&#10;</description></item><item><title>Iterative Prompt Engineering with LLMStudio</title><link>https://www.tewari.info/2024/02/04/iterative-prompt-engineering-with-llmstudio/</link><pubDate>Mon, 05 Feb 2024 01:10:11 +0000</pubDate><guid>https://www.tewari.info/2024/02/04/iterative-prompt-engineering-with-llmstudio/</guid><description>&lt;p&gt;Creating the ideal prompt can be the key to transforming a less than average outcome into one that is remarkably relevant. Discovering the right prompt often involves numerous revisions and a method of trial and error. I felt the need to refer to my past attempts, modifications made to prompts, LLM models I tried and other LLM settings as well relative cost of these combinations. There are a few options to help with this : &lt;a class="link" href="https://github.com/microsoft/promptflow" target="_blank" rel="noopener"&#10; &gt;promptflow&lt;/a&gt;, &lt;a class="link" href="https://www.langchain.com/langsmith" target="_blank" rel="noopener"&#10; &gt;langsmith&lt;/a&gt;, &lt;a class="link" href="https://github.com/TensorOpsAI/LLMStudio" target="_blank" rel="noopener"&#10; &gt;LLMStudio&lt;/a&gt; and others.&lt;/p&gt;&#10;&lt;p&gt;I tried LLMStudio and promptflow. This article is about LLMStudio.&lt;/p&gt;&#10;&lt;p&gt;If you are installing LLMStudio on Windows, use &lt;a class="link" href="https://learn.microsoft.com/en-us/windows/wsl/" target="_blank" rel="noopener"&#10; &gt;WSL&lt;/a&gt;. Here are the steps :&lt;/p&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;Create a folder on your machine.&lt;/li&gt;&#10;&lt;li&gt;Create .env file here with following content:&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;OPENAI_API_KEY=&amp;#34;sk-api_key&amp;#34;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;ANTHROPIC_API_KEY=&amp;#34;sk-api_key&amp;#34;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ul&gt;&#10;&lt;li&gt;Enter wsl and create a new python environment with conda&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;(base) PS c:\code\llmstudio&amp;gt; wsl&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;(base) ash@DESKTOP:/mnt/d/code/llmstudio$ conda activate lmstd&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;LLMStudio runs on &lt;a class="link" href="https://bun.sh/" target="_blank" rel="noopener"&#10; &gt;Bun&lt;/a&gt;. Bun is a javascript runtime like &lt;a class="link" href="https://nodejs.org/en" target="_blank" rel="noopener"&#10; &gt;Node&lt;/a&gt;.&lt;/p&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;Instructions for installing bun on windows :&lt;br&gt;&#10;&lt;a class="link" href="https://bun.sh/docs/installation#windows" target="_blank" rel="noopener"&#10; &gt;https://bun.sh/docs/installation#windows&lt;/a&gt;&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;sudo apt-get install unzip&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;powershell -c &amp;#34;irm bun.sh/install.ps1|iex&amp;#34;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;figure&gt;&lt;img src="https://www.tewari.info/wp-content/image-27.png"&gt;&#10;&lt;/figure&gt;&#10;&#10;&lt;ul&gt;&#10;&lt;li&gt;Install Node v18, if you run into ReferenceError: Request is not defined    at Object.&lt;anonymous&gt; (/home/ash/miniconda3/lib/python3.11/site-packages/llmstudio/ui/node_modules/next/dist/server/web/spec-extension/request.js:28:27)&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;figure&gt;&lt;img src="https://www.tewari.info/wp-content/image-31.png"&gt;&#10;&lt;/figure&gt;&#10;&#10;&lt;ul&gt;&#10;&lt;li&gt;Start LLMStudio&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;figure&gt;&lt;img src="https://www.tewari.info/wp-content/image-32.png"&gt;&#10;&lt;/figure&gt;&#10;&#10;&lt;figure&gt;&lt;img src="https://www.tewari.info/wp-content/image-33.png"&gt;&#10;&lt;/figure&gt;&#10;&#10;&lt;figure&gt;&lt;img src="https://www.tewari.info/wp-content/image-34.png"&gt;&#10;&lt;/figure&gt;&#10;&#10;&lt;figure&gt;&lt;img src="https://www.tewari.info/wp-content/image-35.png"&gt;&#10;&lt;/figure&gt;&#10;&#10;&lt;p&gt;Export the execution data as csv file by clicking on [Export data] button. This data includes the input, output, LLM model, Input and Output tokens as well as cost.&lt;/p&gt;&#10;&lt;figure&gt;&lt;img src="https://www.tewari.info/wp-content/image-37.png"&gt;&#10;&lt;/figure&gt;&#10;&#10;&lt;p&gt;References&lt;br&gt;&#10;&lt;a class="link" href="https://www.tensorops.ai/post/what-is-llmstudio" target="_blank" rel="noopener"&#10; &gt;What is LLMstudio?&lt;/a&gt;&lt;br&gt;&#10;&lt;a class="link" href="https://github.com/TensorOpsAI/LLMstudio" target="_blank" rel="noopener"&#10; &gt;LLMstudio&lt;/a&gt; by &lt;a class="link" href="http://tensorops.ai/" target="_blank" rel="noopener"&#10; &gt;TensorOps&lt;/a&gt;&lt;br&gt;&#10;&lt;a class="link" href="https://docs.llmstudio.ai/quickstart" target="_blank" rel="noopener"&#10; &gt;LLM Studio Quickstart&lt;/a&gt;&lt;br&gt;&#10;&lt;a class="link" href="https://dev.to/openhacking/install-bun-for-windows-a-modern-javascript-runtime-like-node-or-deno-449e" target="_blank" rel="noopener"&#10; &gt;Install Bun for Windows&lt;/a&gt;&lt;br&gt;&#10;&lt;a class="link" href="https://medium.com/@raj.nagaraj1990/setup-bun-js-in-windows-using-wsl-and-vs-code-712a00cd82a1" target="_blank" rel="noopener"&#10; &gt;Setup Bun JS in windows using WSL and VS code&lt;/a&gt;&lt;br&gt;&#10;&lt;a class="link" href="https://stackoverflow.com/questions/77383943/nextjs-referenceerror-request-is-not-defined-reading-old-version-of-node-s" target="_blank" rel="noopener"&#10; &gt;NextJS - ReferenceError: Request is not defined&lt;/a&gt;&lt;/p&gt;&#10;</description></item><item><title>Prompt Engineering and Security - Custom GPT</title><link>https://www.tewari.info/2024/01/21/prompt-engineering-and-security-custom-gpt/</link><pubDate>Sun, 21 Jan 2024 23:01:24 +0000</pubDate><guid>https://www.tewari.info/2024/01/21/prompt-engineering-and-security-custom-gpt/</guid><description>&lt;p&gt;I have been delving into Advanced Prompt Engineering and Security techniques for Large Language Models (LLMs). As an exercise, I have created a custom GPT in &lt;a class="link" href="https://openai.com/blog/introducing-gpts" target="_blank" rel="noopener"&#10; &gt;ChatGPT&lt;/a&gt; to help practice spelling of English words. &lt;a class="link" href="https://bit.ly/3Ua0oib" target="_blank" rel="noopener"&#10; &gt;Spell It&lt;/a&gt; GPT is secured with Advanced Prompt Engineering techniques to guard against common attack vectors, including Direct Prompt Injection, Prompt Leaking, Role Playing, Simulation, DAN and Code Injection.&lt;/p&gt;&#10;&lt;figure&gt;&lt;img src="https://www.tewari.info/wp-content/spell-it-gpt-256.png"&#10;&#9;&#9;&#9;alt="Spell-It-GPT"&gt;&lt;figcaption&gt;&#10;&#9;&#9;&#9;&lt;p&gt;Spell-It-GPT&lt;/p&gt;&#10;&#9;&#9;&lt;/figcaption&gt;&#10;&lt;/figure&gt;&#10;&#10;&lt;p&gt;Play with the &lt;a class="link" href="https://bit.ly/3Ua0oib" target="_blank" rel="noopener"&#10; &gt;Spell It&lt;/a&gt; GPT and try to break it. It is not impossible but (probably) fairly difficult to do ;) Regardless, practice spelling and have fun!&lt;/p&gt;&#10;&lt;p&gt;Switch to &lt;a class="link" href="https://openai.com/blog/chatgpt-can-now-see-hear-and-speak" target="_blank" rel="noopener"&#10; &gt;Voice Mode&lt;/a&gt; in ChatGPT Mobile App to practice spelling and put headsets on for best results!&lt;/p&gt;&#10;&lt;p&gt;Spell It: &lt;a class="link" href="https://bit.ly/3Ua0oib" target="_blank" rel="noopener"&#10; &gt;https://bit.ly/3Ua0oib&lt;/a&gt;&lt;/p&gt;&#10;&lt;p&gt;Here are some resources you can learn more about Prompt Engineering and Security:&lt;br&gt;&#10;&lt;a class="link" href="https://www.mercity.ai/blog-post/advanced-prompt-engineering-techniques" target="_blank" rel="noopener"&#10; &gt;Advanced Prompt Engineering Techniques&lt;/a&gt;&lt;br&gt;&#10;&lt;a class="link" href="https://owasp.org/www-project-top-10-for-large-language-model-applications/" target="_blank" rel="noopener"&#10; &gt;OWASP Top 10 for Large Language Model Applications&lt;/a&gt;&lt;br&gt;&#10;&lt;a class="link" href="https://github.com/OWASP/www-project-top-10-for-large-language-model-applications/wiki/Educational-Resources" target="_blank" rel="noopener"&#10; &gt;Educational Resources&lt;/a&gt;&lt;br&gt;&#10;&lt;a class="link" href="https://www.promptingguide.ai/risks/adversarial" target="_blank" rel="noopener"&#10; &gt;Adversarial Prompting in LLMs&lt;/a&gt;&lt;/p&gt;&#10;</description></item></channel></rss>