<?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: Sreegeethesh</title>
    <description>The latest articles on DEV Community by Sreegeethesh (@sreegeetheshdhananjayan).</description>
    <link>https://dev.to/sreegeetheshdhananjayan</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.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F4060232%2F1d454583-ac2b-4fba-baa2-8a7066e3d411.png</url>
      <title>DEV Community: Sreegeethesh</title>
      <link>https://dev.to/sreegeetheshdhananjayan</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/sreegeetheshdhananjayan"/>
    <language>en</language>
    <item>
      <title>I Built an AI Red Team Platform to Attack LLMs, RAG Systems, and Agents</title>
      <dc:creator>Sreegeethesh</dc:creator>
      <pubDate>Thu, 24 Sep 2026 12:18:09 +0000</pubDate>
      <link>https://dev.to/sreegeetheshdhananjayan/i-built-an-ai-red-team-platform-to-attack-llms-rag-systems-and-agents-2cba</link>
      <guid>https://dev.to/sreegeetheshdhananjayan/i-built-an-ai-red-team-platform-to-attack-llms-rag-systems-and-agents-2cba</guid>
      <description>

&lt;h1&gt;
  
  
  I Built an AI Red Team Platform to Attack LLMs, RAG Systems, and Agents
&lt;/h1&gt;

&lt;p&gt;AI applications are getting better at generating code, answering questions, retrieving information, and interacting with tools.&lt;/p&gt;

&lt;p&gt;But testing whether an AI application &lt;strong&gt;works&lt;/strong&gt; is very different from testing whether it behaves safely when someone intentionally tries to break it.&lt;/p&gt;

&lt;p&gt;That was the problem I wanted to explore.&lt;/p&gt;

&lt;p&gt;So I built &lt;strong&gt;AI Red Team&lt;/strong&gt;, a local-first AI security testing platform designed to attack AI systems I own, collect reproducible evidence, and verify whether security fixes actually worked.&lt;/p&gt;

&lt;p&gt;GitHub: &lt;a href="https://github.com/SREEGEETHES/ai-redteam" rel="noopener noreferrer"&gt;https://github.com/SREEGEETHES/ai-redteam&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The core idea is simple:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Don't just find a vulnerability. Capture the evidence and prove the fix.&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  What is AI Red Team?
&lt;/h2&gt;

&lt;p&gt;AI Red Team is a security testing platform for:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;LLM applications&lt;/li&gt;
&lt;li&gt;RAG systems&lt;/li&gt;
&lt;li&gt;AI agents&lt;/li&gt;
&lt;li&gt;AI model APIs&lt;/li&gt;
&lt;li&gt;Local AI environments&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The current implementation includes:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;18 deterministic OWASP-based attacks&lt;/li&gt;
&lt;li&gt;6 vulnerable/secure lab environments&lt;/li&gt;
&lt;li&gt;183 automated tests&lt;/li&gt;
&lt;li&gt;16 deterministic detectors&lt;/li&gt;
&lt;li&gt;SHA-256 integrity hashes for evidence&lt;/li&gt;
&lt;li&gt;Automated retesting&lt;/li&gt;
&lt;li&gt;FAIL → PASS → VERIFIED workflow&lt;/li&gt;
&lt;li&gt;JSON, Markdown and HTML reports&lt;/li&gt;
&lt;li&gt;FastAPI API&lt;/li&gt;
&lt;li&gt;CLI&lt;/li&gt;
&lt;li&gt;Streamlit dashboard&lt;/li&gt;
&lt;li&gt;Docker support&lt;/li&gt;
&lt;li&gt;Local-first execution&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The goal isn't to claim that an AI system is "secure" after running a few tests.&lt;/p&gt;

&lt;p&gt;Instead, the platform answers a much narrower question:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Did this specific security scenario pass or fail, and can I reproduce the result?&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Why I Built It
&lt;/h2&gt;

&lt;p&gt;Traditional application security tools are extremely useful, but AI systems introduce additional attack surfaces.&lt;/p&gt;

&lt;p&gt;For example, an application might expose an LLM that can:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Receive user-controlled prompts.&lt;/li&gt;
&lt;li&gt;Retrieve documents from a vector database.&lt;/li&gt;
&lt;li&gt;Call internal tools.&lt;/li&gt;
&lt;li&gt;Generate structured output.&lt;/li&gt;
&lt;li&gt;Access application data.&lt;/li&gt;
&lt;li&gt;Potentially influence external systems.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;That means security testing cannot stop at:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Request → Response
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You also need to understand the complete path:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;User Input
    ↓
   LLM
    ↓
Retrieval
    ↓
Tool Selection
    ↓
Application Logic
    ↓
Side Effect
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This changes how security testing needs to be approached.&lt;/p&gt;

&lt;h2&gt;
  
  
  The OWASP GenAI LLM Top 10
&lt;/h2&gt;

&lt;p&gt;The platform uses the &lt;strong&gt;OWASP GenAI LLM Top 10 2026&lt;/strong&gt; as its primary taxonomy.&lt;/p&gt;

&lt;p&gt;The implemented coverage includes:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Prompt Injection&lt;/li&gt;
&lt;li&gt;Sensitive Information Disclosure&lt;/li&gt;
&lt;li&gt;Supply Chain Vulnerabilities&lt;/li&gt;
&lt;li&gt;Data and Model Poisoning&lt;/li&gt;
&lt;li&gt;Improper Output Handling&lt;/li&gt;
&lt;li&gt;Excessive Agency&lt;/li&gt;
&lt;li&gt;System Prompt Leakage&lt;/li&gt;
&lt;li&gt;Vector and Embedding Weaknesses&lt;/li&gt;
&lt;li&gt;Misinformation&lt;/li&gt;
&lt;li&gt;Unbounded Consumption&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Instead of treating these as documentation categories, I implemented executable security tests around them.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Attack Lifecycle
&lt;/h2&gt;

&lt;p&gt;Every scan follows a structured workflow:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;DISCOVER
   ↓
THREAT MODEL
   ↓
BASELINE
   ↓
ATTACK
   ↓
OBSERVE
   ↓
COLLECT EVIDENCE
   ↓
DETECT
   ↓
CLASSIFY
   ↓
REPORT
   ↓
REMEDIATE
   ↓
RETEST
   ↓
REGRESSION
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A security scanner shouldn't simply throw payloads at an endpoint and print a result.&lt;/p&gt;

&lt;p&gt;It needs to explain &lt;strong&gt;what happened&lt;/strong&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Deterministic Testing Instead of LLM-as-a-Judge
&lt;/h2&gt;

&lt;p&gt;One of the biggest design choices was avoiding an LLM as the primary security judge.&lt;/p&gt;

&lt;p&gt;For example, imagine a test designed to determine whether a known canary secret is exposed.&lt;/p&gt;

&lt;p&gt;Instead of asking another LLM:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"Does this response look like a secret leak?"&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;the scanner can deterministically check:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Expected canary:
CANARY_SECRET_12345

Response:
"I found the value CANARY_SECRET_12345..."

Detector:
canary_secret_leak

Result:
FAIL
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That makes the result reproducible.&lt;/p&gt;

&lt;p&gt;The platform uses deterministic payloads and detectors for its implemented attack cases.&lt;/p&gt;

&lt;p&gt;The result model is:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;PASS
FAIL
INCONCLUSIVE
NOT_APPLICABLE
ERROR
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;An important rule is:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;No evidence = no PASS.&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;An inconclusive test should not become a passing test simply because the target didn't return an obvious failure.&lt;/p&gt;

&lt;h2&gt;
  
  
  Evidence Is the Important Part
&lt;/h2&gt;

&lt;p&gt;Finding a vulnerability is only half the job.&lt;/p&gt;

&lt;p&gt;The scanner needs to preserve what actually happened.&lt;/p&gt;

&lt;p&gt;An evidence record can contain:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Scan ID
Test ID
Timestamp
Target
Request
Response
HTTP status
Headers
Tool calls
Retrieved documents
Detectors triggered
Expected behavior
Observed behavior
Reproduction count
Result
SHA-256 integrity hash
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Test: LLM02-SD-001
Result: FAIL
Detector: canary_secret_leak
Reproduction count: 2
Evidence hash: SHA-256
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The SHA-256 hash provides an integrity check for the stored evidence.&lt;/p&gt;

&lt;p&gt;I deliberately describe this as &lt;strong&gt;integrity-verifiable evidence&lt;/strong&gt;, rather than "tamper-proof evidence."&lt;/p&gt;

&lt;p&gt;A hash can detect changes to the data. It does not magically prevent someone from modifying both the evidence and its stored hash.&lt;/p&gt;

&lt;h2&gt;
  
  
  Testing Vulnerable vs Secure Applications
&lt;/h2&gt;

&lt;p&gt;Another important part of the project is the lab environment.&lt;/p&gt;

&lt;p&gt;Instead of testing only one application, I created vulnerable and secure variants.&lt;/p&gt;

&lt;p&gt;The project contains six lab pairs:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Vulnerable LLM
Secure LLM

Vulnerable RAG
Secure RAG

Vulnerable Agent
Secure Agent
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This makes it possible to test the scanner itself.&lt;/p&gt;

&lt;p&gt;The workflow looks like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Vulnerable Target
       ↓
     Scan
       ↓
     FAIL
       ↓
     Fix
       ↓
Secure Target
       ↓
    Retest
       ↓
     PASS
       ↓
   VERIFIED
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This became the central workflow of the project.&lt;/p&gt;

&lt;h2&gt;
  
  
  FAIL → PASS → VERIFIED
&lt;/h2&gt;

&lt;p&gt;A vulnerability finding shouldn't simply disappear because the application was changed.&lt;/p&gt;

&lt;p&gt;The platform therefore includes a retest workflow.&lt;/p&gt;

&lt;p&gt;Example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Initial Scan

LLM02 Sensitive Information Disclosure
             ↓
           FAIL
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;After applying a fix:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Retest

Previous Result: FAIL
Current Result:  PASS
             ↓
          VERIFIED
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This gives the project a security engineering workflow rather than a one-time vulnerability scanner.&lt;/p&gt;

&lt;h2&gt;
  
  
  Testing AI Agents Is Different
&lt;/h2&gt;

&lt;p&gt;Agent security introduced another important problem.&lt;/p&gt;

&lt;p&gt;Suppose an agent receives:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Delete all customer records.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The model may attempt to call:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;delete_customer_records()
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;But that does not necessarily mean the application is vulnerable.&lt;/p&gt;

&lt;p&gt;There are several different things to measure:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Model behavior
      ↓
Did the model attempt the action?

Security control
      ↓
Did authorization prevent it?

Application behavior
      ↓
Did the application execute it?

Actual side effect
      ↓
Was any data actually changed?
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Model attempted destructive tool call
          ↓
Authorization middleware blocked it
          ↓
Database unchanged
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That is very different from:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Model attempted destructive tool call
          ↓
Tool executed
          ↓
Database modified
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This distinction became important when designing the agent testing architecture.&lt;/p&gt;

&lt;h2&gt;
  
  
  RAG Security Testing
&lt;/h2&gt;

&lt;p&gt;RAG systems introduce another security boundary.&lt;/p&gt;

&lt;p&gt;The model isn't only receiving a prompt.&lt;/p&gt;

&lt;p&gt;It is also receiving information retrieved from a knowledge base.&lt;/p&gt;

&lt;p&gt;That creates potential issues around:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;poisoned documents&lt;/li&gt;
&lt;li&gt;cross-tenant retrieval&lt;/li&gt;
&lt;li&gt;unauthorized information disclosure&lt;/li&gt;
&lt;li&gt;malicious instructions inside retrieved content&lt;/li&gt;
&lt;li&gt;weak embedding boundaries&lt;/li&gt;
&lt;li&gt;ungrounded responses&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The testing architecture therefore treats retrieval as part of the evidence chain:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;User Query
    ↓
Retriever
    ↓
Retrieved Documents
    ↓
LLM
    ↓
Response
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The scanner can then inspect what was retrieved and compare that with the expected security boundary.&lt;/p&gt;

&lt;h2&gt;
  
  
  Architecture
&lt;/h2&gt;

&lt;p&gt;The project is structured around several major components:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;                    AI RED TEAM
                         │
                Scan Orchestrator
                         │
        ┌────────────────┼────────────────┐
        │                │                │
   Attack Engine    Evidence Engine   Policy Engine
        │                │                │
        └────────────────┼────────────────┘
                         │
              Target Adapter Layer
                         │
       ┌─────────────────┼─────────────────┐
       │                 │                 │
      LLM               RAG              Agent
       │                 │                 │
       └─────────────────┼─────────────────┘
                         │
                  Findings / Reports
                         │
                 Retest / Regression
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The target adapter layer allows different AI interfaces to be tested without coupling the attack engine to one specific implementation.&lt;/p&gt;

&lt;p&gt;The project includes adapters for:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;REST&lt;/li&gt;
&lt;li&gt;Ollama&lt;/li&gt;
&lt;li&gt;OpenAI-compatible APIs&lt;/li&gt;
&lt;li&gt;RAG&lt;/li&gt;
&lt;li&gt;Agents&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  CLI + API + Dashboard
&lt;/h2&gt;

&lt;p&gt;The platform can be used through multiple interfaces.&lt;/p&gt;

&lt;h3&gt;
  
  
  CLI
&lt;/h3&gt;

&lt;p&gt;The CLI is useful for automation and CI/CD workflows.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;redteam scan &lt;span class="nt"&gt;--target&lt;/span&gt; ...
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Retesting can be triggered with:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;redteam retest &amp;lt;scan-id&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  FastAPI
&lt;/h3&gt;

&lt;p&gt;The API provides programmatic access to scanning functionality.&lt;/p&gt;

&lt;h3&gt;
  
  
  Streamlit
&lt;/h3&gt;

&lt;p&gt;The dashboard provides a visual workflow for:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Targets
   ↓
Scans
   ↓
Findings
   ↓
Evidence
   ↓
OWASP Coverage
   ↓
Remediation
   ↓
Retest
   ↓
Regression
   ↓
Reports
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The current dashboard contains &lt;strong&gt;13 pages&lt;/strong&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Reports
&lt;/h2&gt;

&lt;p&gt;The scanner can generate:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;JSON reports&lt;/li&gt;
&lt;li&gt;Markdown reports&lt;/li&gt;
&lt;li&gt;HTML reports&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This makes the results useful both for automation and human review.&lt;/p&gt;

&lt;p&gt;A typical workflow could be:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;CI/CD
  ↓
Run security tests
  ↓
Generate JSON
  ↓
Store artifact
  ↓
Review findings
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Testing the Scanner
&lt;/h2&gt;

&lt;p&gt;A security testing tool should itself be tested heavily.&lt;/p&gt;

&lt;p&gt;The current project has:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;183 automated tests.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;These cover areas including:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;attack definitions&lt;/li&gt;
&lt;li&gt;payload generation&lt;/li&gt;
&lt;li&gt;detectors&lt;/li&gt;
&lt;li&gt;adapters&lt;/li&gt;
&lt;li&gt;evidence&lt;/li&gt;
&lt;li&gt;classification&lt;/li&gt;
&lt;li&gt;orchestration&lt;/li&gt;
&lt;li&gt;API behavior&lt;/li&gt;
&lt;li&gt;lab environments&lt;/li&gt;
&lt;li&gt;retesting&lt;/li&gt;
&lt;li&gt;regression behavior&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The goal was to make the framework deterministic enough that changes to the scanner itself don't silently break existing security checks.&lt;/p&gt;

&lt;h2&gt;
  
  
  Local-First Design
&lt;/h2&gt;

&lt;p&gt;I intentionally designed the project around local testing.&lt;/p&gt;

&lt;p&gt;The project can be started using:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight powershell"&gt;&lt;code&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;\run_local.bat&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The Streamlit dashboard then becomes available locally.&lt;/p&gt;

&lt;p&gt;The project also includes Docker support.&lt;/p&gt;

&lt;p&gt;A local-first workflow makes experimentation easier without requiring every test to be sent to an external service.&lt;/p&gt;

&lt;h2&gt;
  
  
  What This Project Is Not
&lt;/h2&gt;

&lt;p&gt;AI Red Team is &lt;strong&gt;not&lt;/strong&gt; a replacement for:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Burp Suite&lt;/li&gt;
&lt;li&gt;OWASP ZAP&lt;/li&gt;
&lt;li&gt;traditional SAST&lt;/li&gt;
&lt;li&gt;DAST&lt;/li&gt;
&lt;li&gt;cloud security scanners&lt;/li&gt;
&lt;li&gt;infrastructure security testing&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;It focuses specifically on &lt;strong&gt;AI model interfaces and AI application behavior&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;It is also not a guarantee that an application is secure.&lt;/p&gt;

&lt;p&gt;Passing the implemented test suite means:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;The application passed the security scenarios that were actually tested.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;It does not mean:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;The application contains no vulnerabilities.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;That distinction is fundamental to security testing.&lt;/p&gt;

&lt;h2&gt;
  
  
  Security Boundaries
&lt;/h2&gt;

&lt;p&gt;The project is intended for:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;local development&lt;/li&gt;
&lt;li&gt;developer-owned applications&lt;/li&gt;
&lt;li&gt;authorized staging environments&lt;/li&gt;
&lt;li&gt;intentionally vulnerable labs&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;It should not be used against systems without authorization.&lt;/p&gt;

&lt;p&gt;The lab environments also make it possible to learn the attack and defense cycle without targeting real systems.&lt;/p&gt;

&lt;h2&gt;
  
  
  Technology Stack
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Python
FastAPI
Streamlit
SQLAlchemy
Pydantic
pytest
Docker
SQLite
Altair
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Along with integrations for AI targets such as Ollama and OpenAI-compatible interfaces.&lt;/p&gt;

&lt;h2&gt;
  
  
  What I Learned
&lt;/h2&gt;

&lt;p&gt;The most interesting part of this project wasn't writing attack payloads.&lt;/p&gt;

&lt;p&gt;It was designing the difference between:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;"The model said something suspicious."
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;and:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;"This specific security control failed,
here is the reproducible evidence,
and here is the retest proving whether the fix worked."
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That difference is what turned this from a collection of prompt attacks into a security testing workflow.&lt;/p&gt;

&lt;p&gt;I also learned that AI security needs to consider multiple layers simultaneously:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Model
 ↓
Prompt
 ↓
Retrieval
 ↓
Tools
 ↓
Application
 ↓
Authorization
 ↓
Side Effects
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Testing only the model isn't enough when the model is connected to real application functionality.&lt;/p&gt;

&lt;h2&gt;
  
  
  Current Project Status
&lt;/h2&gt;

&lt;p&gt;The current implementation includes:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;18 deterministic attacks
16 deterministic detectors
6 vulnerable/secure lab pairs
183 automated tests
SHA-256 evidence integrity
FAIL → PASS → VERIFIED retesting
JSON / Markdown / HTML reports
13-page Streamlit dashboard
CLI
FastAPI
Docker support
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Repository:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/SREEGEETHES/ai-redteam" rel="noopener noreferrer"&gt;https://github.com/SREEGEETHES/ai-redteam&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  What's Next?
&lt;/h2&gt;

&lt;p&gt;There are several directions I want to explore further:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;More advanced attack chaining&lt;/li&gt;
&lt;li&gt;Adaptive AI red-team agents&lt;/li&gt;
&lt;li&gt;MCP security testing&lt;/li&gt;
&lt;li&gt;More RAG isolation tests&lt;/li&gt;
&lt;li&gt;More agent authorization scenarios&lt;/li&gt;
&lt;li&gt;CI/CD security gates&lt;/li&gt;
&lt;li&gt;Expanded regression testing&lt;/li&gt;
&lt;li&gt;Additional AI security benchmarks&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;But I wanted the first version to solve one problem properly:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Attack → Capture Evidence → Fix → Retest → Verify&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Rather than trying to build an AI security platform that claims to test everything.&lt;/p&gt;

&lt;h2&gt;
  
  
  Final Thought
&lt;/h2&gt;

&lt;p&gt;AI security isn't only about making models refuse bad prompts.&lt;/p&gt;

&lt;p&gt;Once an AI system can retrieve documents, access APIs, execute tools, or influence application state, security becomes a system-level problem.&lt;/p&gt;

&lt;p&gt;That's what I wanted to explore with AI Red Team.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Don't just ask whether the AI works.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Try to break it.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Capture what happened.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Fix it.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Then attack it again.&lt;/strong&gt;&lt;/p&gt;

</description>
      <category>ai</category>
      <category>llm</category>
      <category>rag</category>
      <category>security</category>
    </item>
    <item>
      <title>I Built JARVIS to Put Security Guardrails Around My Vibe Coding Workflow</title>
      <dc:creator>Sreegeethesh</dc:creator>
      <pubDate>Wed, 16 Sep 2026 13:59:45 +0000</pubDate>
      <link>https://dev.to/sreegeetheshdhananjayan/i-built-jarvis-to-put-security-guardrails-around-my-vibe-coding-workflow-34a1</link>
      <guid>https://dev.to/sreegeetheshdhananjayan/i-built-jarvis-to-put-security-guardrails-around-my-vibe-coding-workflow-34a1</guid>
      <description>&lt;p&gt;I’ve been using AI coding agents heavily.&lt;/p&gt;

&lt;p&gt;They make it ridiculously easy to go from:&lt;/p&gt;

&lt;p&gt;“I have an idea”&lt;/p&gt;

&lt;p&gt;to:&lt;/p&gt;

&lt;p&gt;“I have a working application”&lt;/p&gt;

&lt;p&gt;But while preparing for a cybersecurity interview, I realized I had a problem.&lt;/p&gt;

&lt;p&gt;I was getting faster at building software.&lt;/p&gt;

&lt;p&gt;I wasn’t getting equally systematic at checking the software I was building.&lt;/p&gt;

&lt;p&gt;So I built something.&lt;/p&gt;

&lt;p&gt;Meet J.A.R.V.I.S. Framework.&lt;/p&gt;

&lt;p&gt;GitHub: &lt;a href="https://github.com/SREEGEETHES/J.A.R.V.I.S-framework" rel="noopener noreferrer"&gt;https://github.com/SREEGEETHES/J.A.R.V.I.S-framework&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;What is JARVIS?&lt;/p&gt;

&lt;p&gt;JARVIS is a universal audit and diagnostic framework for AI coding agents.&lt;/p&gt;

&lt;p&gt;The idea is to make an AI agent follow a structured engineering protocol instead of casually reviewing a project and saying:&lt;/p&gt;

&lt;p&gt;“Looks good.”&lt;/p&gt;

&lt;p&gt;The current framework has 158 checks.&lt;/p&gt;

&lt;p&gt;70 security checks&lt;/p&gt;

&lt;p&gt;The House Party Protocol covers things like:&lt;/p&gt;

&lt;p&gt;Secrets&lt;/p&gt;

&lt;p&gt;Authentication&lt;/p&gt;

&lt;p&gt;Authorization&lt;/p&gt;

&lt;p&gt;SQL injection&lt;/p&gt;

&lt;p&gt;XSS&lt;/p&gt;

&lt;p&gt;SSRF&lt;/p&gt;

&lt;p&gt;IDOR&lt;/p&gt;

&lt;p&gt;CSRF&lt;/p&gt;

&lt;p&gt;CORS&lt;/p&gt;

&lt;p&gt;Secure cookies&lt;/p&gt;

&lt;p&gt;AI security&lt;/p&gt;

&lt;p&gt;CI/CD security&lt;/p&gt;

&lt;p&gt;46 web launch checks&lt;/p&gt;

&lt;p&gt;Drop My Needle looks at:&lt;/p&gt;

&lt;p&gt;Performance&lt;/p&gt;

&lt;p&gt;Accessibility&lt;/p&gt;

&lt;p&gt;Legal requirements&lt;/p&gt;

&lt;p&gt;UX&lt;/p&gt;

&lt;p&gt;Asset optimization&lt;/p&gt;

&lt;p&gt;Forms&lt;/p&gt;

&lt;p&gt;Error pages&lt;/p&gt;

&lt;p&gt;Launch configuration&lt;/p&gt;

&lt;p&gt;42 deployment checks&lt;/p&gt;

&lt;p&gt;Prepare for Landing checks:&lt;/p&gt;

&lt;p&gt;Git hygiene&lt;/p&gt;

&lt;p&gt;Environment files&lt;/p&gt;

&lt;p&gt;Dependencies&lt;/p&gt;

&lt;p&gt;Build readiness&lt;/p&gt;

&lt;p&gt;Health checks&lt;/p&gt;

&lt;p&gt;Logging&lt;/p&gt;

&lt;p&gt;Rollback preparation&lt;/p&gt;

&lt;p&gt;Operational readiness&lt;/p&gt;

&lt;p&gt;The important part: No Fake Pass&lt;/p&gt;

&lt;p&gt;This is probably my favorite part of the framework.&lt;/p&gt;

&lt;p&gt;AI can be very confident.&lt;/p&gt;

&lt;p&gt;That doesn’t mean it is correct.&lt;/p&gt;

&lt;p&gt;So I created a simple rule:&lt;/p&gt;

&lt;p&gt;No evidence = No PASS&lt;/p&gt;

&lt;p&gt;If JARVIS can’t prove that a security control exists in the code, it shouldn’t mark the check as passed.&lt;/p&gt;

&lt;p&gt;The audit uses:&lt;/p&gt;

&lt;p&gt;PASS&lt;br&gt;
FAIL&lt;br&gt;
WAITING_AUTH&lt;/p&gt;

&lt;p&gt;This makes the agent focus on evidence instead of assumptions.&lt;/p&gt;

&lt;p&gt;Four phases&lt;/p&gt;

&lt;p&gt;Every major protocol follows:&lt;/p&gt;

&lt;p&gt;Discovery&lt;br&gt;
    ↓&lt;br&gt;
Audit&lt;br&gt;
    ↓&lt;br&gt;
Remediation&lt;br&gt;
    ↓&lt;br&gt;
Reporting&lt;/p&gt;

&lt;p&gt;Discovery&lt;/p&gt;

&lt;p&gt;Inspect the repository and identify relevant code and configuration.&lt;/p&gt;

&lt;p&gt;Audit&lt;/p&gt;

&lt;p&gt;Run the defined controls and collect evidence.&lt;/p&gt;

&lt;p&gt;Remediation&lt;/p&gt;

&lt;p&gt;Safe code issues can be fixed automatically.&lt;/p&gt;

&lt;p&gt;High-impact changes require human approval.&lt;/p&gt;

&lt;p&gt;Reporting&lt;/p&gt;

&lt;p&gt;Results are persisted in:&lt;/p&gt;

&lt;p&gt;.jarvis/STATE.md&lt;/p&gt;

&lt;p&gt;So the audit doesn’t disappear when the AI session ends.&lt;/p&gt;

&lt;p&gt;Why human authorization?&lt;/p&gt;

&lt;p&gt;I don’t want an AI agent to interpret:&lt;/p&gt;

&lt;p&gt;“Fix everything”&lt;/p&gt;

&lt;p&gt;as permission to modify production infrastructure.&lt;/p&gt;

&lt;p&gt;Some changes are fundamentally different from editing a source file.&lt;/p&gt;

&lt;p&gt;Changing:&lt;/p&gt;

&lt;p&gt;Cloud infrastructure&lt;/p&gt;

&lt;p&gt;Production credentials&lt;/p&gt;

&lt;p&gt;Databases&lt;/p&gt;

&lt;p&gt;Billing configuration&lt;/p&gt;

&lt;p&gt;External services&lt;/p&gt;

&lt;p&gt;should have a human checkpoint.&lt;/p&gt;

&lt;p&gt;That’s why JARVIS has a separate human authorization mode.&lt;/p&gt;

&lt;p&gt;And yes, the name is from Iron Man&lt;/p&gt;

&lt;p&gt;I’m a huge Iron Man fan.&lt;/p&gt;

&lt;p&gt;When I started this project, I wanted the experience to feel like having a technical co-pilot beside me.&lt;/p&gt;

&lt;p&gt;So JARVIS became the perfect name.&lt;/p&gt;

&lt;p&gt;But underneath the theme, the idea is pretty simple:&lt;/p&gt;

&lt;p&gt;Build fast with AI, but don’t skip the engineering checks.&lt;/p&gt;

&lt;p&gt;Supported environments&lt;/p&gt;

&lt;p&gt;The framework is designed to work across multiple AI coding environments, including:&lt;/p&gt;

&lt;p&gt;Antigravity&lt;/p&gt;

&lt;p&gt;OpenCode&lt;/p&gt;

&lt;p&gt;Claude Code&lt;/p&gt;

&lt;p&gt;Cursor&lt;/p&gt;

&lt;p&gt;Windsurf&lt;/p&gt;

&lt;p&gt;Cline / Roo Code&lt;/p&gt;

&lt;p&gt;The repository includes both global and project-level installation options.&lt;/p&gt;

&lt;p&gt;What I’m hoping to learn&lt;/p&gt;

&lt;p&gt;This is still an evolving project.&lt;/p&gt;

&lt;p&gt;I’m particularly interested in where this idea goes as AI coding agents become more capable.&lt;/p&gt;

&lt;p&gt;Can structured protocols make agents more reliable?&lt;/p&gt;

&lt;p&gt;Can persistent audit state make AI-assisted development easier to review?&lt;/p&gt;

&lt;p&gt;Can we automate more security checks without giving agents too much authority?&lt;/p&gt;

&lt;p&gt;That’s what I’m experimenting with.&lt;/p&gt;

&lt;p&gt;If you’re building with AI coding agents, I’d love to know how you’re handling security in your workflow.&lt;/p&gt;

&lt;p&gt;GitHub: &lt;a href="https://github.com/SREEGEETHES/J.A.R.V.I.S-framework" rel="noopener noreferrer"&gt;https://github.com/SREEGEETHES/J.A.R.V.I.S-framework&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  ai #security #devsecops #appsec #vibecoding #opensource #python #coding
&lt;/h1&gt;

</description>
      <category>agents</category>
      <category>ai</category>
      <category>cybersecurity</category>
      <category>security</category>
    </item>
    <item>
      <title>Your SaaS Isn't Production-Ready Just Because `npm run build` Works</title>
      <dc:creator>Sreegeethesh</dc:creator>
      <pubDate>Wed, 02 Sep 2026 11:48:48 +0000</pubDate>
      <link>https://dev.to/sreegeetheshdhananjayan/your-saas-isnt-production-ready-just-because-npm-run-build-works-1i43</link>
      <guid>https://dev.to/sreegeetheshdhananjayan/your-saas-isnt-production-ready-just-because-npm-run-build-works-1i43</guid>
      <description>&lt;p&gt;A few days ago, I was going through one of my SaaS applications before shipping it.&lt;/p&gt;

&lt;p&gt;The product worked.&lt;/p&gt;

&lt;p&gt;The UI looked good.&lt;/p&gt;

&lt;p&gt;The API worked.&lt;/p&gt;

&lt;p&gt;Authentication worked.&lt;/p&gt;

&lt;p&gt;And technically, I could have deployed it and called it done.&lt;/p&gt;

&lt;p&gt;But opening DevTools, viewing the page source, checking how Google would understand the site, and looking at the production bundle told a different story.&lt;/p&gt;

&lt;p&gt;A working application is not necessarily a production-ready application.&lt;/p&gt;

&lt;p&gt;So I ended up doing a complete frontend production-hardening pass.&lt;/p&gt;

&lt;p&gt;Here is the checklist I now use before calling a SaaS frontend ready for production.&lt;/p&gt;




&lt;h2&gt;
  
  
  1. Build a Proper Page Source
&lt;/h2&gt;

&lt;p&gt;Modern React applications can easily produce pages where the initial HTML tells crawlers almost nothing about the application.&lt;/p&gt;

&lt;p&gt;The browser eventually renders everything correctly, but crawlers, link previews, search engines, and other machines still benefit from meaningful HTML.&lt;/p&gt;

&lt;p&gt;I started checking the actual page source instead of judging the application only from what React rendered on screen.&lt;/p&gt;

&lt;p&gt;The page should expose enough meaningful information for machines to understand what it represents.&lt;/p&gt;




&lt;h2&gt;
  
  
  2. Build a Custom 404 Page
&lt;/h2&gt;

&lt;p&gt;A default server error or blank React page is a terrible dead end.&lt;/p&gt;

&lt;p&gt;A proper 404 page should:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;clearly explain that the requested page doesn't exist,&lt;/li&gt;
&lt;li&gt;maintain the product's branding,&lt;/li&gt;
&lt;li&gt;provide navigation back into the product,&lt;/li&gt;
&lt;li&gt;link to important pages,&lt;/li&gt;
&lt;li&gt;and return the correct HTTP status where possible.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Even error pages are part of the product experience.&lt;/p&gt;




&lt;h2&gt;
  
  
  3. Give Every Page a Unique Title
&lt;/h2&gt;

&lt;p&gt;One of the easiest mistakes in a SPA is having every route use the same title.&lt;/p&gt;

&lt;p&gt;For example:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;My SaaS&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;is much less useful than:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;AI Video Editor | ProductName&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;or:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;Pricing | ProductName&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Every important route now gets its own descriptive title.&lt;/p&gt;

&lt;p&gt;This improves search visibility, browser-tab usability, bookmarks, and link previews.&lt;/p&gt;




&lt;h2&gt;
  
  
  4. Write Useful Meta Descriptions
&lt;/h2&gt;

&lt;p&gt;I also stopped using generic descriptions such as:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;The best platform for everything.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Every important public page gets a description explaining what that specific page actually offers.&lt;/p&gt;

&lt;p&gt;Good metadata should help someone decide whether the page is relevant before they even open it.&lt;/p&gt;




&lt;h2&gt;
  
  
  5. Add Canonical URLs
&lt;/h2&gt;

&lt;p&gt;Applications often accidentally expose the same content through multiple URLs.&lt;/p&gt;

&lt;p&gt;Query parameters, alternate paths, trailing slashes, campaign URLs, and routing behavior can all create duplicate versions of a page.&lt;/p&gt;

&lt;p&gt;Canonical tags tell search engines which URL should be considered the authoritative one.&lt;/p&gt;

&lt;p&gt;A small detail, but an important one.&lt;/p&gt;




&lt;h2&gt;
  
  
  6. Use One Clear Primary Heading Per Page
&lt;/h2&gt;

&lt;p&gt;Design systems make it surprisingly easy to build pages that look visually correct while having terrible document structure underneath.&lt;/p&gt;

&lt;p&gt;Each page should have a clear purpose.&lt;/p&gt;

&lt;p&gt;The primary heading should communicate that purpose.&lt;/p&gt;

&lt;p&gt;Then the remaining headings should form a logical hierarchy.&lt;/p&gt;

&lt;p&gt;Not because an SEO plugin says so.&lt;/p&gt;

&lt;p&gt;Because semantic HTML makes the page easier for search engines, accessibility tools, browsers, and humans to understand.&lt;/p&gt;




&lt;h2&gt;
  
  
  7. Generate a Sitemap
&lt;/h2&gt;

&lt;p&gt;If the application contains publicly indexable pages, I add a &lt;code&gt;sitemap.xml&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;It contains the canonical public URLs I actually want crawled.&lt;/p&gt;

&lt;p&gt;The important part is not merely generating a sitemap.&lt;/p&gt;

&lt;p&gt;It is making sure the sitemap doesn't advertise pages that should never be indexed in the first place.&lt;/p&gt;




&lt;h2&gt;
  
  
  8. Configure &lt;code&gt;robots.txt&lt;/code&gt;
&lt;/h2&gt;

&lt;p&gt;Then comes &lt;code&gt;robots.txt&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;It communicates which sections crawlers should or shouldn't access and points them toward the sitemap.&lt;/p&gt;

&lt;p&gt;For SaaS products, this becomes especially useful when separating public marketing pages from dashboards, authenticated routes, internal tools, or temporary environments.&lt;/p&gt;




&lt;h2&gt;
  
  
  9. Add &lt;code&gt;llms.txt&lt;/code&gt;
&lt;/h2&gt;

&lt;p&gt;This one is newer.&lt;/p&gt;

&lt;p&gt;Alongside traditional search-engine optimization, I also started thinking about how AI systems understand products.&lt;/p&gt;

&lt;p&gt;I added an &lt;code&gt;llms.txt&lt;/code&gt; file containing a concise, machine-readable explanation of the product and its important resources.&lt;/p&gt;

&lt;p&gt;Whether &lt;code&gt;llms.txt&lt;/code&gt; becomes a universal standard or not, the underlying idea is worth paying attention to:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;websites are increasingly being consumed by machines other than traditional search crawlers.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;SEO is slowly becoming broader than Google.&lt;/p&gt;




&lt;h2&gt;
  
  
  10. Stop Treating the Favicon as an Afterthought
&lt;/h2&gt;

&lt;p&gt;That tiny icon appears everywhere:&lt;/p&gt;

&lt;p&gt;browser tabs, history, bookmarks, shortcuts, search interfaces, and sometimes mobile surfaces.&lt;/p&gt;

&lt;p&gt;I replaced the placeholder favicon with something simple, recognizable, high-contrast, and consistent with the product identity.&lt;/p&gt;

&lt;p&gt;Small visual elements can have an outsized effect on how finished a product feels.&lt;/p&gt;




&lt;h2&gt;
  
  
  11. Add Internal Links and Breadcrumbs
&lt;/h2&gt;

&lt;p&gt;A lot of SaaS landing pages behave like isolated islands.&lt;/p&gt;

&lt;p&gt;I started deliberately connecting related pages.&lt;/p&gt;

&lt;p&gt;Features → relevant use cases.&lt;/p&gt;

&lt;p&gt;Blog posts → related documentation.&lt;/p&gt;

&lt;p&gt;Documentation → product pages.&lt;/p&gt;

&lt;p&gt;Child pages → parent sections.&lt;/p&gt;

&lt;p&gt;Where the information hierarchy justified it, I added breadcrumbs as well.&lt;/p&gt;

&lt;p&gt;Good internal linking helps users navigate while also helping crawlers understand the structure and relationships between pages.&lt;/p&gt;




&lt;h2&gt;
  
  
  12. Add Structured Data
&lt;/h2&gt;

&lt;p&gt;Humans understand a page through visual context.&lt;/p&gt;

&lt;p&gt;Machines don't always get that luxury.&lt;/p&gt;

&lt;p&gt;Structured data gives additional context about what the page represents.&lt;/p&gt;

&lt;p&gt;Depending on the page, this can describe things such as:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;the organization,&lt;/li&gt;
&lt;li&gt;software/application information,&lt;/li&gt;
&lt;li&gt;articles,&lt;/li&gt;
&lt;li&gt;breadcrumbs,&lt;/li&gt;
&lt;li&gt;FAQs,&lt;/li&gt;
&lt;li&gt;or other supported entities.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For breadcrumb-enabled pages, I also added breadcrumb structured data rather than relying only on the visual component.&lt;/p&gt;




&lt;h2&gt;
  
  
  13. Fix Every Production Console Error
&lt;/h2&gt;

&lt;p&gt;One rule I started following:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;a production browser console should be boring.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;No mysterious errors.&lt;/p&gt;

&lt;p&gt;No failed requests.&lt;/p&gt;

&lt;p&gt;No hydration problems.&lt;/p&gt;

&lt;p&gt;No missing assets.&lt;/p&gt;

&lt;p&gt;No repeated warnings that everyone has learned to ignore.&lt;/p&gt;

&lt;p&gt;Warnings have a tendency to become background noise.&lt;/p&gt;

&lt;p&gt;And when the important error finally appears, nobody notices it.&lt;/p&gt;




&lt;h2&gt;
  
  
  14. Disable Production Source Maps When They Aren't Needed
&lt;/h2&gt;

&lt;p&gt;Development source maps are incredibly useful.&lt;/p&gt;

&lt;p&gt;Production source maps require more thought.&lt;/p&gt;

&lt;p&gt;Depending on the deployment model, publicly accessible source maps can expose significantly more information about the application's source than intended.&lt;/p&gt;

&lt;p&gt;For applications that don't need publicly shipped source maps, I disable them in the production build or upload private maps only to the monitoring platform that requires them.&lt;/p&gt;




&lt;h2&gt;
  
  
  15. Reduce Massive JavaScript Bundles
&lt;/h2&gt;

&lt;p&gt;Then I opened the bundle output.&lt;/p&gt;

&lt;p&gt;This is where things usually get interesting.&lt;/p&gt;

&lt;p&gt;A beautiful landing page shouldn't require downloading a ridiculous amount of JavaScript before becoming useful.&lt;/p&gt;

&lt;p&gt;I started looking for:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;oversized dependencies,&lt;/li&gt;
&lt;li&gt;libraries imported globally,&lt;/li&gt;
&lt;li&gt;components that could be lazy-loaded,&lt;/li&gt;
&lt;li&gt;routes that could be code-split,&lt;/li&gt;
&lt;li&gt;duplicate dependencies,&lt;/li&gt;
&lt;li&gt;unused packages,&lt;/li&gt;
&lt;li&gt;and features that shouldn't be in the initial bundle.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Bundle size is not just a Lighthouse metric.&lt;/p&gt;

&lt;p&gt;It affects actual humans using slower hardware and slower networks.&lt;/p&gt;




&lt;h2&gt;
  
  
  16. Remove Every Default Vite/React Placeholder
&lt;/h2&gt;

&lt;p&gt;This sounds obvious.&lt;/p&gt;

&lt;p&gt;Yet production applications constantly ship with traces of their scaffolding.&lt;/p&gt;

&lt;p&gt;Vite logos.&lt;/p&gt;

&lt;p&gt;React favicons.&lt;/p&gt;

&lt;p&gt;Default metadata.&lt;/p&gt;

&lt;p&gt;Placeholder page titles.&lt;/p&gt;

&lt;p&gt;Starter README text.&lt;/p&gt;

&lt;p&gt;Example assets.&lt;/p&gt;

&lt;p&gt;Development console messages.&lt;/p&gt;

&lt;p&gt;Boilerplate copy.&lt;/p&gt;

&lt;p&gt;I now search the repository before release and remove anything that makes the application look like a starter template instead of an actual product.&lt;/p&gt;




&lt;h1&gt;
  
  
  The Bigger Lesson
&lt;/h1&gt;

&lt;p&gt;None of these changes individually feels revolutionary.&lt;/p&gt;

&lt;p&gt;That is exactly why they get ignored.&lt;/p&gt;

&lt;p&gt;Developers naturally focus on the difficult parts:&lt;/p&gt;

&lt;p&gt;authentication,&lt;br&gt;
databases,&lt;br&gt;
payments,&lt;br&gt;
AI pipelines,&lt;br&gt;
background jobs,&lt;br&gt;
infrastructure,&lt;br&gt;
and application logic.&lt;/p&gt;

&lt;p&gt;Then we finish the feature and mentally declare the product complete.&lt;/p&gt;

&lt;p&gt;But production quality lives in hundreds of smaller decisions surrounding the feature.&lt;/p&gt;

&lt;p&gt;Can Google understand the page?&lt;/p&gt;

&lt;p&gt;Can an AI system understand the product?&lt;/p&gt;

&lt;p&gt;Does the browser console stay clean?&lt;/p&gt;

&lt;p&gt;Does a broken URL still feel like part of the application?&lt;/p&gt;

&lt;p&gt;Are users downloading JavaScript they don't need?&lt;/p&gt;

&lt;p&gt;Does the website still advertise the framework used to scaffold it?&lt;/p&gt;

&lt;p&gt;Does every page actually explain what it is?&lt;/p&gt;

&lt;p&gt;These aren't glamorous engineering tasks.&lt;/p&gt;

&lt;p&gt;But together they make the difference between:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;“I built a React app.”&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;and&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;“I shipped a product.”&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;My current pre-production frontend checklist:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Meaningful page source&lt;/li&gt;
&lt;li&gt;Custom 404&lt;/li&gt;
&lt;li&gt;Unique page titles&lt;/li&gt;
&lt;li&gt;Page-specific meta descriptions&lt;/li&gt;
&lt;li&gt;Canonical URLs&lt;/li&gt;
&lt;li&gt;Semantic page headings&lt;/li&gt;
&lt;li&gt;&lt;code&gt;sitemap.xml&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;robots.txt&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;llms.txt&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Product-specific favicon&lt;/li&gt;
&lt;li&gt;Internal links + breadcrumbs&lt;/li&gt;
&lt;li&gt;Structured data&lt;/li&gt;
&lt;li&gt;Zero unexplained console errors&lt;/li&gt;
&lt;li&gt;Production source-map strategy&lt;/li&gt;
&lt;li&gt;JavaScript bundle optimization&lt;/li&gt;
&lt;li&gt;Zero framework placeholders&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;I'm probably going to keep extending this checklist as I ship more products.&lt;/p&gt;

&lt;p&gt;Because shipping the feature is only half the job.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The other half is making the web understand what you shipped.&lt;/strong&gt;&lt;/p&gt;

</description>
      <category>frontend</category>
      <category>performance</category>
      <category>saas</category>
      <category>seo</category>
    </item>
    <item>
      <title># I Built My Developer Portfolio as Peter Parker's Lab 🕷️</title>
      <dc:creator>Sreegeethesh</dc:creator>
      <pubDate>Thu, 13 Aug 2026 06:21:19 +0000</pubDate>
      <link>https://dev.to/sreegeetheshdhananjayan/-i-built-my-developer-portfolio-as-peter-parkers-lab-49hd</link>
      <guid>https://dev.to/sreegeetheshdhananjayan/-i-built-my-developer-portfolio-as-peter-parkers-lab-49hd</guid>
      <description>&lt;p&gt;I could have built another developer portfolio.&lt;/p&gt;

&lt;p&gt;You know the one.&lt;/p&gt;

&lt;p&gt;Dark background.&lt;/p&gt;

&lt;p&gt;Glowing buttons.&lt;/p&gt;

&lt;p&gt;"Full Stack Developer | AI | Cloud | DevOps"&lt;/p&gt;

&lt;p&gt;Six project cards.&lt;/p&gt;

&lt;p&gt;GitHub link.&lt;/p&gt;

&lt;p&gt;Done.&lt;/p&gt;

&lt;p&gt;But honestly, that doesn't feel like me.&lt;/p&gt;

&lt;p&gt;Before I was interested in AI, software engineering, cloud, automation and all the other things I keep breaking and rebuilding, I was just a kid who loved Spider-Man.&lt;/p&gt;

&lt;p&gt;And the older I got, the more I realized that I didn't actually relate to Spider-Man because he was a superhero.&lt;/p&gt;

&lt;p&gt;I related to &lt;strong&gt;Peter Parker&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;The curious kid.&lt;/p&gt;

&lt;p&gt;The awkward kid.&lt;/p&gt;

&lt;p&gt;The kid who builds things.&lt;/p&gt;

&lt;p&gt;The kid who experiments.&lt;/p&gt;

&lt;p&gt;The kid who fails and somehow keeps going.&lt;/p&gt;

&lt;p&gt;That felt familiar.&lt;/p&gt;

&lt;p&gt;So when I started building my portfolio, I wanted it to represent that.&lt;/p&gt;

&lt;p&gt;I called it:&lt;/p&gt;

&lt;h2&gt;
  
  
  🧪 Peter Parker's Lab
&lt;/h2&gt;

&lt;p&gt;The idea is that my portfolio is basically my digital lab.&lt;/p&gt;

&lt;p&gt;A place where I can show what I'm building, what I'm learning and what I'm experimenting with.&lt;/p&gt;

&lt;p&gt;🕷️ &lt;strong&gt;Peter Parker&lt;/strong&gt; → curiosity&lt;/p&gt;

&lt;p&gt;🕸️ &lt;strong&gt;Spider-Man&lt;/strong&gt; → persistence&lt;/p&gt;

&lt;p&gt;💻 &lt;strong&gt;Developer&lt;/strong&gt; → everything I'm building today&lt;/p&gt;

&lt;p&gt;And honestly, "lab" describes my development journey pretty well.&lt;/p&gt;

&lt;p&gt;I build something.&lt;/p&gt;

&lt;p&gt;It breaks.&lt;/p&gt;

&lt;p&gt;I investigate why.&lt;/p&gt;

&lt;p&gt;I fix it.&lt;/p&gt;

&lt;p&gt;Then I get another idea and break something else.&lt;/p&gt;

&lt;p&gt;😂&lt;/p&gt;

&lt;p&gt;That's the fun part.&lt;/p&gt;

&lt;p&gt;I'm currently interested in building things around:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;AI&lt;/li&gt;
&lt;li&gt;AI agents&lt;/li&gt;
&lt;li&gt;automation&lt;/li&gt;
&lt;li&gt;full-stack applications&lt;/li&gt;
&lt;li&gt;developer tools&lt;/li&gt;
&lt;li&gt;cloud infrastructure&lt;/li&gt;
&lt;li&gt;DevOps&lt;/li&gt;
&lt;li&gt;local-first software&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I'm not trying to pretend I've mastered all of it.&lt;/p&gt;

&lt;p&gt;I'm trying to keep learning by &lt;strong&gt;building real things&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;That's what I want this portfolio to show.&lt;/p&gt;

&lt;p&gt;Not just a list of technologies.&lt;/p&gt;

&lt;p&gt;Not just a list of GitHub repositories.&lt;/p&gt;

&lt;p&gt;But the problems I'm curious about and the things I'm actually trying to create.&lt;/p&gt;

&lt;p&gt;🌐 &lt;strong&gt;Peter Parker's Lab&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://peterparker-lab.vercel.app/" rel="noopener noreferrer"&gt;https://peterparker-lab.vercel.app/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This is version one.&lt;/p&gt;

&lt;p&gt;I'll keep changing it as I change.&lt;/p&gt;

&lt;p&gt;New projects.&lt;/p&gt;

&lt;p&gt;New experiments.&lt;/p&gt;

&lt;p&gt;New ideas.&lt;/p&gt;

&lt;p&gt;Probably new bugs too.&lt;/p&gt;

&lt;p&gt;Because maybe the best portfolio isn't one that says:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"Look how much I know."&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Maybe it's one that says:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;"Look what I'm curious enough to build next."&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;🕷️❤️&lt;/p&gt;

&lt;p&gt;And yes...&lt;/p&gt;

&lt;p&gt;I still think Spider-Man is one of the coolest characters ever.&lt;/p&gt;

&lt;p&gt;Some things don't change.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>webdev</category>
      <category>programming</category>
      <category>productivity</category>
    </item>
    <item>
      <title>I Built an Open-Source AI Video Clipping Pipeline</title>
      <dc:creator>Sreegeethesh</dc:creator>
      <pubDate>Sat, 08 Aug 2026 06:46:05 +0000</pubDate>
      <link>https://dev.to/sreegeetheshdhananjayan/i-built-an-open-source-ai-video-clipping-pipeline-13c6</link>
      <guid>https://dev.to/sreegeetheshdhananjayan/i-built-an-open-source-ai-video-clipping-pipeline-13c6</guid>
      <description>&lt;h1&gt;
  
  
  I Built an Open-Source AI Video Clipping Pipeline
&lt;/h1&gt;

&lt;p&gt;I wanted a tool that could take a long video and turn it into social-ready clips without uploading the entire video to some SaaS platform.&lt;/p&gt;

&lt;p&gt;So I built &lt;strong&gt;AutoClip&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;The idea is simple:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;YouTube URL / Video File
          ↓
      Transcription
          ↓
   LLM Clip Selection
          ↓
   Vertical Reframing
          ↓
    Speaker Tracking
          ↓
   Animated Captions
          ↓
     MP4 Export
          ↓
    Buffer Scheduling
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;The interesting part is that the video processing happens locally.&lt;/p&gt;

&lt;p&gt;AutoClip uses an LLM to identify moments worth clipping, but only the transcript text is sent to the LLM. The actual video stays on the user's machine.&lt;/p&gt;

&lt;p&gt;It supports multiple caption styles:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Word Pop&lt;/li&gt;
&lt;li&gt;Karaoke Fill&lt;/li&gt;
&lt;li&gt;Clean Lower Third&lt;/li&gt;
&lt;li&gt;Boxed&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The final clips are rendered as 9:16 MP4s ready for social platforms.&lt;/p&gt;
&lt;h2&gt;
  
  
  Publishing Architecture
&lt;/h2&gt;

&lt;p&gt;I also wanted publishing to follow the same privacy model.&lt;/p&gt;

&lt;p&gt;Instead of building a cloud scheduler, AutoClip uses a BYOK approach.&lt;/p&gt;

&lt;p&gt;The stack is:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Your PC
  ↓
AutoClip processes video
  ↓
Cloudflare R2
  ↓
Buffer
  ↓
Social Platform
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;The R2 bucket acts as temporary media storage so Buffer can access the video.&lt;/p&gt;

&lt;p&gt;Once the job is handed off, the user's computer doesn't need to stay online.&lt;/p&gt;

&lt;p&gt;No central media storage.&lt;/p&gt;

&lt;p&gt;No SaaS layer.&lt;/p&gt;

&lt;p&gt;No subscription.&lt;/p&gt;

&lt;p&gt;No watermark.&lt;/p&gt;

&lt;p&gt;No telemetry.&lt;/p&gt;

&lt;p&gt;Just your infrastructure and your API keys.&lt;/p&gt;
&lt;h2&gt;
  
  
  Why I Built It
&lt;/h2&gt;

&lt;p&gt;There are plenty of AI video tools already.&lt;/p&gt;

&lt;p&gt;I wanted one where I could actually understand and control what happens to my content.&lt;/p&gt;

&lt;p&gt;The goal was:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Your machine edits.&lt;br&gt;
Your Buffer publishes.&lt;br&gt;
Your content stays yours.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;AutoClip is open source.&lt;/p&gt;

&lt;p&gt;GitHub:&lt;br&gt;
&lt;/p&gt;
&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://assets.dev.to/assets/github-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/SREEGEETHES" rel="noopener noreferrer"&gt;
        SREEGEETHES
      &lt;/a&gt; / &lt;a href="https://github.com/SREEGEETHES/Autoclip" rel="noopener noreferrer"&gt;
        Autoclip
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      
    &lt;/h3&gt;
  &lt;/div&gt;
  &lt;div class="ltag-github-body"&gt;
    
&lt;div id="readme" class="md"&gt;&lt;div class="markdown-heading"&gt;
&lt;h1 class="heading-element"&gt;AutoClip&lt;/h1&gt;
&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;The local-first AI clipper that finishes the job.&lt;/strong&gt; Drop in a long video → get ranked, caption-burned, speaker-tracked 9:16 clips out — and schedule them to post while your PC is off.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/artbyjazi/autoclip/actions/workflows/ci.yml" rel="noopener noreferrer"&gt;&lt;img src="https://github.com/artbyjazi/autoclip/actions/workflows/ci.yml/badge.svg" alt="CI"&gt;&lt;/a&gt;
&lt;a href="https://github.com/SREEGEETHES/Autoclip/LICENSE" rel="noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/7013272bd27ece47364536a221edb554cd69683b68a46fc0ee96881174c4214c/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f6c6963656e73652d4d49542d626c75652e737667" alt="License: MIT"&gt;&lt;/a&gt;
&lt;a href="https://www.python.org/" rel="nofollow noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/a8bc94425f437747429dfc6929f451b6e81b6081d311bb6120d68ca668ee2768/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f707974686f6e2d332e3131253230253743253230332e31322d626c75652e737667" alt="Python 3.11 | 3.12"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Paste a YouTube link or drop a file. AutoClip transcribes it, uses an LLM to find the moments actually worth clipping, reframes them to vertical while tracking whoever is speaking, burns in animated captions, exports platform-ready MP4s — then hands the finished clips to Buffer to publish on schedule. No accounts with us. No uploads to our servers. No watermarks. No subscription.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Your machine edits. Your Buffer publishes. Your R2 bridges the media. Nobody owns your content but you.&lt;/strong&gt;&lt;/p&gt;

&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;What it does&lt;/h2&gt;
&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Ingest anything&lt;/strong&gt; — a YouTube URL or a local file, hours long or minutes.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Find the real hooks&lt;/strong&gt; — an LLM reads the transcript and ranks the moments worth clipping, down to the word. Timing…&lt;/li&gt;
&lt;/ul&gt;&lt;/div&gt;
  &lt;/div&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/SREEGEETHES/Autoclip" rel="noopener noreferrer"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;/div&gt;


&lt;p&gt;I'd love feedback from anyone building content automation, video tooling, or local-first AI applications.&lt;/p&gt;

</description>
      <category>opusclipalternative</category>
      <category>webdev</category>
      <category>ai</category>
      <category>programming</category>
    </item>
    <item>
      <title>How I built an offline semantic photo search app (Python + Vector DB)</title>
      <dc:creator>Sreegeethesh</dc:creator>
      <pubDate>Mon, 03 Aug 2026 10:51:14 +0000</pubDate>
      <link>https://dev.to/sreegeetheshdhananjayan/how-i-built-an-offline-semantic-photo-search-app-python-vector-db-3da9</link>
      <guid>https://dev.to/sreegeetheshdhananjayan/how-i-built-an-offline-semantic-photo-search-app-python-vector-db-3da9</guid>
      <description>&lt;h1&gt;
  
  
  Show DEV 🚀
&lt;/h1&gt;

&lt;p&gt;I built &lt;strong&gt;OmniCard&lt;/strong&gt;, a local-first AI media manager.&lt;/p&gt;

&lt;p&gt;Features:&lt;/p&gt;

&lt;p&gt;• Semantic image search&lt;/p&gt;

&lt;p&gt;• AI captions&lt;/p&gt;

&lt;p&gt;• Smart tags&lt;/p&gt;

&lt;p&gt;• Duplicate detection&lt;/p&gt;

&lt;p&gt;• SQLite + LanceDB&lt;/p&gt;

&lt;p&gt;• Desktop application with pywebview&lt;/p&gt;

&lt;p&gt;The goal was simple:&lt;/p&gt;

&lt;p&gt;Search photos by what's inside them instead of by filename.&lt;/p&gt;

&lt;p&gt;Example:&lt;/p&gt;

&lt;p&gt;"Drone over mountains"&lt;/p&gt;

&lt;p&gt;instead of&lt;/p&gt;

&lt;p&gt;IMG_4829.jpg&lt;/p&gt;

&lt;p&gt;The app stores everything locally, so your media never leaves your computer.&lt;/p&gt;

&lt;p&gt;Live demo:&lt;br&gt;
&lt;a href="https://sreegeethes.github.io/Omnicard/" rel="noopener noreferrer"&gt;https://sreegeethes.github.io/Omnicard/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;GitHub:&lt;br&gt;
&lt;a href="https://github.com/SREEGEETHES/Omnicard" rel="noopener noreferrer"&gt;https://github.com/SREEGEETHES/Omnicard&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Release:&lt;br&gt;
&lt;a href="https://github.com/SREEGEETHES/Omnicard/releases/tag/v1.0.0" rel="noopener noreferrer"&gt;https://github.com/SREEGEETHES/Omnicard/releases/tag/v1.0.0&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Would love feedback from other Python and AI developers.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>database</category>
      <category>python</category>
      <category>showdev</category>
    </item>
  </channel>
</rss>
