У меня есть документ с тремя атрибутами: тегами, местоположением и текстом.
В настоящее время я индексирую их все, используя LangChain/pgvector/embeddings.
У меня есть удовлетворительные результаты, но я хочу знать, есть ли лучший способ, поскольку я хочу найти один или несколько документов с определенным тегом и местоположением, но текст может сильно различаться, но иметь одно и то же значение. По этой причине я подумал об использовании баз данных встраивания/векторов.
Будет ли также использоваться RAG (Поисковая дополненная генерация), чтобы «научить» LLM некоторым общим сокращениям, которые он не знает?
import pandas as pd
from langchain_core.documents import Document
from langchain_postgres import PGVector
from langchain_postgres.vectorstores import PGVector
from langchain_openai.embeddings import OpenAIEmbeddings
connection = "postgresql+psycopg://langchain:langchain@localhost:5432/langchain"
embeddings = OpenAIEmbeddings(model = "text-embedding-3-small")
collection_name = "notas_v0"
vectorstore = PGVector(
embeddings=embeddings,
collection_name=collection_name,
connection=connection,
use_jsonb=True,
)
# START INDEX
# df = pd.read_csv("notes.csv")
# df = df.dropna() # .head(10000)
# df["tags"] = df["tags"].apply(
# lambda x: [tag.strip() for tag in x.split(",") if tag.strip()]
# )
# long_texts = df["Texto Longo"].tolist()
# wc = df["Centro Trabalho Responsável"].tolist()
# notes = df["Nota"].tolist()
# tags = df["tags"].tolist()
# documents = list(
# map(
# lambda x: Document(
# page_content=x[0], metadata = {"wc": x[1], "note": x[2], "tags": x[3]}
# ),
# zip(long_texts, wc, notes, tags),
# )
# )
# print(
# [
# vectorstore.add_documents(documents=documents[i : i + 100])
# for i in range(0, len(documents), 100)
# ]
# )
# print("Done.")
### END INDEX
### BEGIN QUERY
result = vectorstore.similarity_search_with_relevance_scores(
"EVTD202301222707",
filter = {"note": {"$in": ["15310116"]}, "tags": {"$in": ["abcd", "xyz"]}},
k=10, # Limit of results
)
### END QUERY





Здесь есть одно главное неизвестное: каково приблизительное или среднее количество токенов в «текстовой» части вашего ввода.
Сценарий 1: У вас не очень длинный ввод (скажем, где-то 512 токенов)
В этом случае, чтобы получить лучшие результаты, вы можете обучить свою собственную «модель внедрения», пожалуйста, посмотрите мой ответ здесь, в котором есть некоторая информация.
Как только вы получите правильную модель внедрения, вы индексируете соответствующие текстовые векторы в своем конвейере RAG. Есть еще несколько шагов, применимых ко всем сценариям, поэтому я добавлю их в конце.
Сценарий 2: у вас очень длинный ввод для каждого документа, скажем, каждый «текстовый» ввод огромен (скажем, ~ 8000 токенов, хотя это число может быть любым). В этом случае вы можете использовать символьный поиск вместо векторного поиска. Символический поиск, потому что на любом языке для описания чего-то, что действительно означает одно и то же или имеет схожий контекст, наверняка будет много слов, пересекающихся в исходном и целевом тексте. Очень редко можно найти 10-страничный текст по одной и той же теме, который не пересекается во многих работах.
Таким образом, вы можете использовать здесь символьный поиск, объединить его с векторными валидаторами и использовать сервис LLM, который позволяет использовать длинные контекстные подсказки. Итак, вы находите несколько хороших кандидатов с помощью символического поиска, а затем передаете их в длинном контексте LLM для оставшихся частей.
Шаги, применимые ко всем сценариям:
Ваш объект json также должен содержать «тег», «местоположение», а также «текст» и «вектор».
{"text":"some text", "text_embedding":[...], #not applicable in symbolic search "location":"loc", "tags":[] }
Таким образом, когда вы получаете совпадения в результате векторного или символьного поиска; вы также сможете фильтровать или сортировать на основе других свойств, таких как теги и местоположение.
Пожалуйста, прокомментируйте, если у вас есть больше сомнений!
Да, это тоже будет случай RAG. Вероятно, вам придется использовать какой-либо алгоритм или инструмент поиска, чтобы найти наиболее релевантные документы по ключевому слову. Затем реализуйте или используйте существующий алгоритм для определения веса оценки, чтобы объединить семантический поиск с поиском по ключевым словам. Это сложно, но можно добиться лучших результатов.