<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"><channel><title><![CDATA[Santhosh Reddy]]></title><description><![CDATA[Let's talk about tech, AI and building systems. Agents as a service, Governed intelligence and everything in between.]]></description><link>https://blog.omlabs.co</link><image><url>https://cdn.hashnode.com/uploads/logos/61f11c69e247b2151e620d41/2fdc9643-3bf2-418d-a020-09c26ed1525f.jpg</url><title>Santhosh Reddy</title><link>https://blog.omlabs.co</link></image><generator>RSS for Node</generator><lastBuildDate>Sat, 13 Jun 2026 10:18:14 GMT</lastBuildDate><atom:link href="https://blog.omlabs.co/rss.xml" rel="self" type="application/rss+xml"/><language><![CDATA[en]]></language><ttl>60</ttl><item><title><![CDATA[Building effective and cost-efficient AI agents]]></title><description><![CDATA[There's a moment every builder hits — you've got access to powerful LLMs, a shiny new agentic framework, and the energy to automate everything. So you start building. Agents everywhere. Tools calling ]]></description><link>https://blog.omlabs.co/building-effective-and-cost-efficient-ai-agents</link><guid isPermaLink="true">https://blog.omlabs.co/building-effective-and-cost-efficient-ai-agents</guid><category><![CDATA[AI]]></category><category><![CDATA[agentic AI]]></category><category><![CDATA[llm]]></category><dc:creator><![CDATA[Santhosh Reddy]]></dc:creator><pubDate>Sat, 13 Jun 2026 06:21:47 GMT</pubDate><enclosure url="https://cdn.hashnode.com/uploads/covers/61f11c69e247b2151e620d41/7204094a-e832-48b0-9ef6-b3f754ce6e30.jpg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>There's a moment every builder hits — you've got access to powerful LLMs, a shiny new agentic framework, and the energy to automate everything. So you start building. Agents everywhere. Tools calling tools. Memory layers on memory layers.</p>
<p>And then your cloud bill shows up.</p>
<p>I've been there. And honestly, watching companies like Microsoft and Uber publicly wrestle with runaway AI infrastructure costs was a wake-up call for me too. These aren't small teams fumbling around — these are organizations with some of the best AI engineers on the planet. And they're still figuring out how to make agentic systems not just <em>work</em>, but work <em>efficiently</em>.</p>
<p>So here's what I've personally been learning and unlearning.</p>
<hr />
<h2>1. Match the Model to the Job</h2>
<p>This one took me longer to internalize than I'd like to admit: you don't need Claude or GPT-4 for every single step in your pipeline.</p>
<p>A well-prompted DeepSeek or a capable flash-class model can get you 99% of the way there on tasks like classification, extraction, structured formatting, or simple reasoning — at a fraction of the cost. The moment I stopped treating LLM selection as a one-size-fits-all decision and started matching model capability to task complexity, costs dropped noticeably.</p>
<p>And here's the thing — as models have gotten better, I think many of us have quietly let our prompt engineering get lazier. That's a mistake. Strong prompting still matters enormously, especially when you're trying to squeeze real performance out of a lighter model. Don't outsource your thinking to the most expensive model available when a well-crafted prompt to a cheaper one does the job.</p>
<hr />
<h2>2. Context Engineering is Everything</h2>
<p>I've seen agents fail not because of bad models or broken logic — but because they were drowning in noise.</p>
<p>Dumping your entire knowledge base into context is not engineering, it's hoping. What you actually want is a clean, well-structured knowledge layer where the agent can <em>ask</em> for exactly what it needs — and receive back only what it needs, nothing more.</p>
<p>This applies to tools too. Every tool in your agentic system should be designed with surgical precision: clear inputs, scoped outputs, no data dumps. When an agent calls a tool and gets back a wall of loosely structured JSON, it has to spend tokens just making sense of it. That's waste you're paying for.</p>
<p>Good context engineering is the difference between an agent that reasons cleanly and one that hallucinates under the weight of its own context window.</p>
<hr />
<h2>3. Not Everything Needs an Agent</h2>
<p>This one is hard to say out loud in certain circles, but: <strong>most workflows don't need a full agent</strong>.</p>
<p>Agents are expensive by design. They carry instructions to handle many scenarios, they manage tools, they maintain memory, they loop until they reach a goal. All of that burns tokens — on every single run.</p>
<p>Before reaching for an agent, ask yourself: <em>can I solve this with a deterministic workflow, a few LLM calls with structured output, and some conditional logic?</em> More often than not, the answer is yes. A clean workflow with targeted LLM calls — one to extract, one to transform, one to summarize — is faster, cheaper, more debuggable, and honestly, easier to trust in production.</p>
<p>Build agents where genuine autonomy and adaptive reasoning are <em>required</em>. Not because it sounds impressive on a slide.</p>
<hr />
<h2>4. LLMs Are a Tool, Not the Default</h2>
<p>This is the underlying principle behind all of the above.</p>
<p>Just because a language model is accessible doesn't mean it's always the right tool. Regex handles pattern matching better than an LLM. A database query retrieves structured data more reliably than prompting a model to "find" something. Deterministic logic is more trustworthy for branching decisions than an LLM-reasoned if/else.</p>
<p>The best AI systems I've seen aren't the ones that use AI the most — they're the ones that use AI <em>precisely</em>, reserving it for the steps where natural language understanding, generation, or fuzzy reasoning actually adds something that code alone can't.</p>
<hr />
<h2>5. Build Small, Focused Sub-Agents — Then Orchestrate Them Well</h2>
<p>Here's something I've started doing that changed how my systems perform and what they cost: instead of building one big general-purpose agent with a massive system prompt, a long list of tools, and instructions to handle everything — I build small, purpose-built sub-agents, each designed for one specific outcome.</p>
<p>Each sub-agent gets its own tightly engineered prompt, only the tools it actually needs, and clear input/output contracts. A research sub-agent that only knows how to search and summarize. A data extraction sub-agent that only reads and structures. An action sub-agent that only writes or calls APIs. Focused. Contained. Predictable.</p>
<p>Then you build a clean orchestration layer that routes work to the right sub-agent based on what's needed at each step. This is where the real gains come from — the orchestrator doesn't need to be expensive either, it just needs to be smart about routing. Fewer tokens wasted on irrelevant instructions, fewer hallucinations from overloaded context, better debuggability because each unit has a single responsibility.</p>
<p>For production-grade systems, I've been using <a href="https://mastra.ai">Mastra</a> — an open-source TypeScript framework that makes this pattern genuinely easy to build. It handles agent orchestration, tool definitions, memory, and step-based workflows with a clean developer experience that doesn't get in your way. It's solid, it scales, and it's built for the real world — not just demos.</p>
<p>The mental model shift is simple: stop thinking "one smart agent that handles everything" and start thinking "a well-designed team of focused agents, coordinated by a clear orchestration layer." That's how you build systems that are both powerful and efficient.</p>
<hr />
<h2>The Real Goal</h2>
<p>We're not here to build AI agents. We're here to build systems that create real value by automating real problems.</p>
<p>Sometimes that's a fully autonomous multi-agent system. Often, it's a workflow with two LLM calls and a well-placed conditional. The measure of good engineering isn't how much AI you used — it's how much value you delivered, at what cost, with how much reliability.</p>
<p>That's the shift I keep coming back to. Build for outcomes, not optics.</p>
]]></content:encoded></item><item><title><![CDATA[NFT.JS - A Javascript library to implement NFTs]]></title><description><![CDATA[👋 Hello world ! This is Santhosh Reddy, a web3 developer and the solo developer of NFTJS. What's NFT.JS ? Today I'm launching NFT.JS to the world of web3 developers. Now let's talk what, why and how about NFT.JS
Intro... 🙋‍♂️
Remember that, this is...]]></description><link>https://blog.omlabs.co/nftjs-a-javascript-library-to-implement-nfts</link><guid isPermaLink="true">https://blog.omlabs.co/nftjs-a-javascript-library-to-implement-nfts</guid><category><![CDATA[Blockchain]]></category><category><![CDATA[Web3]]></category><category><![CDATA[Solidity]]></category><category><![CDATA[NFT]]></category><category><![CDATA[JavaScript]]></category><dc:creator><![CDATA[Santhosh Reddy]]></dc:creator><pubDate>Tue, 05 Apr 2022 08:17:21 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1653371424020/nm9G4bnc1.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>👋 Hello world ! This is Santhosh Reddy, a web3 developer and the solo developer of NFTJS. What's NFT.JS ? Today I'm launching NFT.JS to the world of web3 developers. Now let's talk what, why and how about NFT.JS</p>
<h2 id="heading-intro">Intro... 🙋‍♂️</h2>
<p>Remember that, this is about the initial version of NFT.JS and to use NFT.JS you need to use the NFT.JS 2.0. You can checkout it <a target="_blank" href="https://santhoshreddy.hashnode.dev/launching-nftjs-2-the-next-level">here</a></p>
<p>If you're a web3 developer, you will definitely know what NFTs are and might have also implemented them somewhere in your previous projects or Dapps right?</p>
<p>Usually, implementing NFTs in the Dapps includes the work of creating an ERC721 contract using solidity, testing them and deploying to the network using Truffle &amp; Ganache or Remix IDE and then interacting with the contract from the Dapps using web3js.</p>
<p>Not done yet! You need to use IPFS to store metadata as well as files in the metadata like images, videos or other media content.</p>
<p>Have you ever thought of using a single library that can perform all these tasks! NFT.JS has taken birth here :)</p>
<p>Let's move on to the detailed talk on NFT.JS</p>
<p>Before moving on, I have a small request. If you found NFT.JS interesting and useful please consider upvoting it on <a target="_blank" href="https://www.producthunt.com/posts/nftjs-2-0">Product Hunt</a></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1649042962638/S2IyR4dXO.png" alt="20220404_085105_0000.png" /></p>
<p>Visit : <a target="_blank" href="https://nft-js.web.app/">NFT.JS</a></p>
<h2 id="heading-whats-nftjs">What's NFT.JS... ‼️</h2>
<p>Long story short, NFT.JS is a Javascript library that does all the above discussed tasks to implement NFTs in the Dapps.</p>
<p>Building a NFT marketplace ? Developing a Decentralized social platform or any other Dapps that needs to implement NFTs ? If "yes", using NFT.JS is a cool thing that you can do.</p>
<p>Using NFT.JS, you can deploy a ERC721 contract that can perform all the required functions without writing a single line of Solidity. You can easily interact with the contract by calling the functions and sending transactions to the contract with just 1-2 lines of NFT.JS and it also removes the usage of IPFS.</p>
<p>You can simply provide the input file into the metadata object and NFT.JS uploads all the files provided in the metadata to IPFS and lastly uploads the metadata.json file to IPFS and mints the NFT.</p>
<p>Have you heard of lazyMinting ? NFT.JS also provides that cool feature. In lazyMinting, the user can mint a NFT where the token data is stored off-chain(ipfs) to avoid gas fee and in future, if a buyer is ready to buy that NFT, the data moves on-chain by minting the NFT to the buyer. Here the user can get rid of gas-fee which is a big entry barrier.</p>
<p>Planning to build your Opensea ? Don't reinvent the wheel and consider using NFT.JS.</p>
<h2 id="heading-tech-stack-used">Tech Stack used... 👨‍💻</h2>
<ol>
<li><p>Javascript (programming language of the library)</p>
</li>
<li><p>Solidity (to create a ERC721 contract)</p>
</li>
<li><p>Web3.JS (to deploy and interact with the contract)</p>
</li>
<li><p>Moralis (for RPC nodes and IPFS gateway)</p>
</li>
</ol>
<p>The technologies mentioned above are used to develop NFT.JS</p>
<h2 id="heading-why-use-nftjs">Why use NFT.JS... ❓</h2>
<p>The 3 main benefits that you can enjoy using NFT.JS are...</p>
<h4 id="heading-1-low-code-development">1. Low code development</h4>
<p>NFT.JS completely diminishes the usage of Solidity to create smart contracts.</p>
<p>Not only that, using web3.js to interact with a contract also requires 4-5 lines of code right? NFT.JS does that same thing in just 1-2 lines of code.</p>
<h4 id="heading-2-integrated-ipfs">2. Integrated IPFS</h4>
<p>Need to use a 3rd party IPFS node and gateways like Infura, Alchemy? No need, Moralis IPFS gateway is integrated to NFT.JS and doesn't even need to code to use IPFS.</p>
<p>Using Moralis IPFS that is integrated to NFT.JS gives you a cool experience and can handle files that are as large as 1GB and that's the maximum limit.</p>
<h4 id="heading-3-implement-lazyminting">3. Implement lazyMinting</h4>
<p>LazyMinting is a cool experience that you can give your Dapp users. NFT.JS also provides the feature of implementing lazyMinting.</p>
<p>Not only that, getting started with NFT.JS is very simple and implementation &amp; usage is super easy.</p>
<p>Isn't it cool...?</p>
<h2 id="heading-how-to-nftjs">How to NFT.JS ⚙</h2>
<p>(deprecated. see NFTJS 2.0 <a target="_blank" href="https://santhoshreddy.hashnode.dev/launching-nftjs-2-the-next-level">here</a>) </p>
<p>Now let's jump into a deep talk on how to use NFT.JS by exploring its usage and implementations.</p>
<h4 id="heading-install-nftjs">Install NFT.JS</h4>
<p>The first thing you need to do to get started with NFT.JS is to install it by adding a simple script tag in the <code>&lt;head&gt;</code> section of your index.html file.</p>
<pre><code><span class="hljs-operator">&lt;</span>script src<span class="hljs-operator">=</span><span class="hljs-string">"https://nftjs.netlify.app/nft.js"</span> <span class="hljs-keyword">type</span><span class="hljs-operator">=</span><span class="hljs-string">"text/javascript"</span> <span class="hljs-operator">/</span><span class="hljs-operator">&gt;</span>`
</code></pre><h4 id="heading-initialize-it">Initialize it...</h4>
<p>After installing NFT.JS you need to initialize the NFT.JS by providing the ethereum network (mainnet/rinkeby/ropsten...) and the user's wallet address as strings in the following way.</p>
<pre><code>NFTJS.start(<span class="hljs-string">"rinkeby"</span>, accounts[<span class="hljs-number">0</span>])
</code></pre><p>If you want to change the network or user's wallet address in any instance, you can easily do it by calling the same function again with different parameters.</p>
<pre><code>NFTJS.start(<span class="hljs-string">"ropsten"</span>, accounts[<span class="hljs-number">1</span>])
</code></pre><h4 id="heading-deploying-a-collection-contract">Deploying a collection contract</h4>
<p>The ERC721 contract is created using Solidity with all the required 
functions and compiled already. By calling the <code>createCollection</code> function, you can deploy it to the network that you have set in <code>NFTJS.start()</code>.</p>
<p>The required parameters are <code>name</code> of the collections as a string, <code>SYMBOL</code> of the collection as a string, <code>publicMintable</code> as string ("true"/"false") and <code>maxSupply</code> as an integer.</p>
<p>publicMintable is a parameter that defines if you would like to allow others (other than owner) to mint NFTs in the collection and Default value is false and it's always false unless you give "true" as the parameter value.</p>
<pre><code>await NFTJS.createCollection(
<span class="hljs-string">"Nftify"</span>,
<span class="hljs-string">"NFY"</span>,
<span class="hljs-string">"true"</span>,
<span class="hljs-number">10000</span>
)
</code></pre><p>After the transaction receipt gives the deployed contractAddress, you can get it by calling a simple function like this.</p>
<pre><code><span class="hljs-keyword">var</span> <span class="hljs-keyword">address</span> <span class="hljs-operator">=</span> NFTJS.deployed()
</code></pre><p>This only gives the address of the collection that is most recently deployed in that web session. If either the page is reloaded or a new contract is deployed, the address of the past contract is gone.</p>
<h4 id="heading-initiating-a-collection">Initiating a collection</h4>
<p>Initiating a collection requires the address of that contract and must be deployed to the network that you have provided in the <code>NFTJS.start()</code></p>
<pre><code><span class="hljs-keyword">var</span> collection <span class="hljs-operator">=</span> <span class="hljs-keyword">new</span> NFTJS.collection(<span class="hljs-keyword">address</span>)
</code></pre><h4 id="heading-functions-of-a-collection">Functions of a collection</h4>
<p>Now let's see how to interact with a smart contract by sending and calling the data.</p>
<p><strong>1. mintNFT : </strong>Minting an NFT requires the metadata object which contains the items like name, description, image and others.</p>
<p>Let's discuss the role of IPFS here. The first thing that the <code>minNFT</code> function does is, it checks if an item in the level 1 items of the object is a file. It uploads all the files to the IPFS and replaces the file values with the file URL. It will take some to complete the whole process.</p>
<p>Note that, if a file input's value is given in metadata and the user doesn't upload a file, the function fails.</p>
<p>After uploading the files in metadata, it uploads the final metadata object to the IPFS and then sends the transaction to the metamask wallet.</p>
<pre><code><span class="hljs-selector-tag">await</span> <span class="hljs-selector-tag">collection</span><span class="hljs-selector-class">.mintNFT</span>({
  <span class="hljs-attribute">name </span>: <span class="hljs-string">"king"</span>,
  description :  <span class="hljs-string">"king of the kingdom"</span>,
  image : inputElement.files[<span class="hljs-number">0</span>]
})
</code></pre><p><strong>2. lazyMintAndTransfer : </strong> This is a function which is similar to mintNFT but is needed if you want to provide your users a gas free minting experience.</p>
<p>The required parameters are minter, price and metadata. Here, the buyer of the NFT is the user who is calling the function and the minter is the one who minted the NFT off-chain. The price is the amount of ETH the buyer needs to pay the minter.</p>
<p>The metadata of the NFT stored off-chain while minting 
should be given as the parameter. Dealing with metadata and IPFS is the same as in the mintNFT function.</p>
<p>As soon as the transaction is completed, the NFT data moves on-chain by directly minting it to the buyer and the ETH gets transferred to the minter address.</p>
<pre><code>await collection.lazyMintAndTransfer(
  nft.minter, 
  nft.price,
  nft.metadataObj
)
</code></pre><p><strong>3. updateNFT : </strong>This is a crucial function to update the NFT's metadata. This function requires the ID of the NFT that needs to be updated and the new metadata that needs to replace the old one.</p>
<p>Here, the user must be the owner of the NFT.</p>
<p>Dealing with metadata and IPFS is the same as in the mintNFT function.</p>
<pre><code><span class="hljs-selector-tag">await</span> <span class="hljs-selector-tag">collection</span><span class="hljs-selector-class">.updateNFT</span>(<span class="hljs-selector-tag">id</span>, {
  <span class="hljs-attribute">name </span>: <span class="hljs-string">"king1"</span>,
  description :  <span class="hljs-string">"king1 of the kingdom1"</span>,
  image : inputElement.files[<span class="hljs-number">0</span>]
})
</code></pre><p><strong>4. burnNFT : </strong>This function is used to burn or delete the NFT. This function requires the ID of the NFT that has to be minted and the user must be the owner of the NFT.</p>
<pre><code>await collection.burnNFT(id)
</code></pre><p><strong>5. approve : </strong> This function is used to give the transfer approval to the collection contract. This function requires the ID of the NFT that has to be approved and the user must be the owner of the NFT.</p>
<pre><code>await collection.approve(id)
</code></pre><p><strong>6. setApproveAll : </strong> This function allows the user to give or revoke approval on all his NFTs to the collection contract. The parameter that you need to give is a string form of the boolean ("true"/"false"). </p>
<p>The default value is "true" and is always the same unless you give a parameter like "false".</p>
<pre><code>await collection.setApprovalForAll(<span class="hljs-keyword">bool</span>)
</code></pre><p><strong>7. transfer : </strong> This function is used when a user wants to transfer his/her NFT to anyone he/she wishes. The required parameters are "to" which is an address to which he/she wants to transfer and the ID of the NFT.</p>
<pre><code>await collection.<span class="hljs-built_in">transfer</span>(to, id)
</code></pre><p><strong>8. transferFrom : </strong> This function is basically a buy function. The required parameters are from, to, price and id. As this transfer is made by the collection contract, the from/owner must give the approval to the contract before calling this function.</p>
<p>Usually, this function should be called by the "to". This function transfers the NFT of the given ID from "from" to the "to" and transfers the ETH of "price" from "to" to the "from". As said, it's a biy function and <code>msg.value</code> must be &gt; 0.</p>
<pre><code>await collection.transferFrom(<span class="hljs-keyword">from</span>, to, price, id)
</code></pre><p><strong>9. details : </strong>This function returns the object that includes the details of the collection like, name, symbol, owner, maxSupply, publucMintable and totalSupply. Here, totalSupply also includes the burned NFTs.</p>
<pre><code><span class="hljs-keyword">var</span> details <span class="hljs-operator">=</span> await collection.details()
</code></pre><p><strong>10. getApproved : </strong> This function takes the ID of a NFT and returns the address to which the owner has given approval of that NFT id. </p>
<p>Usually, it returns the address(0) if not approved and returns the address of the collection if approved.</p>
<pre><code><span class="hljs-keyword">var</span> <span class="hljs-keyword">address</span> <span class="hljs-operator">=</span> await collection.getApproved(id)
</code></pre><p><strong>11. isApprovedForAll : </strong> This function returns the boolean value. This boolean is equal to the value given in the setApproveAll function. Its default value is false.</p>
<pre><code><span class="hljs-keyword">var</span> <span class="hljs-keyword">bool</span> <span class="hljs-operator">=</span> await collection.isApprovedForAll()
</code></pre><p><strong>12. ownerOf : </strong> This function returns the owner's address of the given NFT id.</p>
<pre><code><span class="hljs-keyword">var</span> owner <span class="hljs-operator">=</span> await collection.ownerOf(id)
</code></pre><p><strong>13. balanceOf : </strong> This function returns the no.of NFTs holding of the given user's address.</p>
<pre><code><span class="hljs-keyword">var</span> balance <span class="hljs-operator">=</span> await collection.balanceOf(<span class="hljs-keyword">address</span>)
</code></pre><p>Hope you understand how to use NFT.JS to implement NFTs in your projects in a low-code way and save your valuable time &amp; energy.</p>
<p>If you have any doubts, found any bugs or want to give a suggestion or feedback on NFT.JS you can comment down below or can reach out to me on <a target="_blank" href="https://twitter.com/santhosh6404">twitter</a></p>
<h2 id="heading-limitations">Limitations... ⛔</h2>
<p>The only 2 limitations of NFT.JS are...</p>
<ol>
<li><p>It only supports Ethereum, not other networks like Polygon and BSC and only the ERC721 standard, not ERC1155.</p>
</li>
<li><p>While implementing lazyMinting, you need to store the token data off-chain right ? Unfortunately, NFT.JS doesn't provide the option to store the off-chain data and you need to set up your own space for that.</p>
</li>
</ol>
<h2 id="heading-future-plans">Future plans... 🔮</h2>
<p>As a developer and a problem-solver, the only future plan for NFT.JS is to break the above limitations...</p>
<p>I think it would be great if NFT.JS also supports ERC1155 as well as other networks like Polygon and BSC. Using Polygon or BSC is a great thing to reduce the gas fee. </p>
<p>I also feel that, ETH2.0 can also replace the positions of Solana, Polygon and BSC coz, ETH2.0 is an upgraded version of ETH and uses proof-of-stake which may result in a much lower gas fee than Polygon and BSC.</p>
<h2 id="heading-final-thoughts">Final Thoughts... 🙂</h2>
<p>I'm so excited and happy that I also completed developing something that can help my fellow devs.</p>
<p>Uhhh.....</p>
<p>Finally, if you are to build something that requires implementation of NFTs please consider using NFT.JS...</p>
<p><strong>Taking a leave for now...👋Bye!</strong></p>
]]></content:encoded></item></channel></rss>