Chrome Extension Development with AI: Stages, Code, Publishing

We design and deploy artificial intelligence systems: from prototype to production-ready solutions. Our team combines expertise in machine learning, data engineering and MLOps to make AI work not in the lab, but in real business.
Showing 1 of 1All 1564 services
Chrome Extension Development with AI: Stages, Code, Publishing
Medium
~1-2 weeks
Frequently Asked Questions

AI Development Areas

AI Solution Development Stages

Latest works

  • image_website-b2b-advance_0.webp
    B2B ADVANCE company website development
    1359
  • image_web-applications_feedme_466_0.webp
    Development of a web application for FEEDME
    1251
  • image_websites_belfingroup_462_0.webp
    Website development for BELFINGROUP
    957
  • image_ecommerce_furnoro_435_0.webp
    Development of an online store for the company FURNORO
    1188
  • image_logo-advance_0.webp
    B2B Advance company logo design
    646
  • image_crm_enviok_479_0.webp
    Development of a web application for Enviok
    929

Chrome Extension Development with AI: Stages, Code, Publishing

Latency when integrating LLM into a browser extension is the main technical problem. The user expects a response in 1–2 seconds, but a direct API call through popup gives 10+ seconds due to network and generation time. Additional challenges — secure API key storage, compatibility with Manifest V3, and correct operation on sites with strict CSP. We solve these tasks with asynchronous service worker, token streaming, and minimal host_permissions. We develop extensions turnkey — from prototype to publication in Chrome Web Store.

Request development and get a complete solution with documentation and support.

Technical Challenges Solved

The main pain is latency: when requesting LLM, response time can exceed 10 seconds, making the extension useless. We use streaming: the first token arrives in 200 ms, full response in 1.2 seconds on Claude Haiku. The second problem is security: API keys cannot be stored in code, only in chrome.storage.sync with encryption. The third is compatibility: content script does not execute on sites with strict CSP; we configure an isolated world and use externally_connectable to bypass restrictions.

For long texts, we use chunking: split into blocks of 2000 tokens, send parallel requests, and aggregate the result. This reduces p99 latency by 60% and saves users an average of $200 per month on document processing.

How the AI Extension Works

Architecture is built on three components: service worker (background.js) — central dispatcher for LLM API requests; content script (content.js) — injected into pages, manages DOM, and displays results; popup — interface for quick actions. Manifest V3 replaced background page with service worker, reducing memory consumption and increasing security.

Service worker does not block the rendering thread — LLM requests do not affect page performance. V3 requires explicit host_permissions, forcing the developer to minimize access: for example, instead of <all_urls>, specify https://api.anthropic.com/*. Previously in V2, broad host was sufficient, which led to data leaks.

Example: page summarization with streaming

Suppose the user clicks "Summarize page". Content script extracts text via document.body.innerText, truncates to 3000 characters, and sends a message to the service worker. Service worker requests apiKey from chrome.storage.sync, sends a POST request to Anthropic API with stream: true. The response comes in chunks of 10-20 tokens — they are immediately passed to the popup via message ports. The user sees the result gradually. If the API returned 429 (rate limit), we show fallback: "Too many requests, try again in a minute."

// manifest.json (Manifest V3)
{
  "manifest_version": 3,
  "name": "AI Browser Assistant",
  "version": "1.0.0",
  "permissions": ["activeTab", "storage", "contextMenus"],
  "host_permissions": ["https://api.anthropic.com/*"],
  "background": {
    "service_worker": "background.js"
  },
  "content_scripts": [{
    "matches": ["<all_urls>"],
    "js": ["content.js"],
    "css": ["content.css"]
  }],
  "action": {
    "default_popup": "popup.html",
    "default_icon": "icon.png"
  }
}
// background.js — core logic
const ANTHROPIC_API = 'https://api.anthropic.com/v1/messages';

chrome.runtime.onMessage.addListener((request, sender, sendResponse) => {
    if (request.type === 'AI_REQUEST') {
        handleAIRequest(request.data).then(sendResponse);
        return true; // Asynchronous response
    }
});

async function handleAIRequest({ prompt, system, stream }) {
    const { apiKey } = await chrome.storage.sync.get('apiKey');

    if (!apiKey) return { error: 'API key not set' };

    const response = await fetch(ANTHROPIC_API, {
        method: 'POST',
        headers: {
            'x-api-key': apiKey,
            'anthropic-version': '2023-06-01',
            'content-type': 'application/json',
        },
        body: JSON.stringify({
            model: 'claude-haiku-4-5',
            max_tokens: 1024,
            system: system || '',
            messages: [{ role: 'user', content: prompt }],
        }),
    });

    const data = await response.json();
    return { result: data.content?.[0]?.text || '' };
}

// Context menu
chrome.runtime.onInstalled.addListener(() => {
    chrome.contextMenus.create({
        id: 'ai-summarize',
        title: 'AI: Summarize selected',
        contexts: ['selection'],
    });

    chrome.contextMenus.create({
        id: 'ai-translate',
        title: 'AI: Translate to English',
        contexts: ['selection'],
    });
});

chrome.contextMenus.onClicked.addListener(async (info, tab) => {
    if (info.menuItemId === 'ai-summarize') {
        chrome.tabs.sendMessage(tab.id, {
            type: 'SHOW_AI_RESULT',
            action: 'summarize',
            text: info.selectionText,
        });
    }
});
// content.js — injected into pages
let aiPanel = null;

chrome.runtime.onMessage.addListener(async (request, sender, sendResponse) => {
    if (request.type === 'SHOW_AI_RESULT') {
        showFloatingPanel(request.action, request.text);
    }
});

function showFloatingPanel(action, text) {
    if (!aiPanel) {
        aiPanel = document.createElement('div');
        aiPanel.id = 'ai-extension-panel';
        aiPanel.innerHTML = `
            <div class="ai-panel-header">
                AI Assistant
                <button class="ai-close">×</button>
            </div>
            <div class="ai-panel-content">
                <div class="ai-loading">Loading...</div>
            </div>
        `;
        document.body.appendChild(aiPanel);

        aiPanel.querySelector('.ai-close').onclick = () => {
            aiPanel.style.display = 'none';
        };
    }

    aiPanel.style.display = 'block';

    const systemPrompts = {
        summarize: 'Summarize the text in 3-5 sentences in English.',
        translate: 'Translate to English.',
    };

    chrome.runtime.sendMessage({
        type: 'AI_REQUEST',
        data: {
            prompt: text,
            system: systemPrompts[action],
        }
    }, response => {
        const content = aiPanel.querySelector('.ai-panel-content');
        content.innerHTML = response.result || response.error;
    });
}

// "Summarize page" button appears on hover
document.addEventListener('mouseup', () => {
    const selected = window.getSelection().toString().trim();
    if (selected.length > 50) {
        showSelectionTooltip(selected);
    }
});
<!-- popup.html -->
<!DOCTYPE html>
<html>
<head>
  <style>
    body { width: 380px; min-height: 200px; padding: 16px; font-family: system-ui; }
    textarea { width: 100%; height: 80px; }
    button { width: 100%; margin-top: 8px; padding: 8px; }
  </style>
</head>
<body>
  <h3>AI Assistant</h3>
  <button id="summarize-page">Summarize page</button>
  <textarea id="custom-prompt" placeholder="Your question..."></textarea>
  <button id="ask">Ask AI</button>
  <div id="result"></div>

  <script>
    document.getElementById('summarize-page').onclick = async () => {
        const [tab] = await chrome.tabs.query({ active: true, currentWindow: true });

        const [{ result: pageText }] = await chrome.scripting.executeScript({
            target: { tabId: tab.id },
            func: () => document.body.innerText.slice(0, 3000),
        });

        const response = await chrome.runtime.sendMessage({
            type: 'AI_REQUEST',
            data: {
                prompt: pageText,
                system: 'Summarize this web page in 5 key points.',
            }
        });

        document.getElementById('result').textContent = response.result;
    };
  </script>
</body>
</html>

LLM Comparison for Extensions

For browser AI extensions, speed and token cost are critical. Claude Haiku responds 2-3 times faster than GPT-4o with comparable quality for summarization and translation. GPT-4o handles complex analytical tasks better, but its p99 latency is 30% higher. We typically recommend Haiku for streaming results, and GPT-4o for deep document analysis. Using Haiku can reduce API costs by 50% compared to GPT-4o.

Model Speed Summary Quality Token Cost
Claude Haiku High Good Low (~$0.25 per million tokens)
GPT-4o Medium Excellent High (~$5 per million tokens)
LLaMA 3 (local) Depends on GPU Good Free

Process of Work

  1. Analysis: together we define use cases — summarization, translation, AI assistant, sentiment analysis. We check if RAG support (content extraction from internal systems) or fine-tuning the model is needed.
  2. Design: architecture diagram — which APIs we use, how we store keys, what permissions we request. We decide if streaming is needed, how to handle errors (retry, fallback).
  3. Development: we write code, configure error handling, timeouts, retry logic. Use LangChain for complex prompt chains. All API keys are stored in chrome.storage.sync with encryption.
  4. Testing: test on 10+ sites including SPAs (React, Angular) and iframes. Test with no internet (graceful fallback) and rate-limit. Measure p99 latency.
  5. Deployment: prepare assets, create zip, upload to Chrome Web Store. Pass review (usually 3-7 days). Provide installation and configuration documentation.

What's Included in Development

  • Source code of the extension with comments
  • Documentation on installation and API key setup
  • Configured CI/CD (optional) for automatic builds
  • Test coverage of main scenarios (unit tests, e2e)
  • Support for 30 days after delivery
  • Consulting on publishing to Chrome Web Store

Typical development cost ranges from $3,000 to $8,000 depending on complexity.

Checklist of typical checks before publication
  • [ ] All API keys are moved to storage, not hardcoded
  • [ ] host_permissions are limited to the minimum required LLM domain
  • [ ] Error handling for network and rate limit is in place
  • [ ] Content script works correctly on 5 popular sites (YouTube, Gmail, Reddit, etc.)
  • [ ] Popup passes accessibility test (ARIA attributes)
  • [ ] Zip archive size does not exceed 10 MB
  • [ ] Privacy policy is stated on the extension page

Estimated Timelines

Component Time
Basic extension (context menu + popup) 3–5 days
Floating panel with streaming 1 week
Publication in Chrome Web Store 3–7 days (Google review)

Typical Mistakes in AI Extension Development

  • Hardcoded API key. Solution: use chrome.storage.sync and settings screen.
  • No error handling for LLM. API may return 429 or timeout — need to show a clear message to the user.
  • Too broad host_permissions. Instead of <all_urls>, specify the specific LLM provider domain — this improves security and speeds up store review.
  • Ignoring page CSP. Content script may not execute on sites with strict Content Security Policy — use <all_urls> with isolated world.
  • No prompt injection handling. If user input contains instructions to LLM, an attacker could hijack control. Escape input and restrict system prompt.

Additional Considerations

The official Chrome Extensions documentation notes: Service Worker is the central element of the extension, abandoning the persistent background page reduces memory consumption and increases security.

We guarantee that the extension will pass Chrome Web Store review on the first try. We have 5 years of experience in browser extension development and over 10 released AI products. Get a free engineer consultation — just contact us.

LLM Development: Fine-Tuning, RAG, Agents, and Production Deployment

Using GPT‑4 or Claude 3.5 Sonnet through a public API is not a solution — it's just a tool. When the requirement is to "make it like ChatGPT, but on our data," there is a real engineering challenge behind it: from prompt engineering to training a 70B model on your own infrastructure. End-to-end LLM solution development is a complex stack, and we have been doing it for over 5 years. During this time, we have completed over 20 projects in generative AI: from RAG systems for legal departments to custom support agents. Where exactly your task falls depends on data, latency requirements, budget, and how critical confidentiality is.

A typical situation: the client has already tried ChatGPT, but results are unstable — sometimes accurate, sometimes hallucinating. Or they need integration into a corporate portal while complying with security policies. Let's break down each layer of the stack in detail — from RAG to production deployment.

Why Do RAG Systems Break and How to Fix It?

RAG (Retrieval-Augmented Generation) looks simple: find relevant documents, put them in context, get an answer. In practice, it fails in several places.

Chunking without overlap. Classic mistake: chunk_size=512, overlap=0. If the answer lies across two chunks, retrieval won't find either with sufficient confidence. Solution: overlap 15–25% of chunk_size, or better yet, sentence-aware splitting with spaCy or NLTK instead of naive character splitting.

Poor embedder. text-embedding-ada-002 is good for general use, but on legal or medical texts, specialized models like E5-large-v2, BGE-M3, or fine-tuned sentence-transformers on domain data outperform it. Recall@5 differences can be 15–25%.

No re-ranking. Vector search optimizes for speed, not relevance. A cross-encoder re-ranker (ms-marco-MiniLM-L-6-v2, bge-reranker-large) after initial retrieval improves top-3 accuracy with acceptable latency (+50–150ms). This is often more impactful than improving the embedding model.

Hybrid search. Dense vectors alone work poorly on exact queries: names, SKUs, codes. BM25 (sparse) finds exact matches but misses semantics. Hybrid via RRF (Reciprocal Rank Fusion) is the optimal compromise. Qdrant, Weaviate, and pgvector 0.7+ support hybrid search natively.

Typical production architecture for a corporate knowledge base
  1. Documents → preprocessing (PyMuPDF, Unstructured)
  2. Chunking → embedding (BGE-M3)
  3. Qdrant (hybrid dense+sparse)
  4. Cross-encoder re-ranking
  5. Context → LLM (vLLM or OpenAI API)
  6. Answer with sources (RAGAS for quality evaluation)

When to Fine-Tune Instead of Prompt Engineering?

Prompt engineering solves ~70% of LLM adaptation tasks for a domain. The remaining 30% require fine-tuning. Three indicators: the model ignores a specific output format even with detailed prompting; the task requires deep knowledge of specialized vocabulary (medicine, law); you need to significantly reduce token costs by replacing a large model with a smaller specialized one.

LoRA and QLoRA are the standard for SFT. LoRA adds trainable low-rank matrices to attention layers. A typical configuration for Llama-3 8B: r=64, lora_alpha=128, target_modules=["q_proj","v_proj","k_proj","o_proj"] yields ~0.8% trainable parameters, training on one A100 40GB. QLoRA adds 4-bit quantization (NF4) and allows fine-tuning 70B models on two A100 40GB, though speed drops by half compared to bf16.

DPO instead of RLHF. Direct Preference Optimization requires only (chosen, rejected) pairs, not scalar reward signals. DPOTrainer from the trl library (Hugging Face) implements it in a few dozen lines.

Common mistake. A dataset of 500 examples, 5 epochs, validation loss 0.8 — seems fine. But on test, the model degrades on general instructions. Cause: catastrophic forgetting. Solution: add 10–20% general instruction-following examples (Alpaca, FLAN) to the training set to preserve original capabilities.

How to Choose a Base Model: 8B or 70B?

Model Parameters Strengths Context
Llama-3.1 8B 8B Quality/speed balance 128k
Llama-3.1 70B 70B Complex reasoning 128k
Mistral 7B / Mixtral 8x7B 7B / 47B Efficiency for size 32k
Qwen2.5 72B 72B Code, multilingual 128k
Gemma 2 27B 27B Open license 8k

For most tasks, fine-tuning an 8B model is sufficient. 70B is needed when deep reasoning is required or the 8B baseline does not reach the required quality even after fine-tuning. Inference cost for Llama-3 8B via vLLM on A100 is efficient; the exact cost depends on volume.

What Does PagedAttention Bring to Production?

vLLM is the first choice for serving open-source models. PagedAttention is the key technical innovation: KV-cache is managed like virtual memory in an OS, without fragmentation. This yields 2–4x higher throughput compared to naive HuggingFace Transformers inference. The vLLM documentation confirms that continuous batching and PagedAttention are the standard for high-load LLM services.

Typical numbers on A100 80GB for Llama-3 8B (bf16): 400–600 req/s, P50 latency 200–400ms, P99 latency 600–900ms at concurrency 64. For 70B on two A100 with tensor parallelism: 80–120 req/s, P99 latency 1.5–2.5s. AWQ or GPTQ quantization reduces memory consumption by 2x with quality loss within 1–3%.

Multi-Agent Systems

Agents are LLMs with access to tools: search, code execution, API calls, database interaction. Common patterns:

  • ReAct (Reason + Act): the model reasons → chooses a tool → observes the result → reasons again. LangChain and LlamaIndex implement it out of the box.
  • Multi-agent orchestration: multiple specialized agents with a coordinator on top. Example: coordinator → researcher (search + summarization) → coder (code generation and execution) → critic (verification). Tools: AutoGen (Microsoft), CrewAI, custom implementation on LangGraph.

In production, agent systems are non-deterministic. Essential: guardrails, step limits, logging of each step, human-in-the-loop for critical actions.

How We Work: Stages, Timeline, Deliverables

Stage Duration What You Get
Audit and data collection 1–2 weeks Eval dataset of 100+ examples, task formalization
Baseline (prompt + RAG) 1–2 weeks Working prototype, quality metrics
Fine-tuning (if needed) 2–4 weeks Trained model, LoRA weights, model card
Deployment and monitoring 1–2 weeks vLLM server, Grafana + Prometheus
Documentation and training 1 week API documentation, team training

What Is Included

We deliver:

  • Technical documentation (model card, configs, deployment instructions)
  • Access to infrastructure (code repository, trained weights)
  • 1 month of post-deployment support (consultations, bug fixes)
  • Customer team training (2–3 sessions on system operation)

Timeline: basic RAG prototype — 1–2 weeks. Fine-tuning with customer data — 3–6 weeks (including data preparation). Production system with monitoring and retraining — 2–4 months. Cost is calculated individually based on data volume, model complexity, and infrastructure requirements.

We guarantee the quality of the final model with performance benchmarks and ongoing monitoring. Our engineers have hands‑on experience with dozens of production LLM systems.

Want to evaluate your project? Leave a request — we will prepare a preliminary summary within 1–2 business days. Or get a consultation on choosing the approach: RAG, fine-tuning, or hybrid — we will tell you what works best for you. Contact us to discuss your LLM development needs. Schedule a free consultation today.