New to Kestra?
Use blueprints to kickstart your first workflows.
Triage GitHub issues with OpenAI embeddings and Qdrant vector search to detect duplicates, auto-label categories, and notify Slack.
Diagram unavailable
We could not build the topology for this blueprint. The flow itself is valid, use the YAML on the left to run it.
Automate GitHub issue triage, semantic duplicate detection, and category labeling using OpenAI, Qdrant vector search, and Kestra orchestration. In active open-source and enterprise repositories, maintainers frequently spend hours manually reading incoming issues, flagging duplicates, and assigning taxonomy labels. Traditional keyword searches often fail because users describe identical problems using entirely different terminology.
This blueprint reacts to newly opened GitHub issues via a webhook, converts the title and body into dense vector embeddings with OpenAI, and queries a Qdrant collection for existing semantically similar issues. When candidate duplicates cross a configurable cosine similarity threshold, the workflow tags the issue with a possible-duplicate label, posts a polite comment linking to prior matching issues with confidence scores, and alerts the maintainer Slack channel. If no duplicates are found, the flow runs an OpenAI classification model to auto-label the issue with standard taxonomy categories (e.g., bug, feature, question, documentation) and indexes the new issue into Qdrant for future matching.
github_issue_webhook receives GitHub issue event webhooks authenticated by a shared secret key configured in the webhook URL.gate_issue_event (io.kestra.plugin.core.flow.If) gates execution to only process opened actions authored by human users (user.type != 'Bot') with non-empty titles. All other actions and bot activities are safely logged and skipped.create_collection_if_missing (io.kestra.plugin.qdrant.CreateCollection) idempotently ensures the target Qdrant collection exists with 1536-dimensional cosine vector configuration.create_embedding (io.kestra.plugin.core.http.Request) invokes the OpenAI Embeddings API (text-embedding-3-small) to convert the issue title and body into a high-dimensional vector.search_similar_issues (io.kestra.plugin.qdrant.Query) searches Qdrant for nearest neighbor vectors above similarity_threshold (default 0.82) using fetchType: FETCH.filter_matches (io.kestra.plugin.core.output.OutputValues) excludes the current issue number from the search candidates to prevent self-matching.route_triage_decision (io.kestra.plugin.core.flow.Switch) inspects candidate counts:add_duplicate_label applies the possible-duplicate label, comment_duplicate_matches posts a markdown comment listing matching issue URLs and similarity scores, and notify_slack_duplicate posts an alert to the triage Slack channel.classify_issue (io.kestra.plugin.openai.ChatCompletion) classifies the issue into standard categories using structured JSON output, validates the label against allowed_labels, and applies the validated label to the issue via apply_category_label.upsert_issue_vector (io.kestra.plugin.qdrant.Upsert) indexes the issue number, embedding vector, title, and URL into Qdrant so subsequent incoming issues can match against it. Setting the point ID to the issue number guarantees idempotent upserts on redelivered webhooks.Building duplicate detection with custom webhooks or ad hoc scripts introduces infrastructure maintenance, unhandled rate limits, lost webhook retries, and brittle vector store connections.
Orchestrating this with Kestra provides an event-driven webhook endpoint, declarative retries across GitHub, OpenAI, and Qdrant APIs, conditional routing with Switch and If tasks, and end-to-end execution lineage without managing dedicated server daemons.
text-embedding-3-small and gpt-4o-mini.GITHUB_WEBHOOK_KEY: Secret key securing the Kestra webhook trigger endpoint against unauthorized HTTP calls.GITHUB_TOKEN: GitHub Personal Access Token (classic or fine-grained) with issues:write permissions.OPENAI_API_KEY: OpenAI API key used for generating vector embeddings and structured chat classification.QDRANT_HOST: Hostname or IP address of the Qdrant gRPC service endpoint (default port 6334).QDRANT_API_KEY: API key used to authenticate with the Qdrant vector database.SLACK_WEBHOOK_URL: Slack Incoming Webhook URL used to dispatch duplicate detection notifications.GITHUB_WEBHOOK_KEY, GITHUB_TOKEN, OPENAI_API_KEY, QDRANT_HOST, QDRANT_API_KEY, and SLACK_WEBHOOK_URL.github_issue_webhook trigger (e.g., https://<kestra-host>/api/v1/executions/webhook/company.team/github-issue-triage-and-duplicate-detection-qdrant/<your-key>).application/json and select the Issues event. Note that GitHub signs payloads with HMAC while Kestra authenticates incoming calls via the secret webhook key embedded in the URL path.pull_request events to cross-reference incoming PRs against open bug issues.