<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Ricardo Carneiro</title>
    <description>The latest articles on DEV Community by Ricardo Carneiro (@ricardo_carneiro_eb9caf27).</description>
    <link>https://dev.to/ricardo_carneiro_eb9caf27</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3952456%2F0572722c-b167-41fa-b523-19f9c21e9963.jpg</url>
      <title>DEV Community: Ricardo Carneiro</title>
      <link>https://dev.to/ricardo_carneiro_eb9caf27</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/ricardo_carneiro_eb9caf27"/>
    <language>en</language>
    <item>
      <title>Why is Your Chatbot Saving "Good Morning" as the Customer's Name? 🤖🤦‍♂️</title>
      <dc:creator>Ricardo Carneiro</dc:creator>
      <pubDate>Tue, 26 May 2026 11:25:39 +0000</pubDate>
      <link>https://dev.to/ricardo_carneiro_eb9caf27/why-is-your-chatbot-saving-good-morning-as-the-customers-name-2dc4</link>
      <guid>https://dev.to/ricardo_carneiro_eb9caf27/why-is-your-chatbot-saving-good-morning-as-the-customers-name-2dc4</guid>
      <description>&lt;p&gt;The classic struggle of chatbot data extraction, why your complex regex is failing, and how to fix it in 30 seconds using semantic NLU.&lt;br&gt;
tags: webdev, ai, chatbots, javascript&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fyfrcdhyaltb7y4bvi2gj.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fyfrcdhyaltb7y4bvi2gj.png" alt=" " width="800" height="447"&gt;&lt;/a&gt;&lt;/p&gt;



&lt;p&gt;We've all been there. You spend days building a sleek WhatsApp chatbot or a customer service agent. You write what you think is the perfect prompt or input validation.&lt;/p&gt;

&lt;p&gt;Then, your bot asks: &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;"Hi! What is your full name?"&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;And the user replies: &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;"Good morning! I'm John Doe."&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Your traditional validation or naive regex captures the input, and boom—your CRM database now has a new client officially named &lt;strong&gt;"Good morning!"&lt;/strong&gt; or &lt;strong&gt;"Good morning! I'm John Doe."&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Even worse, you ask for a Brazilian postal code (CEP) and the user types: &lt;em&gt;"It is 01310-100"&lt;/em&gt;. Your strict regex fails because it's not strictly digits, or your lazy regex fails to extract it.&lt;/p&gt;

&lt;p&gt;Traditional chatbot validation is broken. Relying on complex regex patterns is a maintenance nightmare, and raw LLM prompts are slow, expensive, and prone to hallucinations.&lt;/p&gt;


&lt;h3&gt;
  
  
  Enter NaLU AI: Semantic NLU Validation in 30 Seconds
&lt;/h3&gt;

&lt;p&gt;I got tired of these universal chatbot struggles, so I built &lt;strong&gt;&lt;a href="https://naluai.dev" rel="noopener noreferrer"&gt;NaLU AI&lt;/a&gt;&lt;/strong&gt;. It’s a lightweight API and MCP Server designed specifically to clean, structure, and validate conversational data in real-time.&lt;/p&gt;

&lt;p&gt;NaLU combines a fast deterministic layer with semantic LLM validation in multiple languages (English, Portuguese, Spanish). Instead of processing raw strings, it understands &lt;strong&gt;context&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Let's see it in action.&lt;/p&gt;


&lt;h3&gt;
  
  
  The Code 🛠️
&lt;/h3&gt;

&lt;p&gt;Here is how you can easily validate and extract a clean full name from a conversation using a simple JavaScript &lt;code&gt;fetch&lt;/code&gt; (or standard cURL):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;fetch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;https://api.naluai.dev/v1/extract/name&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;method&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;POST&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;headers&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Authorization&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Bearer YOUR_TOKEN&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Content-Type&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;application/json&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="na"&gt;body&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;JSON&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;stringify&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
    &lt;span class="na"&gt;agent_input&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Good morning! Whats your name?&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;user_input&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Good morning!&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;language&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;pt-BR&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
  &lt;span class="p"&gt;})&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;result&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The JSON Response:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="w"&gt;

&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"obtained"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"extracted_value"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;""&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"confidence"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"high"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"certain"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"reasoning"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"suggestion_to_agent"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Good morning again! Could you please tell me your name?"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"validator_used"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"validate_name"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"engine"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"llm"&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;

&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Notice that:&lt;/p&gt;

&lt;p&gt;It automatically filtered out the greeting ("Good morning isn´t a valid name").&lt;br&gt;
It suggest a "try-again-message".&lt;/p&gt;

&lt;p&gt;13 Built-in Semantic Validators&lt;br&gt;
NaLU AI comes with 13 ready-to-use validators:&lt;/p&gt;

&lt;p&gt;validate_name (extracts clean proper names, ignores titles and greetings)&lt;br&gt;
validate_cpf / validate_cnpj (validates Brazilian documents using mod 11 check)&lt;br&gt;
validate_cep (extracts postal codes and returns enriched address data)&lt;br&gt;
validate_handoff (detects if the user wants to speak to a human, measuring urgency from 1 to 3)&lt;br&gt;
validate_reply (analyzes conversational context like counter-proposals or indirect answers)&lt;br&gt;
Built for n8n, Make, Cursor &amp;amp; Claude Code&lt;br&gt;
Since it is a standard REST API, it integrates out of the box with no-code tools like n8n and Make.&lt;/p&gt;

&lt;p&gt;Even cooler, it exposes itself as an MCP Server, allowing you to add it directly to Cursor or Claude Code to perform semantic tasks locally!&lt;/p&gt;

&lt;p&gt;Give it a try! 🚀&lt;br&gt;
NaLU AI is free to start. The free tier gives you 3,000 free credits per month (no credit card required), and paid plans start at less than a fraction of a cent per validation (R0,0058/ 0.001 USD).&lt;/p&gt;

&lt;p&gt;Stop losing clients to bad chatbot regex. Clean your database and make your agents truly smart in 30 seconds.&lt;/p&gt;

&lt;p&gt;👉 Test it out in the playground: naluai.dev&lt;/p&gt;

&lt;p&gt;Let me know in the comments how you are currently handling user data extraction in your chatbot webhooks!&lt;/p&gt;

</description>
      <category>ai</category>
      <category>agentaichallenge</category>
      <category>n8nbrightdatachallenge</category>
    </item>
    <item>
      <title>Como estruturei um clone do Linktree (mais simples) multi-domínio e resiliente usando .NET 8 e MongoDB</title>
      <dc:creator>Ricardo Carneiro</dc:creator>
      <pubDate>Tue, 26 May 2026 11:19:51 +0000</pubDate>
      <link>https://dev.to/ricardo_carneiro_eb9caf27/como-estruturei-um-clone-do-linktree-mais-simples-multi-dominio-e-resiliente-usando-net-8-e-1lpo</link>
      <guid>https://dev.to/ricardo_carneiro_eb9caf27/como-estruturei-um-clone-do-linktree-mais-simples-multi-dominio-e-resiliente-usando-net-8-e-1lpo</guid>
      <description>&lt;p&gt;Fala, pessoal! 👋&lt;/p&gt;

&lt;p&gt;Recentemente enfrentei o desafio de criar uma plataforma de agregador de links profissionais do zero (estilo Linktree), mas com foco em resolver dois problemas que as ferramentas tradicionais de mercado deixam de lado: &lt;strong&gt;SEO de nicho de verdade&lt;/strong&gt; e &lt;strong&gt;limpeza contra links de spam/phishing&lt;/strong&gt;. &lt;/p&gt;

&lt;p&gt;O resultado desse projeto foi o &lt;a href="https://bcards.page" rel="noopener noreferrer"&gt;BCards&lt;/a&gt;, e hoje quero compartilhar um pouco das decisões de arquitetura e tecnologia que tomei para colocá-lo de pé.&lt;/p&gt;




&lt;h2&gt;
  
  
  🛠️ A Stack Escolhida
&lt;/h2&gt;

&lt;p&gt;Para garantir velocidade de entrega, robustez e performance de busca, escolhi uma stack moderna e muito sólida:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  &lt;strong&gt;Backend:&lt;/strong&gt; ASP.NET Core MVC com .NET 8 (C#)&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Banco de Dados:&lt;/strong&gt; MongoDB (com drivers oficiais para .NET)&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Armazenamento de Arquivos (PDFs/Imagens):&lt;/strong&gt; MongoDB GridFS&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Pagamentos:&lt;/strong&gt; Stripe (com webhooks)&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Autenticação:&lt;/strong&gt; OAuth 2.0 (Google e Microsoft)&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Envio de E-mail:&lt;/strong&gt; SMTP Resend&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  🧠 Desafios e Soluções de Arquitetura
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1. Sistema de Multi-Tenant e Multi-Domínio
&lt;/h3&gt;

&lt;p&gt;Um agregador de links precisa suportar várias marcas e domínios. No código do BCards, configurei para responder a múltiplos hosts (como &lt;code&gt;bcards.page&lt;/code&gt;, &lt;code&gt;bcards.site&lt;/code&gt;, &lt;code&gt;spicylinks.site&lt;/code&gt;) de forma dinâmica a partir das configurações de Tenant do &lt;code&gt;appsettings.json&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Isso permite que a aplicação seja modular, entregando interfaces customizadas de acordo com o domínio que o usuário acessa, usando o mesmo núcleo do backend.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. SEO Otimizado com Server-Side Rendering (SSR)
&lt;/h3&gt;

&lt;p&gt;Muitos criadores de link na bio pecam no SEO por renderizarem tudo no cliente (Client-Side Rendering) com frameworks SPA pesados. No BCards, optei por &lt;strong&gt;SSR puro via Razor Views&lt;/strong&gt;. &lt;br&gt;
O robô do Google recebe o HTML limpo, completo, com meta-tags dinâmicas e marcação &lt;strong&gt;Schema.org&lt;/strong&gt; otimizada por nicho de mercado.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. A Luta Contra o Spam (Moderação Humana)
&lt;/h3&gt;

&lt;p&gt;Ferramentas de links são alvos constantes de spammers, esquemas de pirâmide e phishing. Para proteger o domínio e manter nossa autoridade no Google sempre alta, desenvolvi um &lt;strong&gt;Dashboard de Moderação Humana&lt;/strong&gt;.&lt;br&gt;
Cada página criada passa por uma fila onde validamos critérios estritos de conteúdo (conteúdo suspeito, links quebrados e segurança de links) antes de torná-la 100% ativa para o público.&lt;/p&gt;

&lt;h3&gt;
  
  
  4. Stripe Integration &amp;amp; Efeito Decoy
&lt;/h3&gt;

&lt;p&gt;Adotei 3 planos estratégicos integrados nativamente com Stripe Webhooks. O sistema escuta os eventos &lt;code&gt;checkout.session.completed&lt;/code&gt; e atualiza instantaneamente as limitações da página do usuário no banco (como permitir upload de PDFs no plano Premium e habilitar até 15 páginas).&lt;/p&gt;




&lt;h2&gt;
  
  
  🚀 Conclusão e Próximos Passos
&lt;/h2&gt;

&lt;p&gt;O projeto está ativo e rodando muito bem. A combinação de .NET 8 e MongoDB se provou extremamente veloz para leitura de dados e flexível para modificações de schema à medida que novas features de links são adicionadas.&lt;/p&gt;

&lt;p&gt;Gostaria muito de ouvir a opinião técnica de vocês sobre esse modelo arquitetural! &lt;/p&gt;

&lt;p&gt;Se quiserem ver como ficou a interface final e criar uma página de testes, o link é: &lt;a href="https://bcards.page" rel="noopener noreferrer"&gt;https://bcards.page&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Fico à disposição nos comentários para trocar ideias sobre o código, integrações do Stripe ou a estrutura do MongoDB! 💬&lt;/p&gt;

</description>
      <category>braziliandevs</category>
      <category>dotnet</category>
      <category>mongodb</category>
      <category>architecture</category>
    </item>
  </channel>
</rss>
