This content originally appeared on HackerNoon and was authored by Dmitrii Galkin
Причина по которая я захотел поделиться своим опытом простая. В каждой средней компании есть много микросервисов и различных АПИ. Команды пилять микросервисы. Каждая команда взаимодействует друг с другом. Спасибо большое Фастапи и ее создателю за то что сделали прекрасынй фрейморк на основе пайдентика генерирующий все необходимые спеки. Но проблема все еще актуальна, некоторым стартапам не хватает времени писать нормальную документацию - дак может и не надо, если часть кода уже генерируется.
\
- Что я использовал
- Стримлит
- Хрома
- Лангчен
- Оламма
\ Я решил попробовать провести эксперимент и соединить Swagger и с OpenAI и посмотреть что из этого получиться. Это статья туториал / гайд для тех кто хочет узнать чем все кончилось и как я это сделал на основе RAG with ChromaDB and Langchain.
\ Цель
Fast to find. Information and ask about something “How to create item with API?“
\ Все шаги в RAG делятся на 3 части
- Взять информацию, разбить ее на чанки и положить в векторное хранилище.
- Достать во время запроса от клиента и отправить в модель
- Сравнить результат и ожидание
\
Пишем сплиттер
для того чтобы написать сплиттер обычно лангчейн предоставляет много заготовленных штук, но так как в нашем случае спецификация это список запросов которые связаны с моделями лучше всего взять и разбить это на просто запросы. Для этого я написал простой снипет. Это максимально простая функция кторая разделяет всю полученную спеку на простые части. И добавляет связанные модели к патчу.
def get_openapi_spec_paths(specification: dict) -> dict:
paths = []
for p in specification["paths"]:
for m in specification["paths"][p]:
path = specification["paths"][p][m]
path["method"] = m
path["path"] = p
paths.append(path)
return paths
Загрузка документов
После того как мы разделили на чанки нам нужно их заэнкодировать в векторное предстовление и загрузить в хрома дб. В дальнейшем перед тем как делать запрос в чат гпт мы сделаем векторный поиск по эмбедингам чтобы достать релевантные документы.
\
import json
from langchain.docstore.document import Document
from langchain_openai import OpenAIEmbeddings
from langchain_chroma import Chroma
specification = get_openapi_spec(url)
paths = get_openapi_spec_paths(specification)
dumped_paths = dump_openapi_spec_to_chroma_docs(paths)
# Dump documents to Chroma documents
for p in paths:
dumped_paths.append(
Document(page_content=json.dumps(p), metadata={"source": "local"})
)
# Init embeddings model
embeddings = OpenAIEmbeddings(
model="text-embedding-ada-002"
)
# Upload to database
Chroma.from_documents(
documents=dumped_paths,
embedding=embeddings,
persist_directory="data",
collection_name="spec",
)
\ В этом примере, мы сохраняем данные локально в директорию ‘data’, но Chroma может работать как и в короткой памяти так и как отдельный инстанс.
Пишем ретривер и чейн
Мы готовы к тому чтобы сделать первый запрос. Я загрузил пример простого API про собачек, который написал на фастапи и добавил ссылку в скрипт.
\ В качестве модели мы будем использовать chatgpt-4o
embeddings = OpenAIEmbeddings(model=settings.OPENAI_API_EMBEDDINGS_MODEL)
llm = ChatOpenAI(api_key=settings.OPENAI_API_KEY, model=settings.OPEN_API_MODEL)
chroma_db = Chroma(
persist_directory="data",
embedding_function=embeddings,
collection_name="spec",
)
retriever = chroma_db.as_retriever()
prompt = PromptTemplate.from_template(
"""
System: You are an assistant that converts OpenAPI JSON specs into neatly structured, human-readable
text with summary, description, tags, produces, responses, parameters, method, and curl examples.
EXAMPLE ANSWER:
### GET /dogs
**Summary**: Retrieve a list of dogs
**Description**: Get a filtered list of dogs based on query parameters such as breed, age, or size.
**Tags**: Dogs
**Produces**: application/json
**Parameters**:
- **Query**:
- `breed` (string, optional): Filter by dog breed.
- `age` (integer, optional): Filter by dog age.
- `size` (string, optional): Filter by dog size (small, medium, large).
**Method**: GET
**Curl Example**:
```sh
curl -X GET "https://api.example.com/dogs?breed=labrador&size=medium" -H "Authorization: Bearer <your_token>"
```
Now, format the following OpenAPI spec:
{context}
{question}
"""
)
def format_docs(docs):
return "\n\n".join(doc.page_content for doc in docs)
chain = (
{"context": retriever | format_docs, "question": RunnablePassthrough()}
| prompt
| llm
| StrOutputParser()
)
chain.invoke(("How to get list of dogs?")
\ Я докуртил few shot промп и финальную версию можно увидеть в гитхаб репозитори.
Пример на основе Lamma
Если вы не готовы использовать OpenAPI в целях например безопасности или по другим причнам, всегда есть возможность запустить на Lamma7B для этого установить себе ламу. Спульте и заменить llm на
\
# pull model before usage
# ollama pull llama3.1
from langchain_ollama import OllamaLLM
llm = OllamaLLM(model="llama3.1:8b")
Lets Add StreamLete
куда же без этого молодца? В наших экспериментах? Даа.
\
import streamlit as st
if "messages" not in st.session_state:
st.session_state.messages = []
for message in st.session_state.messages:
with st.chat_message(message["role"]):
st.markdown(message["content"])
if prompt := st.chat_input("Enter your message."):
st.session_state.messages.append({"role": "user", "content": prompt})
with st.chat_message("user"):
st.markdown(prompt)
with st.chat_message("assistant"):
if (len(st.session_state.messages)):
r = chat_with_model(st.session_state.messages[-1]["content"])
response = st.write(r)
st.session_state.messages.append({"role": "assistant", "content": response})
\ Пару строк и получаем что то что мы уже можем трогать.
\
Результаты и тестовая спека
В рещультате я проетстировал
\ Резудльтаты впечатляют, все зависит от модели. А теперь подумайте сколько времени сэкономит это компаниям?
Заключение
Если вы нашли эту статью и эксперимент полезной для себя, поставьте звезду на гитхаб! RAG помог мне сохранить время и силы разобраться в разных спеках различных команд. В любом случае чем понятнее контекст и так далее тем улчше. Поэтому пишите качесвенно докстринги и документацию Фастапи и пайдентик в этом помогут.
\ Ссылка на гитхабыч чтобы запустить проект локльно (не забудь нажать на звездочку)
This content originally appeared on HackerNoon and was authored by Dmitrii Galkin
Dmitrii Galkin | Sciencx (2024-09-24T23:54:00+00:00) How to Turn Your OpenAPI Specification Into an AI Chatbot With RAG. Retrieved from https://www.scien.cx/2024/09/24/how-to-turn-your-openapi-specification-into-an-ai-chatbot-with-rag/
Please log in to upload a file.
There are no updates yet.
Click the Upload button above to add an update.