Elastic
Jina AI
Modelle
API
keyboard_arrow_down
Reader
Konvertieren Sie jede URL in Markdown für besseres Grounding von LLMs.
Einbettungen
Multimodale, mehrsprachige Einbettungen.
Reranker
Reranker zur Maximierung der Suchrelevanz.
MCP
terminal
CLI
article
llms.txt
smart_toy
Agenten
data_object
Schema
menu_book
Dokumentation
Einloggen
login
Abrufen von Jira Support Tickets
Vorteile von Jina Embeddings und Reranker
Tech-Blog
April 10, 2024

Jira Tickets mit Jina Reranker und Haystack 2.0 abrufen

Lernen Sie, wie Sie Jina Reranker und Embeddings mit Haystack verwenden können, um Ihre eigene Jira-Ticket-Suchmaschine zu erstellen, Ihre Abläufe zu optimieren und nie wieder Zeit mit der Erstellung von Duplikaten zu verschwenden.
Graphic with "Reranker" and "Haystack by deepset" on a black background with teal decorative elements.
Francesco Kruk • 10 Minuten gelesen

Nach der Integration von Jina Embeddings in Deepset's Haystack 2.0 und der Veröffentlichung von Jina Reranker freuen wir uns bekannt zu geben, dass Jina Reranker nun auch über die Jina Haystack Erweiterung verfügbar ist.

Jina AI | Haystack
Use the latest Jina AI embedding models
HaystackAuthors deepset
Reranker API
Maximize the search relevancy and RAG accuracy at ease

Haystack ist ein End-to-End-Framework, das Sie in jedem Schritt des GenAI-Projektlebenszyklus begleitet. Ob Sie Dokumentensuche, Retrieval-Augmented Generation (RAG), Frage-Antwort oder Antwortgenerierung durchführen möchten, Haystack kann modernste Embedding-Modelle und LLMs in Pipelines orchestrieren, um End-to-End-NLP-Anwendungen zu erstellen und Ihren Anwendungsfall zu lösen.

Haystack | Haystack
Haystack, the composable open-source AI framework
Haystack

In diesem Beitrag zeigen wir, wie Sie damit Ihre eigene Jira-Ticket-Suchmaschine erstellen können, um Ihre Abläufe zu optimieren und nie wieder Zeit mit der Erstellung von Duplikat-Issues zu verschwenden.

Für dieses Tutorial benötigen Sie einen Jina Reranker API-Schlüssel. Sie können einen mit einem kostenlosen Testkontingent von einer Million Tokens von der Jina Reranker Website erstellen.

💡
Sie können in Colab mitarbeiten oder das Notebook herunterladen.

tagAbrufen von Jira Support Tickets

Jedes Team, das mit einem komplexen Projekt zu tun hat, kennt die Frustration, wenn sie ein Problem melden möchten, aber nicht wissen, ob bereits ein Ticket für dieses Problem existiert.

Im folgenden Tutorial zeigen wir Ihnen, wie Sie mit Jina Reranker und Haystack Pipelines selbst ein Tool erstellen können, das mögliche Duplikat-Tickets für ein neu zu erstellendes Ticket vorschlägt.

  • Durch die Eingabe eines Tickets, das gegen alle existierenden Tickets geprüft werden soll, wird die Pipeline zunächst alle verwandten Issues aus der Datenbank abrufen.
  • Dann werden das ursprüngliche Ticket (falls es bereits in der Datenbank existierte) und alle Child-Tickets (d.h. Tickets, deren Parent-ID dem ursprünglichen Ticket entspricht) aus der Liste entfernt.
  • Die endgültige Auswahl umfasst nun nur noch Issues, die möglicherweise das gleiche Thema wie das ursprüngliche Ticket behandeln, aber in der Datenbank nicht durch ihre IDs als solche gekennzeichnet wurden. Diese Tickets werden neu gerankt, um maximale Relevanz zu gewährleisten und Ihnen die Identifizierung von Duplikateinträgen in der Datenbank zu ermöglichen.

tagBeschaffung des Datensatzes

Für unsere Lösung haben wir alle "In-Progress" Jira Tickets für das Apache Zookeeper Projekt ausgewählt. Dies ist ein Open-Source-Service zur Koordinierung von Prozessen verteilter Anwendungen.

Wir haben die Tickets in einer JSON-Datei abgelegt, um sie besser handhaben zu können. Bitte laden Sie die Datei in Ihren Arbeitsbereich herunter.

tagEinrichten der Voraussetzungen

Um die Anforderungen zu installieren, führen Sie aus:

pip install --q chromadb haystack-ai jina-haystack chroma-haystack

Um den API-Schlüssel einzugeben, setzen Sie ihn als Umgebungsvariable:

import os
import getpass

os.environ["JINA_API_KEY"] = getpass.getpass()
💡
Wenn Sie diesen Code über das Notebook ausführen, wird getpass.getpass() Sie auffordern, den API-Schlüssel unter dem entsprechenden Codeblock einzugeben. Sie können den Schlüssel dort eingeben und Enter drücken, um das Tutorial fortzusetzen. Wenn Sie möchten, können Sie getpass.getpass() auch durch den API-Schlüssel selbst ersetzen.

tagAufbau der Indexierungs-Pipeline

Die Indexierungs-Pipeline wird die Tickets vorverarbeiten, in Vektoren umwandeln und speichern. Wir verwenden den Chroma DocumentStore als unsere Vektordatenbank zum Speichern der Vektoreinbettungen über die Chroma Document Store Haystack Integration.

from haystack_integrations.document_stores.chroma import ChromaDocumentStore

document_store = ChromaDocumentStore()

Wir beginnen mit der Definition unseres benutzerdefinierten Datenvorverarbeiters, der nur relevante Dokumentenfelder berücksichtigt und alle leeren Einträge löscht:

import json
from typing import List
from haystack import Document, component

relevant_keys = ['Summary', 'Issue key', 'Issue id', 'Parent id', 'Issue type', 'Status', 'Project lead', 'Priority', 'Assignee', 'Reporter', 'Creator', 'Created', 'Updated', 'Last Viewed', 'Due Date', 'Labels',
                 'Description', 'Comment', 'Comment__1', 'Comment__2', 'Comment__3', 'Comment__4', 'Comment__5', 'Comment__6', 'Comment__7', 'Comment__8', 'Comment__9', 'Comment__10', 'Comment__11', 'Comment__12',
                 'Comment__13', 'Comment__14', 'Comment__15']

@component
class RemoveKeys:
    @component.output_types(documents=List[Document])
    def run(self, file_name: str):
        with open(file_name, 'r') as file:
            tickets = json.load(file)
        cleaned_tickets = []
        for t in tickets:
            t = {k: v for k, v in t.items() if k in relevant_keys and v}
            cleaned_tickets.append(t)
        return {'documents': cleaned_tickets}

Dann müssen wir einen benutzerdefinierten JSON-Konverter erstellen, um die Tickets in Document-Objekte umzuwandeln, die Haystack verstehen kann:

@component
class JsonConverter:
    @component.output_types(documents=List[Document])
    def run(self, tickets: List[Document]):
        tickets_documents = []
        for t in tickets:
            if 'Parent id' in t:
                t = Document(content=json.dumps(t), meta={'Issue key': t['Issue key'], 'Issue id': t['Issue id'], 'Parent id': t['Parent id']})
            else:
                t = Document(content=json.dumps(t), meta={'Issue key': t['Issue key'], 'Issue id': t['Issue id'], 'Parent id': ''})
            tickets_documents.append(t)
        return {'documents': tickets_documents}

Schließlich betten wir die Documents ein und schreiben diese Einbettungen in den ChromaDocumentStore:

from haystack import Pipeline

from haystack.components.writers import DocumentWriter
from haystack_integrations.components.retrievers.chroma import ChromaEmbeddingRetriever
from haystack.document_stores.types import DuplicatePolicy

from haystack_integrations.components.embedders.jina import JinaDocumentEmbedder

retriever = ChromaEmbeddingRetriever(document_store=document_store)
retriever_reranker = ChromaEmbeddingRetriever(document_store=document_store)

indexing_pipeline = Pipeline()
indexing_pipeline.add_component('cleaner', RemoveKeys())
indexing_pipeline.add_component('converter', JsonConverter())
indexing_pipeline.add_component('embedder', JinaDocumentEmbedder(model='jina-embeddings-v2-base-en'))
indexing_pipeline.add_component('writer', DocumentWriter(document_store=document_store, policy=DuplicatePolicy.SKIP))

indexing_pipeline.connect('cleaner', 'converter')
indexing_pipeline.connect('converter', 'embedder')
indexing_pipeline.connect('embedder', 'writer')

indexing_pipeline.run({'cleaner': {'file_name': 'tickets.json'}})

Dies sollte einen Fortschrittsbalken erzeugen und eine kurze JSON-Datei mit Informationen über das, was gespeichert wurde, ausgeben:

Calculating embeddings: 100%|██████████| 1/1 [00:01<00:00,  1.21s/it]
{'embedder': {'meta': {'model': 'jina-embeddings-v2-base-en',
   'usage': {'total_tokens': 20067, 'prompt_tokens': 20067}}},
 'writer': {'documents_written': 31}}

tagQuery Pipeline erstellen

Lassen Sie uns eine Query Pipeline erstellen, damit wir Tickets vergleichen können. In Haystack 2.0 sind Retriever eng mit DocumentStores verbunden. Wenn wir den Document Store in den zuvor initialisierten Retriever übergeben, kann diese Pipeline auf die von uns generierten Dokumente zugreifen und sie an den Reranker weitergeben. Der Reranker vergleicht diese Dokumente dann direkt mit der Frage und ordnet sie nach Relevanz.

Zunächst definieren wir den benutzerdefinierten Cleaner, um Tickets zu entfernen, die entweder die gleiche Issue ID oder Parent ID wie das als Query übergebene Issue enthalten:

from typing import Optional

@component
class RemoveRelated:
    @component.output_types(documents=List[Document])
    def run(self, tickets: List[Document], query_id: Optional[str]):
        retrieved_tickets = []
        for t in tickets:
            if not t.meta['Issue id'] == query_id and not t.meta['Parent id'] == query_id:
                retrieved_tickets.append(t)
        return {'documents': retrieved_tickets}

Dann embedden wir die Query, rufen relevante Dokumente ab, bereinigen die Auswahl und führen schließlich ein Reranking durch:

from haystack_integrations.components.embedders.jina import JinaTextEmbedder
from haystack_integrations.components.rankers.jina import JinaRanker

query_pipeline_reranker = Pipeline()
query_pipeline_reranker.add_component('query_embedder_reranker', JinaTextEmbedder(model='jina-embeddings-v2-base-en'))
query_pipeline_reranker.add_component('query_retriever_reranker', retriever_reranker)
query_pipeline_reranker.add_component('query_cleaner_reranker', RemoveRelated())
query_pipeline_reranker.add_component('query_ranker_reranker', JinaRanker())

query_pipeline_reranker.connect('query_embedder_reranker.embedding', 'query_retriever_reranker.query_embedding')
query_pipeline_reranker.connect('query_retriever_reranker', 'query_cleaner_reranker')
query_pipeline_reranker.connect('query_cleaner_reranker', 'query_ranker_reranker')
Flussdiagramm, das einen Query-Verarbeitungs-Workflow mit Funktionen wie 'text', 'query_embedder_reranker', 'meta' skizziert.

Um den Unterschied durch den Reranker zu verdeutlichen, haben wir die gleiche Pipeline ohne den finalen Reranking-Schritt analysiert (der entsprechende Code wurde in diesem Beitrag der Übersichtlichkeit halber weggelassen, ist aber im Notebook zu finden):

Flussdiagramm, das einen Textsuche-Prozess mit 'query_embedding', 'query_retriever' und 'query_cleaner' Komponenten detailliert darstellt.

Um die Ergebnisse dieser beiden Pipelines zu vergleichen, definieren wir nun unsere Query in Form eines existierenden Tickets, hier "ZOOKEEPER-3282":

query_ticket_key = 'ZOOKEEPER-3282'

with open('tickets.json', 'r') as file:
    tickets = json.load(file)

for ticket in tickets:
    if ticket['Issue key'] == query_ticket_key:
        query = str(ticket)
        query_ticket_id = ticket['Issue id']

Es geht um "eine große Überarbeitung der Dokumentation" [sic]. Sie werden sehen, dass Jina Reranker trotz des Rechtschreibfehlers ähnliche Tickets korrekt abruft.

{
    "Summary": "a big refactor for the documetations"
    "Issue key": "ZOOKEEPER-3282"
    "Issue id:: 13216608
    "Parent id": ""
    "Issue Type": "Task"
    "Status": "In Progress"
    "Project lead": "phunt"
    "Priority": "Major"
    "Assignee": "maoling"
    "Reporter": "maoling"
    "Creator": "maoling"
    "Created": "19/Feb/19 11:50"
    "Updated": "04/Aug/19 12:48"
    "Last Viewed": "12/Mar/24 11:56"
    "Description": "Hi guys: I'am working on doing a big refactor for the documetations.it aims to - 1.make a better reading experiences and help users know more about zookeeper quickly,as good as other projects' doc(e.g redis,hbase). - 2.have less changes to diff with the original docs as far as possible. - 3.solve the problem when we have some new features or improvements,but cannot find a good place to doc it.   The new catalog may looks kile this: * is new one added. ** is the one to keep unchanged as far as possible. *** is the one modified. -------------------------------------------------------------- |---Overview    |---Welcome ** [1.1]    |---Overview ** [1.2]    |---Getting Started ** [1.3]    |---Release Notes ** [1.4] |---Developer    |---API *** [2.1]    |---Programmer's Guide ** [2.2]    |---Recipes *** [2.3]    |---Clients * [2.4]    |---Use Cases * [2.5] |---Admin & Ops    |---Administrator's Guide ** [3.1]    |---Quota Guide ** [3.2]    |---JMX ** [3.3]    |---Observers Guide ** [3.4]    |---Dynamic Reconfiguration ** [3.5]    |---Zookeeper CLI * [3.6]    |---Shell * [3.7]    |---Configuration flags * [3.8]    |---Troubleshooting & Tuning  * [3.9] |---Contributor Guidelines    |---General Guidelines * [4.1]    |---ZooKeeper Internals ** [4.2] |---Miscellaneous    |---Wiki ** [5.1]    |---Mailing Lists ** [5.2] -------------------------------------------------------------- The Roadmap is: 1.(I pick up it : D)  1.1 write API[2.1], which includes the:    1.1.1  original API Docs which is a Auto-generated java doc,just give a link.    1.1.2. Restful-api (the apis under the /zookeeper-contrib-rest/src/main/java/org/apache/zookeeper/server/jersey/resources)  1.2 write Clients[2.4], which includes the:      1.2.1 C client      1.2.2 zk-python, kazoo      1.2.3 Curator etc.......      look at an example from: https://redis.io/clients # write Recipes[2.3], which includes the:  - integrate "Java Example" and "Barrier and Queue Tutorial"(Since some bugs in the examples and they are obsolete,we may delete something) into it.  - suggest users to use the recipes implements of Curator and link to the Curator's recipes doc.   # write Zookeeper CLI[3.6], which includes the:  - about how to use the zk command line interface [./zkCli.sh]    e.g ls /; get ; rmr;create -e -p etc.......  - look at an example from redis: https://redis.io/topics/rediscli   # write shell[3.7], which includes the:   - list all usages of the shells under the zookeeper/bin. (e.g zkTxnLogToolkit.sh,zkCleanup.sh)   # write Configuration flags[3.8], which includes the:   - list all usages of configurations properties(e.g zookeeper.snapCount):   - move the original Advanced Configuration part of zookeeperAdmin.md into it.     look at an example from:https://coreos.com/etcd/docs/latest/op-guide/configuration.html    # write Troubleshooting & Tuning[3.9], which includes the:   - move the original "Gotchas: Common Problems and Troubleshooting" part of Administrator's Guide.md into it.   - move the original "FAQ" into into it.   - add some new contents (e.g https://www.yumpu.com/en/document/read/29574266/building-an-impenetrable-zookeeper-pdf-github).   look at an example from:https://redis.io/topics/problems                             https://coreos.com/etcd/docs/latest/tuning.html   # write General Guidelines[4.1], which includes the:  - move the original "Logging" part of ZooKeeper Internals into it as the logger specification.  - write specifications about code, git commit messages,github PR  etc ...    look at an example from:    http://hbase.apache.org/book.html#hbase.commit.msg.format   # write Use Cases[2.5], which includes the:  - just move the context from: https://cwiki.apache.org/confluence/display/ZOOKEEPER/PoweredBy into it.  - add some new contents.(e.g Apache Projects:Spark;Companies:twitter,fb)   -------------------------------------------------------------- BTW: - Any insights or suggestions are very welcomed.After the dicussions,I will create a series of tickets(An umbrella) - Since these works can be done parallelly, if you are interested in them, please don't hesitate,just assign to yourself, pick it up. (Notice: give me a ping to avoid the duplicated work)."
}

Schließlich führen wir die Query Pipeline aus. In diesem Fall ruft sie 20 Tickets ab, eliminiert ID-verwandte Einträge, ordnet sie neu und gibt die finale Auswahl der 10 relevantesten Issues aus.

Vor dem Reranking-Schritt enthält die Ausgabe 17 Tickets:

Rank Issue ID Issue Key Summary
1 13191544 ZOOKEEPER-3170 Umbrella for eliminating ZooKeeper flaky tests
2 13400622 ZOOKEEPER-4375 Quota cannot limit the specify value when multiply clients create/set znodes
3 13249579 ZOOKEEPER-3499 [admin server way] Add a complete backup mechanism for zookeeper internal
4 13295073 ZOOKEEPER-3775 Wrong message in IOException
5 13268474 ZOOKEEPER-3617 ZK digest ACL permissions gets overridden
6 13296971 ZOOKEEPER-3787 Apply modernizer-maven-plugin to build
7 13265507 ZOOKEEPER-3600 support the complete linearizable read and multiply read consistency level
8 13222060 ZOOKEEPER-3318 [CLI way]Add a complete backup mechanism for zookeeper internal
9 13262989 ZOOKEEPER-3587 Add a documentation about docker
10 13262130 ZOOKEEPER-3578 Add a new CLI: multi
11 13262828 ZOOKEEPER-3585 Add a documentation about RequestProcessors
12 13262494 ZOOKEEPER-3583 Add new apis to get node type and ttl time info
13 12998876 ZOOKEEPER-2519 zh->state should not be 0 while handle is active
14 13536435 ZOOKEEPER-4696 Update for Zookeeper latest version
15 13297249 ZOOKEEPER-3789 fix the build warnings about @see,@link,@return found by IDEA
16 12728973 ZOOKEEPER-1983 Append to zookeeper.out (not overwrite) to support logrotation
17 12478629 ZOOKEEPER-915 Errors that happen during sync() processing at the leader do not get propagated back to the client.

Nach Einbindung des Rerankers führen wir nun die Query-Pipeline aus:

result = query_pipeline_reranker.run(data={'query_embedder_reranker':{'text': query},
                                  'query_retriever_reranker': {'top_k': 20},
                                  'query_cleaner_reranker': {'query_id': query_ticket_id},
                                  'query_ranker_reranker': {'query': query, 'top_k': 10}
                                  }
                            )

for idx, res in enumerate(result['query_ranker_reranker']['documents']):
    print('Doc {}:'.format(idx + 1), res)

Die finale Ausgabe sind die 10 relevantesten Tickets:

Rank Issue ID Issue Key Summary
1 13262989 ZOOKEEPER-3587 Add a documentation about docker
2 13265507 ZOOKEEPER-3600 support the complete linearizable read and multiply read consistency level
3 13249579 ZOOKEEPER-3499 [admin server way] Add a complete backup mechanism for zookeeper internal
4 12478629 ZOOKEEPER-915 Errors that happen during sync() processing at the leader do not get propagated back to the client.
5 13262828 ZOOKEEPER-3585 Add a documentation about RequestProcessors
6 13297249 ZOOKEEPER-3789 fix the build warnings about @see,@link,@return found by IDEA
7 12998876 ZOOKEEPER-2519 zh->state should not be 0 while handle is active
8 13536435 ZOOKEEPER-4696 Update for Zookeeper latest version
9 12728973 ZOOKEEPER-1983 Append to zookeeper.out (not overwrite) to support logrotation
10 13222060 ZOOKEEPER-3318 [CLI way]Add a complete backup mechanism for zookeeper internal

tagVorteile von Jina Embeddings und Reranker

Zusammenfassend haben wir in diesem Tutorial ein Tool zur Identifizierung von duplizierten Tickets entwickelt, das auf Jina Embeddings, Jina Reranker und Haystack 2.0 basiert. Die obigen Ergebnisse zeigen deutlich die Notwendigkeit sowohl von Jina Embeddings für die Auffindung relevanter Dokumente durch Vektorsuche als auch von Jina Reranker für die endgültige Ermittlung der relevantesten Inhalte.

Wenn wir zum Beispiel die beiden Issues betrachten, die sich auf das Hinzufügen von Dokumentation beziehen, also "ZOOKEEPER-3585" und "ZOOKEEPER-3587", sehen wir, dass sie nach dem Retrieval-Schritt zunächst korrekt auf den Positionen 11 bzw. 9 enthalten sind. Nach dem Reranking der Dokumente befinden sie sich nun beide unter den Top 5 der relevantesten Dokumente auf den Positionen 5 bzw. 1, was eine deutliche Verbesserung darstellt.

Durch die Integration beider Modelle in Haystacks Pipelines ist das gesamte Tool einsatzbereit. Diese Kombination macht die Jina Haystack-Erweiterung zur perfekten Lösung für Ihre Anwendung.

Kategorien:
Tech-Blog
rss_feed

Weiterlesen
März 11, 2026 • 7 Minuten gelesen
Bootstrapping Audio Embeddings from Multimodal LLMs
Han Xiao
Abstract illustration of a sound wave or heartbeat, formed by blue, orange, and gray dots on a white background.
März 06, 2026 • 6 Minuten gelesen
Identifying Embedding Models from Raw Numerical Values
Han Xiao
Fingerprint illustration made from numbers, showcasing digital and high-tech design on a light background.
September 09, 2025 • 11 Minuten gelesen
Multimodal Embeddings in Llama.cpp and GGUF
Andrei Ungureanu
Alex C-G
Cartoon llama in the center of a white background, emitting laser-like beams from its eyes. The illustration creates a playfu
Aktuelle Sprache / Design
Search Foundation
Reader
Einbettungen
Reranker
Jina API-Schlüssel abrufen
Ratenbegrenzung
Über uns
Neuigkeiten
Jina-Logo herunterladen
open_in_new
Elastic-Logo herunterladen
open_in_new
API-Status
Elastic © 2026.SicherheitAGBPrivatsphäreCookie-EinstellungenMeine persönlichen Daten nicht verkaufen oder weitergeben
Diese Website und alle zugehörigen Inhalte, Software, Produkte und Dienstleistungen sind ausschließlich für den professionellen Gebrauch bestimmt. Eine Nutzung durch Endverbraucher ist weder vorgesehen noch empfohlen.