Building a Production RAG-Based Slackbot for Developer Support

vespa · Tech · 2024 · source Agentic: no · promotional bias: low · source-backed · extracted with prompt 0.5.4 (schema v2)

Generated from extraction.json — do not edit by hand. Every claim cites verbatim source evidence; stated means the quote directly asserts the claim, implied means it supports it indirectly.

Problem

Domain: Community developer support RAG Slackbot

Vespa needed to absorb a surge of community support questions by turning historical Slack conversations and documentation into a searchable, privacy-aware RAG support bot that could answer questions in Slack and learn from new conversations.

Constraints:

Architecture

Vespa interns built a Kotlin Slackbot that listens for mentions and messages, stores consented Slack messages in a Vespa application, groups retrieved messages by Slack thread, ranks them with hybrid semantic/BM25 ranking plus emoji-feedback signals, and sends selected context to OpenAI for summarization. The bot extends Vespa's existing documentation-search RAG backend and is deployed on GCP with Terraform managed through SpaceLift.

Diagram confidence: reconstructed (reconstructed from prose).

flowchart LR
  slack-events[Slack Events] --> slackbot[Slackbot]
  slackbot --> vespa-app[Vespa App]
  vespa-app --> slack-message-schema[Slack Message Schema]
  slack-message-schema --> text-embedding-field[Text Embedding Field]
  text-embedding-field --> hybrid-rank-profile[Hybrid Rank Profile]
  feedback-signal[Feedback Signal] --> hybrid-rank-profile
  hybrid-rank-profile --> documentation-search-backend[Documentation Search Backend]
  documentation-search-backend --> openai-summarizer[OpenAI Summarizer]
  openai-summarizer --> slackbot
  gcp-deployment[GCP Deployment] --> slackbot
  terraform[Terraform] --> gcp-deployment
  spacelift[SpaceLift] --> terraform
Drag to pan · scroll or use +/− to zoom · reconstructed from the source's described component topology

Components

Component Role Interacts with
Slackbot Kotlin Slack app that responds to mentions, captures messages, exposes slash commands, and handles reactions. Slack Events, Vespa App, OpenAI Summarizer
Slack Events AppMentionEvent and MessageEvent handlers that trigger answering and indexing workflows. Slackbot
Vespa App Search application storing Slack messages and retrieving ranked context. Slack Message Schema, Hybrid Rank Profile, Documentation Search Backend
Slack Message Schema Document schema with message_id, thread_id, text, and generated text embeddings. Vespa App, Text Embedding Field
Text Embedding Field Synthesized 384-dimensional tensor generated when messages are inserted or updated. Slack Message Schema, Hybrid Rank Profile
Hybrid Rank Profile Ranking profile that combines semantic similarity, scaled BM25, and reaction feedback. Vespa App, Feedback Signal, Documentation Search Backend
Feedback Signal Thumbs-up and thumbs-down reactions used to favor helpful historic messages. Hybrid Rank Profile, Slackbot
Documentation Search Backend Existing search.vespa.ai RAG backend extended with Slack schemas and searchers. Vespa App, OpenAI Summarizer
OpenAI Summarizer LLM summarization service that turns retrieved context into Slack answers. Slackbot, Documentation Search Backend
GCP Deployment Production hosting target managed with Terraform and SpaceLift. Slackbot, Terraform
Terraform Infrastructure-as-code configuration for deployment. GCP Deployment, SpaceLift
SpaceLift IaC management platform used to smooth Terraform state and integration. Terraform

Data flow

When a user mentions the bot, the AppMentionEvent handler queries the Vespa app for matching conversations and produces an answer. When users consent to indexing, the MessageEvent handler stores message text with message and thread IDs. Vespa embeds message text into a tensor field, ranks results with a hybrid rank profile, groups hits by thread, biases ranking with reaction feedback, and sends retrieved context to OpenAI for summarization.

4 supporting quotes
“Whenever a user mentions the bot with @BotName, the handler for AppMentionEvent will be called. It should query the Vespa app for a summary of the conversations that match the question.”article, stated
“Whenever a user writes a message, the MessageEvent handler will be called to feed that message to the Vespa app.”article, stated
“The messages are then grouped by their respective threads or conversations, using the maximum relevance score of the messages in each thread.”article, stated
“This Retrieval-Augmented Generation (RAG) system breaks down all documentation, sample apps, blog posts, and more into paragraphs, which are retrieved and sent to OpenAI for summarization.”article, stated

Why this architecture

Vespa reused its existing documentation-search RAG backend rather than building an isolated bot, because the community Slack corpus complemented official docs. Slack thread IDs preserved conversational context, hybrid ranking balanced semantic and lexical matching, emoji reactions gave lightweight relevance feedback, and consent/anonymization controls made production ingestion of community messages acceptable.

4 supporting quotes
“2. The bot bases its answer on previous conversations and Vespa’s Documentation Search 3. A /help command 4. Users must consent that they agree to the bot sending their questions to OpenAI 5. Users can allow indexing of their messages to improve the bot 6. The bot has to anonymize users”article, stated
“since our app should integrate with the existing search.vespa.ai system, we had to extend the already existing Documentation Search Backend”article, stated
“The thread_id field is used for grouping, which means that we take all hits from a search of Slack messages and create hit groups based on who has the same thread_id.”article, stated
“4. Users must consent that they agree to the bot sending their questions to OpenAI 5. Users can allow indexing of their messages to improve the bot 6. The bot has to anonymize users 7. Users can provide feedback with 👍 and 👎 reactions”article, stated

Models used: OpenAI · Vespa embedder · 384-dimensional text embeddings

Scale

Alternatives considered (roads not taken)

Build a standalone Slackbot search backend

Rejected because: The existing documentation search backend already provided RAG over docs, samples, and blog posts, so the Slackbot could extend it.

“Typically, we would have to create a new Vespa application that uses the RAGSearch component.”article, stated
“we had to extend the already existing Documentation Search Backend with our schemas and searchers.”article, stated

Run the bot in Socket Mode for production

Rejected because: Socket Mode was recommended for development, while HTTP server mode was recommended for deployment.

“Socket Mode: The bot connects to the Slack API and is ready to receive events generated from the servers. Socket Mode is the recommended mode during development.”article, stated
“HTTP Server: When running the bot as an HTTP server, you need to specify the IP of your Slackbot server inside the Slack API page.”article, stated

Use Terraform without additional IaC management

Rejected because: Terraform state and configuration were difficult for the interns, while SpaceLift smoothed state handling and integration.

“Terraform’s complexity and steep learning curve often felt like navigating the dark side of automation, making the integration process more complicated than we initially anticipated.”article, stated
“Its remote handling of Terraform state and smooth integration were game-changers. While Terraform alone felt tricky and complicated, SpaceLift made it a powerful and precise tool in our infrastructure toolkit.”article, stated

Patterns

rag-retrieval (knowledge-access)

The bot retrieves historic Slack conversations and documentation paragraphs before summarizing an answer with OpenAI.

“create an intelligent Slackbot that uses Vespa to answer questions based on past conversations and documentation.”article, stated
“The bot should feed every message (with users’ consent, of course) posted in the Slack channel into a Vespa app.”article, stated

hybrid-search (retrieval-ranking)

Vespa combines semantic text similarity and scaled BM25 in its hybrid2 rank profile.

“rank-profile hybrid2”article, stated
“In addition to semantic comparison, we use the classical information retrieval technique BM25 throughout the corpus”article, stated

data-quality-loop (feedback)

Thumbs-up and thumbs-down reactions alter ranking toward helpful historic responses.

“Users can provide feedback with 👍 and 👎 reactions”article, stated
“which will alter the ranking to favor those who provide good replies and ask good questions.”article, stated

privacy-preserving-processing (data-access)

The Slackbot requires consent for OpenAI sharing, lets users opt into indexing, and anonymizes users.

“Users can allow indexing of their messages to improve the bot”article, stated
“and user anonymization.”article, stated

retrieval-ranking (search)

Retrieved messages are ranked individually and then grouped by thread using the maximum relevance score.

“retrieve the best-ranked individual messages.”article, stated
“The messages are then grouped by their respective threads or conversations, using the maximum relevance score of the messages in each thread.”article, stated

Tradeoffs

Extend the existing documentation-search backend

Chose add Slack schemas and searchers to search.vespa.ai infrastructure over build a separate RAG application from scratch.

Rationale: The existing backend already summarized documentation with OpenAI, so Slack conversations became an additional knowledge layer.

“This integration allows the bot to potentially draw on both conversational history and official documentation when answering questions.”summary, stated
“we had to extend the already existing Documentation Search Backend with our schemas and searchers.”article, stated

Blend semantic and lexical ranking

Chose 0.7 semantic similarity and 0.3 scaled BM25 over pure vector search or pure BM25.

Rationale: The rank profile emphasizes conceptual similarity while preserving exact lexical relevance signals.

“expression: 0.7 * semantic_text + 0.3 * scaled_bm25_text”article, stated
“allowing us to compare this against the semantic results.”article, implied

Use HTTP server mode for deployment

Chose public endpoint HTTP server mode over Socket Mode.

Rationale: Socket Mode simplified development, while HTTP server mode is the recommended deployment mode.

“Socket Mode is the recommended mode during development.”article, stated
“HTTP Server is the recommended mode for deployment.”article, stated

Gotchas (what bit them)

Community Slack content cannot be indexed casually.

Root cause: The bot sends questions to OpenAI and stores user messages, creating privacy and consent obligations.

Resolution: Vespa added explicit consent, opt-in indexing, anonymization, and reaction-based feedback controls.

“Users must consent that they agree to the bot sending their questions to OpenAI”article, stated
“Our implementation is a bit more sophisticated and includes features like:”article, stated

Slack conversations need thread-aware retrieval.

Root cause: Individual Slack messages are fragments of conversations, so relevance at message level is not enough.

Resolution: The schema stores thread IDs and groups hits by thread.

“in slack a message is not a thread until it has a reply”article, stated
“we take all hits from a search of Slack messages and create hit groups based on who has the same thread_id.”article, stated

Infrastructure-as-code slowed production deployment.

Root cause: The interns had no prior Terraform experience and ran into configuration and state-management friction.

Resolution: They used SpaceLift, already used by Vespa, to manage Terraform state and integration.

“With no experience with Terraform, we climbed Mount Doom with Andúril in hand”article, stated
“Terraform’s initial configuration hurdles and intricate state management threatened to derail our project at multiple stages.”article, stated

Evaluation

Vespa evaluated the bot through deployment-readiness requirements, user feedback reactions, continuous indexing quality, and whether the bot could improve answers as more consented Slack interactions were processed.

Metrics: Docker pulls · Slack question volume · thumbs-up reactions · thumbs-down reactions · retrieval relevance score · rank score drop limit · indexed messages

3 supporting quotes
“Users can provide feedback with 👍 and 👎 reactions”article, stated
“rank-score-drop-limit: 0.0”article, stated
“The Slackbot will continuously index new messages to enhance its ability to provide users with more accurate and relevant feedback.”article, stated

Outcomes

The bot responded to a community growth moment where Docker pulls rose from 2M to 11M, and it used a 384-dimensional embedding field with a hybrid rank profile weighting semantic similarity 70% and BM25 30%.

3 supporting quotes
“We now have a working Slackbot powered by Vespa and OpenAI capable of learning from conversations.”article, stated
“Vespa.ai saw a dramatic rise in interest in early September 2023”article, stated
“We not only built a powerful Slackbot that learns and adapts”article, stated