{"slug": "how-i-built-a-self-improving-ai-reply-system-for-e-commerce-sellers-with", "title": "How I Built a Self-Improving AI Reply System for E-commerce Sellers with pgvector", "summary": "A developer building Netaliz, a profit analytics tool for Trendyol marketplace sellers, added an AI module that drafts customer-question replies and improves itself by storing every seller-approved answer as a pgvector embedding in Postgres, then retrieving the three closest approved answers per store as few-shot examples in the prompt. The system keeps human review as the default, with auto-send opt-in, so each approval becomes a new training example without fine-tuning.", "body_md": "Marketplace sellers in Turkey get a constant stream of customer questions: \"Is this table waterproof?\", \"Will it fit a small balcony?\", \"Why are the reviews so bad?\". Every unanswered question is a lost sale, but writing thoughtful replies all day doesn't scale.\n\nWhile building [Netaliz](https://netaliz.com), a profit analytics tool for Trendyol sellers, I added an AI module that drafts replies to these questions. The interesting part isn't calling an LLM. It's making the system **get better every time the seller approves an answer**.\n\nHere's how it works.\n\nMy first version was simple: send the product info and the question to an LLM, get an answer back. It worked, but:\n\nSellers were editing almost every draft. That's not automation, that's extra work.\n\nThe final system has four layers that get assembled into the prompt:\n\nLayer 4 is what makes it self-improving.\n\nEvery time a seller approves a draft (or edits and sends it), we store the question, the final answer and an embedding of the question:\n\n```\nCREATE EXTENSION IF NOT EXISTS vector;\n\nCREATE TABLE approved_answers (\n  id          BIGSERIAL PRIMARY KEY,\n  store_id    BIGINT NOT NULL,\n  question    TEXT NOT NULL,\n  answer      TEXT NOT NULL,\n  embedding   vector(1536),\n  created_at  TIMESTAMPTZ DEFAULT now()\n);\n\nCREATE INDEX ON approved_answers\n  USING hnsw (embedding vector_cosine_ops);\n```\n\nKeeping this in Postgres instead of a separate vector database was a deliberate choice. The data already lives there, it's scoped per store with a simple `WHERE`, and it's one less service to run.\n\nWhen a new question comes in, we embed it and pull the closest approved answers from the same store:\n\n```\nSELECT question, answer\nFROM approved_answers\nWHERE store_id = $1\nORDER BY embedding <=> $2\nLIMIT 3;\n```\n\nThose examples go into the prompt as few-shot demonstrations. If a seller always answers sizing questions in a particular way, the model sees that pattern and follows it, without any fine-tuning.\n\nWe also give the model a fixed three-step structure, which made answers noticeably more persuasive:\n\nA simplified version of the prompt assembly:\n\n```\nfunction buildPrompt(ctx: ReplyContext): string {\n  return [\n    `You are a customer support writer for a marketplace seller.`,\n    `Tone: ${ctx.brandVoice}. Never use: ${ctx.bannedWords.join(\", \")}.`,\n    `Rules:\\n${ctx.templateRules.map(r => `- ${r}`).join(\"\\n\")}`,\n    `Product facts:\\n${JSON.stringify(ctx.product)}`,\n    `Structure: acknowledge the concern, give one concrete argument, close with trust.`,\n    `Examples of approved answers:\\n${ctx.examples\n      .map(e => `Q: ${e.question}\\nA: ${e.answer}`)\n      .join(\"\\n\\n\")}`,\n    `Customer question: ${ctx.question}`,\n  ].join(\"\\n\\n\");\n}\n```\n\nBy default, nothing is sent automatically. The AI drafts, the seller reviews and clicks send. Auto-send is opt-in, and even then the brand voice, banned words and template rules still apply.\n\nThis turned out to matter for two reasons: sellers trust the system more, and every human approval becomes a new training example. The review step *is* the learning loop.\n\nIf you're curious about the product side, Netaliz has a demo store with sample data, no signup needed: [netaliz.com/demo](https://netaliz.com/demo).\n\nI'd love to hear how others are handling per-user style in LLM apps. Are you using retrieval, fine-tuning, or something else?", "url": "https://wpnews.pro/news/how-i-built-a-self-improving-ai-reply-system-for-e-commerce-sellers-with", "canonical_source": "https://dev.to/netaliz/how-i-built-a-self-improving-ai-reply-system-for-e-commerce-sellers-with-pgvector-5ae4", "published_at": "2026-10-05 11:38:44+00:00", "updated_at": "2026-10-05 11:49:00.868420+00:00", "lang": "en", "topics": ["ai-products", "large-language-models", "ai-tools", "mlops", "generative-ai"], "entities": ["Netaliz", "Trendyol", "Postgres", "pgvector"], "also_reported_by": [], "alternates": {"html": "https://wpnews.pro/news/how-i-built-a-self-improving-ai-reply-system-for-e-commerce-sellers-with", "markdown": "https://wpnews.pro/news/how-i-built-a-self-improving-ai-reply-system-for-e-commerce-sellers-with.md", "text": "https://wpnews.pro/news/how-i-built-a-self-improving-ai-reply-system-for-e-commerce-sellers-with.txt", "jsonld": "https://wpnews.pro/news/how-i-built-a-self-improving-ai-reply-system-for-e-commerce-sellers-with.jsonld"}}