Como criar um chatbot de IA com Milvus e Towhee
Milvus, um banco de dados vetorial de código aberto, é a espinha dorsal perfeita para qualquer aplicação de IA que exija recursos eficientes e escaláveis de busca vetorial, tornando-o uma escolha de destaque para o gerenciamento de dados do seu chatbot. Towhee é um framework emergente para fluxos de trabalho de machine learning que simplifica o processo de implementação e orquestração de modelos complexos de ML. Ele também torna o desenvolvimento da sua aplicação gerenciável e fácil de entender.
Neste tutorial, você aprenderá como criar um chatbot de IA simples com Python usando Milvus e Towhee. Você se concentrará em como ingerir dados não estruturados, analisá-los, armazená-los com embeddings e processar consultas.
Configurando seu ambiente
Primeiro, crie um ambiente virtual Python para executar seu chatbot.
Aqui está uma sessão de shell do Linux. Ela cria o ambiente, ativa-o e atualiza o pip para a versão mais recente.
[egoebelbecker@ares milvus_chatbot]$ python -m venv ./chatbot_venv
[egoebelbecker@ares milvus_chatbot]$ source chatbot_venv/bin/activate
(chatbot_venv) [egoebelbecker@ares milvus_chatbot]$ pip install --upgrade pip
Requirement already satisfied: pip in ./chatbot_venv/lib64/python3.11/site-packages (22.2.2)
Collecting pip
Using cached pip-23.1.2-py3-none-any.whl (2.1 MB)
Installing collected packages: pip
Attempting uninstall: pip
Found existing installation: pip 22.2.2
Uninstalling pip-22.2.2:
Successfully uninstalled pip-22.2.2
Successfully installed pip-23.1.2
Em seguida, instale os pacotes necessários para executar o código: pandas, jupyter, langchain, towhee, unstructured, milvus, pymilvus, sentence_transformers e gradio.
(chatbot_venv) [egoebelbecker@ares milvus_chatbot]$ pip install pandas jupyter langchain towhee unstructured milvus pymilvus sentence_transformers gradio
Coletando pandas
Obtendo informações de dependência para pandas de https://files.pythonhosted.org/packages/d0/28/88b81881c056376254618fad622a5e94b5126db8c61157ea1910cd1c040a/pandas-2.0.3-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.metadata
Usando pandas-2.0.3-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.metadata em cache (18 kB)
Coletando jupyter
Usando jupyter-1.0.0-py2.py3-none-any.whl em cache (2.7 kB)
(corte)
Instalando pacotes coletados: webencodings, wcwidth, pytz, pure-eval, ptyprocess, pickleshare, json5, ipython-genutils, filetype, fastjsonschema, executing, backcall, zipp, XlsxWriter, xlrd, widgetsnbextension, websocket-client, webcolors, urllib3, uri-template, tzdata, typing-extensions, traitlets, tqdm, tornado, tinycss2, tenacity, tabulate, soupsieve, sniffio, six, send2trash, rpds-py, rfc3986-validator, rfc3986, regex, pyzmq, PyYAML, python-magic, python-json-logger, pypandoc, pygments, pycparser, psutil, prompt-toolkit, prometheus-client, platformdirs, pkginfo, pillow, pexpect, parso, pandocfilters, packaging, overrides, olefile, numpy, nest-asyncio, mypy-extensions, multidict, more-itertools, mistune, mdurl, markupsafe, markdown, lxml, jupyterlab-widgets, jupyterlab-pygments, jsonpointer, joblib, jeepney, idna, greenlet, frozenlist, fqdn, et-xmlfile, docutils, defusedxml, decorator, debugpy, click, charset-normalizer, chardet, certifi, babel, attrs, async-timeout, async-lru, yarl, typing-inspect, terminado, SQLAlchemy, rfc3339-validator, requests, referencing, qtpy, python-pptx, python-docx, python-dateutil, pydantic, pdf2image, openpyxl, numexpr, nltk, msg-parser, matplotlib-inline, marshmallow, markdown-it-py, jupyter-core, jinja2, jedi, jaraco.classes, importlib-metadata, comm, cffi, bleach, beautifulsoup4, asttokens, anyio, aiosignal, stack-data, rich, requests-toolbelt, readme-renderer, pandas, openapi-schema-pydantic, langsmith, jupyter-server-terminals, jupyter-client, jsonschema-specifications, dataclasses-json, cryptography, arrow, argon2-cffi-bindings, aiohttp, SecretStorage, pdfminer.six, langchain, jsonschema, isoduration, ipython, argon2-cffi, unstructured, nbformat, keyring, ipykernel, twine, qtconsole, nbclient, jupyter-events, jupyter-console, ipywidgets, towhee, nbconvert, jupyter-server, notebook-shim, jupyterlab-server, jupyter-lsp, jupyterlab, notebook, jupyter
Instalado com sucesso PyYAML-6.0.1 SQLAlchemy-2.0.19 SecretStorage-3.3.3 XlsxWriter-3.1.2 aiohttp-3.8.5 aiosignal-1.3.1 anyio-3.7.1 argon2-cffi-21.3.0 argon2-cffi-bindings-21.2.0 arrow-1.2.3 asttokens-2.2.1 async-lru-2.0.4 async-timeout-4.0.2 attrs-23.1.0 babel-2.12.1 backcall-0.2.0 beautifulsoup4-4.12.2 bleach-6.0.0 certifi-2023.7.22 cffi-1.15.1 chardet-5.1.0 charset-normalizer-3.2.0 click-8.1.6 comm-0.1.3 cryptography-41.0.2 dataclasses-json-0.5.14 debugpy-1.6.7 decorator-5.1.1 defusedxml-0.7.1 docutils-0.20.1 et-xmlfile-1.1.0 executing-1.2.0 fastjsonschema-2.18.0 filetype-1.2.0 fqdn-1.5.1 frozenlist-1.4.0 greenlet-2.0.2 idna-3.4 importlib-metadata-6.8.0 ipykernel-6.25.0 ipython-8.14.0 ipython-genutils-0.2.0 ipywidgets-8.0.7 isoduration-20.11.0 jaraco.classes-3.3.0 jedi-0.19.0 jeepney-0.8.0 jinja2-3.1.2 joblib-1.3.1 json5-0.9.14 jsonpointer-2.4 jsonschema-4.18.4 jsonschema-specifications-2023.7.1 jupyter-1.0.0 jupyter-client-8.3.0 jupyter-console-6.6.3 jupyter-core-5.3.1 jupyter-events-0.7.0 jupyter-lsp-2.2.0 jupyter-server-2.7.0 jupyter-server-terminals-0.4.4 jupyterlab-4.0.3 jupyterlab-pygments-0.2.2 jupyterlab-server-2.24.0 jupyterlab-widgets-3.0.8 keyring-24.2.0 langchain-0.0.248 langsmith-0.0.15 lxml-4.9.3 markdown-3.4.4 markdown-it-py-3.0.0 markupsafe-2.1.3 marshmallow-3.20.1 matplotlib-inline-0.1.6 mdurl-0.1.2 mistune-3.0.1 more-itertools-10.0.0 msg-parser-1.2.0 multidict-6.0.4 mypy-extensions-1.0.0 nbclient-0.8.0 nbconvert-7.7.3 nbformat-5.9.2 nest-asyncio-1.5.7 nltk-3.8.1 notebook-7.0.1 notebook-shim-0.2.3 numexpr-2.8.4 numpy-1.25.2 olefile-0.46 openapi-schema-pydantic-1.2.4 openpyxl-3.1.2 overrides-7.3.1 packaging-23.1 pandas-2.0.3 pandocfilters-1.5.0 parso-0.8.3 pdf2image-1.16.3 pdfminer.six-20221105 pexpect-4.8.0 pickleshare-0.7.5 pillow-10.0.0 pkginfo-1.9.6 platformdirs-3.10.0 prometheus-client-0.17.1 prompt-toolkit-3.0.39 psutil-5.9.5 ptyprocess-0.7.0 pure-eval-0.2.2 pycparser-2.21 pydantic-1.10.12 pygments-2.15.1 pypandoc-1.11 python-dateutil-2.8.2 python-docx-0.8.11 python-json-logger-2.0.7 python-magic-0.4.27 python-pptx-0.6.21 pytz-2023.3 pyzmq-25.1.0 qtconsole-5.4.3 qtpy-2.3.1 readme-renderer-40.0 referencing-0.30.0 regex-2023.6.3 requests-2.31.0 requests-toolbelt-1.0.0 rfc3339-validator-0.1.4 rfc3986-2.0.0 rfc3986-validator-0.1.1 rich-13.5.1 rpds-py-0.9.2 send2trash-1.8.2 six-1.16.0 sniffio-1.3.0 soupsieve-2.4.1 stack-data-0.6.2 tabulate-0.9.0 tenacity-8.2.2 terminado-0.17.1 tinycss2-1.2.1 tornado-6.3.2 towhee-1.1.1 tqdm-4.65.0 traitlets-5.9.0 twine-4.0.2 typing-extensions-4.7.1 typing-inspect-0.9.0 tzdata-2023.3 unstructured-0.8.7 uri-template-1.3.0 urllib3-2.0.4 wcwidth-0.2.6 webcolors-1.13 webencodings-0.5.1 websocket-client-1.6.1 widgetsnbextension-4.0.8 xlrd-2.0.1 yarl-1.9.2 zipp-3.16.2
(chatbot_venv) [egoebelbecker@ares milvus_chatbot]$
Você pode encontrar um notebook Jupyter com o código para este tutorial aqui. Baixe-o, inicie o Jupyter e carregue o notebook:
chatbot_venv) [egoebelbecker@ares milvus_chatbot]$ jupyter notebook milvus_chatbot.ipynb
[I 2023-07-31 11:29:01.748 ServerApp] Package notebook took 0.0000s to import
[I 2023-07-31 11:29:01.759 ServerApp] Package jupyter_lsp took 0.0108s to import
[W 2023-07-31 11:29:01.759 ServerApp] A `_jupyter_server_extension_points` function was not found in jupyter_lsp. Instead, a `_jupyter_server_extension_paths` function was found and will be used for now. This function name will be deprecated in future releases of Jupyter Server.
[I 2023-07-31 11:29:01.764 ServerApp] Package jupyter_server_terminals took 0.0045s to import
[I 2023-07-31 11:29:01.765 ServerApp] Package jupyterlab took 0.0000s to import
[I 2023-07-31 11:29:02.124 ServerApp] Package notebook_shim took 0.0000s to import
Criando um chatbot
Agora, vamos trabalhar no chatbot.
Armazenamento de documentos
O bot precisa armazenar trechos de documentos e os embeddings que o Towhee extrai deles. É para isso que você usará o Milvus. Você já instalou o Milvus Lite, uma versão leve do Milvus, acima com a biblioteca milvus.
Você pode executar um servidor pela linha de comando:
(chatbot_venv) [egoebelbecker@ares milvus_chatbot]$ milvus-server
__ _________ _ ____ ______
/ |/ / _/ /| | / / / / / __/
/ /|_/ // // /_| |/ / /_/ /\ \
/_/ /_/___/____/___/\____/___/ {Lite}
Welcome to use Milvus!
Version: v2.2.12-lite
Process: 139309
Started: 2023-07-31 12:43:43
Config: /home/egoebelbecker/.milvus.io/milvus-server/2.2.12/configs/milvus.yaml
Logs: /home/egoebelbecker/.milvus.io/milvus-server/2.2.12/logs
Ctrl+C to exit …
Ou, como parte do código da sua aplicação, como mostrado no notebook:
from milvus import default_server
# Start Milvus service
default_server.start()
# # Stop Milvus service
# default_server.stop()
Defina variáveis da aplicação e obtenha a chave de API da OpenAI
Em seguida, defina algumas variáveis e limpe quaisquer arquivos SQLite restantes. Usaremos SQLite abaixo para o histórico de chat.
- MILVUS_URI - as informações de conexão para os servidores Milvus. Analisadas em host e porta.
- MILVUS_HOST - o host onde o Milvus está em execução.
- MILVUS_PORT - a porta em que o servidor escuta.
- DROP_EXIST - descartar coleções Milvus existentes na inicialização.
- EMBED_MODEL - o modelo sentence_transformers que o código usará para criar embeddings
- COLLECTION_NAME - nome da coleção Milvus para dados e embeddings
- DIM - a dimensão dos embeddings que o modelo cria para cada trecho de texto
- OPENAI_API_KEY - chave para a API do LLM
import getpass
import os
MILVUS_URI = 'http://localhost:19530'
[MILVUS_HOST, MILVUS_PORT] = MILVUS_URI.split('://')[1].split(':')
DROP_EXIST = True
EMBED_MODEL = 'all-mpnet-base-v2'
COLLECTION_NAME = 'chatbot_demo'
DIM = 768
OPENAI_API_KEY = getpass.getpass('Enter your OpenAI API key: ')
if os.path.exists('./sqlite.db'):
os.remove('./sqlite.db')
Execute este código para definir as variáveis e responder ao prompt da chave de API.
Pipeline de exemplo
Em seguida, é hora de baixar alguns dados e armazená-los no Milvus. Mas antes de fazer isso, vamos ver um pipeline de exemplo para baixar e processar dados não estruturados.
Você usará as páginas da documentação do Towhee para este exemplo. Você pode experimentar sites diferentes para ver como o código processa diferentes conjuntos de dados.
Este código usa pipelines do Towhee:
- input - inicia um novo pipeline com a fonte passada para ele
- map - usa ops.text_loader() para recuperar a URL e mapeá-la para 'doc'
- flat_map - usa ops.text_splitter() para processar o documento em "trechos" para armazenamento
- output - fecha e prepara o pipeline para uso
Passe este pipeline para DataCollection para ver como ele funciona.
from towhee import pipe, ops, DataCollection
pipe_load = (
pipe.input('source')
.map('source', 'doc', ops.text_loader())
.flat_map('doc', 'doc_chunks', ops.text_splitter(chunk_size=300))
.output('source', 'doc_chunks')
)
DataCollection(pipe_load('https://towhee.io')).show()
Aqui está a saída de show():
O pipeline criou cinco chunks a partir do documento.
Pipeline de embedding de exemplo
O pipeline recuperou os dados e criou chunks. Você também precisa criar embeddings. Vamos dar uma olhada em outro pipeline de exemplo.
Este usa map() para executar ops.sentence_embedding.sbert() em cada chunk. Neste exemplo, estamos passando um único bloco de texto.
pipe_embed = (
pipe.input('doc_chunk')
.map('doc_chunk', 'vec', ops.sentence_embedding.sbert(model_name=EMBED_MODEL))
.map('vec', 'vec', ops.np_normalize())
.output('doc_chunk', 'vec')
)
text = '''SOTA Models
We provide 700+ pre-trained embedding models spanning 5 fields (CV, NLP, Multimodal, Audio, Medical), 15 tasks, and 140+ model architectures.
These include BERT, CLIP, ViT, SwinTransformer, data2vec, etc.
'''
DataCollection(pipe_embed(text)).show()
Execute este código para ver como o pipeline processa o único bloco de texto.
Preparar o Milvus
Agora, você precisa de uma collection para armazenar os dados. Este bloco define create_collection(), que usa MILVUS_HOST e MILVUS_PORT para se conectar ao Milvus, descartar quaisquer collections existentes com o nome especificado e criar uma nova com este schema:
- id - um identificador inteiro
- embedding - um vetor de floats para os embeddings
- text - o texto correspondente aos embeddings
from pymilvus import (
connections, utility, Collection,
CollectionSchema, FieldSchema, DataType
)
def create_collection(collection_name):
connections.connect(host=MILVUS_HOST, port=MILVUS_PORT)
has_collection = utility.has_collection(collection_name)
if has_collection:
collection = Collection(collection_name)
if DROP_EXIST:
collection.drop()
else:
return collection
# Create collection
fields = [
FieldSchema(name='id', dtype=DataType.INT64, is_primary=True, auto_id=True),
FieldSchema(name='embedding', dtype=DataType.FLOAT_VECTOR, dim=DIM),
FieldSchema(name='text', dtype=DataType.VARCHAR, max_length=500)
]
schema = CollectionSchema(
fields=fields,
description="Towhee demo",
enable_dynamic_field=True
)
collection = Collection(name=collection_name, schema=schema)
index_params = {
'metric_type': 'IP',
'index_type': 'IVF_FLAT',
'params': {'nlist': 1024}
}
collection.create_index(
field_name='embedding',
index_params=index_params
)
return collection
Pipeline de inserção
É hora de processar seu texto de entrada e inseri-lo no Milvus. Vamos começar com um pipeline que consolida o que você aprendeu acima.
Esta função:
- Cria a nova collection
- Recupera os dados
- Divide-os em chunks
- Cria embeddings usando EMBED_MODEL
- Insere o texto e os embeddings no Milvus
load_data = (
pipe.input('collection_name', 'source')
.map('collection_name', 'collection', create_collection)
.map('source', 'doc', ops.text_loader())
.flat_map('doc', 'doc_chunk', ops.text_splitter(chunk_size=300))
.map('doc_chunk', 'vec', ops.sentence_embedding.sbert(model_name=EMBED_MODEL))
.map('vec', 'vec', ops.np_normalize())
.map(('collection_name', 'vec', 'doc_chunk'), 'mr',
ops.ann_insert.osschat_milvus(host=MILVUS_HOST, port=MILVUS_PORT))
.output('mr')
)
Aqui está em ação. Execute-o na página da Wikipedia sobre Frodo Baggins.
project_name = 'towhee_demo'
data_source = 'https://en.wikipedia.org/wiki/Frodo_Baggins'
mr = load_data(COLLECTION_NAME, data_source)
print('Fragmentos do documento inseridos:', len(mr.to_list()))
Ele insere 408 fragmentos com embeddings:
2023-07-31 16:50:53,369 - 139993906521792 - node.py-node:167 - INFO: Begin to run Node-_input
2023-07-31 16:50:53,371 - 139993906521792 - node.py-node:167 - INFO: Begin to run Node-create_collection-0
2023-07-31 16:50:53,373 - 139993881343680 - node.py-node:167 - INFO: Begin to run Node-text-loader-1
2023-07-31 16:50:53,374 - 139993898129088 - node.py-node:167 - INFO: Begin to run Node-text-splitter-2
2023-07-31 16:50:53,376 - 139993872950976 - node.py-node:167 - INFO: Begin to run Node-sentence-embedding/sbert-3
2023-07-31 16:50:53,377 - 139993385268928 - node.py-node:167 - INFO: Begin to run Node-np-normalize-4
2023-07-31 16:50:53,378 - 139993376876224 - node.py-node:167 - INFO: Begin to run Node-ann-insert/osschat-milvus-5
2023-07-31 16:50:53,379 - 139993368483520 - node.py-node:167 - INFO: Begin to run Node-_output
(snip)
Categorias:
2023-07-31 18:07:53,530 - 140552729257664 - logger.py-logger:14 - DETAIL: Ignorando sentença porque não excede 5 tokens de palavras
Categorias
2023-07-31 18:07:53,532 - 140552729257664 - logger.py-logger:14 - DETAIL: Ignorando sentença porque não excede 3 tokens de palavras
Categorias ocultas
2023-07-31 18:07:53,533 - 140552729257664 - logger.py-logger:14 - DETAIL: Ignorando sentença porque não excede 3 tokens de palavras
Categorias ocultas
2023-07-31 18:07:53,533 - 140552729257664 - logger.py-logger:14 - DETAIL: Não narrativo. O texto não contém um verbo:
Categorias ocultas:
2023-07-31 18:07:53,534 - 140552729257664 - logger.py-logger:14 - DETAIL: Ignorando sentença porque não excede 5 tokens de palavras
Categorias ocultas
Fragmentos do documento inseridos: 408
Pesquisar na base de conhecimento
Agora, com os embeddings e o texto armazenados no Milvus, você pode pesquisá-los.
Esta função cria um pipeline de consulta. A etapa mais importante é esta:
ops.ann_search.osschat_milvus(host=MILVUS_HOST, port=MILVUS_PORT,
**{'metric_type': 'IP', 'limit': 3, 'output_fields': ['text']}))
O osschat_milvus pesquisa os embeddings em busca de correspondências com o texto enviado.
Aqui está o pipeline completo:
pipe_search = (
pipe.input('collection_name', 'query')
.map('query', 'query_vec', ops.sentence_embedding.sbert(model_name=EMBED_MODEL))
.map('query_vec', 'query_vec', ops.np_normalize())
.map(('collection_name', 'query_vec'), 'search_res',
ops.ann_search.osschat_milvus(host=MILVUS_HOST, port=MILVUS_PORT,
**{'metric_type': 'IP', 'limit': 3, 'output_fields': ['text']}))
.flat_map('search_res', ('id', 'score', 'text'), lambda x: (x[0], x[1], x[2]))
.output('query', 'text', 'score')
)
Experimente:
query = 'Who is Frodo Baggins?'
DataCollection(pipe_search(project_name, query)).show()
O modelo faz um bom trabalho ao recuperar três nós estreitamente correspondentes:
Adicionar um LLM
Agora, é hora de adicionar um grande modelo de linguagem (LLM) para que os usuários possam manter uma conversa com o chatbot. Usaremos o ChatGPT e a API da OpenAI neste exemplo.
Histórico de chat
Para obter melhores resultados do LLM, você precisa armazenar o histórico de chat e apresentá-lo com as consultas. Você usará SQLite para esta etapa.
Aqui está uma função para recuperar o histórico:
pipe_get_history = (
pipe.input('collection_name', 'session')
.map(('collection_name', 'session'), 'history', ops.chat_message_histories.sql(method='get'))
.output('collection_name', 'session', 'history')
)
Aqui está a função para armazená-lo:
pipe_add_history = (
pipe.input('collection_name', 'session', 'question', 'answer')
.map(('collection_name', 'session', 'question', 'answer'), 'history', ops.chat_message_histories.sql(method='add'))
.output('history')
)
Pipeline de consulta LLM
Agora, precisamos de um pipeline para enviar consultas ao ChatGPT.
Este pipeline:
- pesquisa no Milvus usando a consulta do usuário
- coleta o histórico atual do chat
- envia a consulta, a pesquisa no Milvus e o histórico do chat para o ChatGPT
- Acrescenta o resultado do ChatGPT ao histórico do chat
- Retorna o resultado ao chamador
chat = (
pipe.input('collection_name', 'query', 'session')
.map('query', 'query_vec', ops.sentence_embedding.sbert(model_name=EMBED_MODEL))
.map('query_vec', 'query_vec', ops.np_normalize())
.map(('collection_name', 'query_vec'), 'search_res',
ops.ann_search.osschat_milvus(host=MILVUS_HOST,
port=MILVUS_PORT,
**{'metric_type': 'IP', 'limit': 3, 'output_fields': ['text']}))
.map('search_res', 'knowledge', lambda y: [x[2] for x in y])
.map(('collection_name', 'session'), 'history', ops.chat_message_histories.sql(method='get'))
.map(('query', 'knowledge', 'history'), 'messages', ops.prompt.question_answer())
.map('messages', 'answer', ops.LLM.OpenAI(api_key=OPENAI_API_KEY,
model_name='gpt-3.5-turbo',
temperature=0.8))
.map(('collection_name', 'session', 'query', 'answer'), 'new_history', ops.chat_message_histories.sql(method='add'))
.output('query', 'history', 'answer', )
)
Vamos testar este pipeline antes de conectá-lo a uma GUI:
new_query = 'Where did Frodo take the ring?'
DataCollection(chat(COLLECTION_NAME, new_query, session_id)).show()
Aqui estão a saída e os resultados no notebook:
O pipeline funciona. Vamos montar uma interface Gradio.
GUI Gradio
Primeiro, você precisa de funções para criar um identificador de sessão e responder a consultas da interface.
Estas funções criam um ID de sessão usando um UUID e aceitam uma sessão e uma consulta para o pipeline de consulta.
import uuid
import io
def create_session_id():
uid = str(uuid.uuid4())
suid = ''.join(uid.split('-'))
return 'sess_' + suid
def respond(session, query):
res = chat(COLLECTION_NAME, query, session).get_dict()
answer = res['answer']
response = res['history']
response.append((query, answer))
return response
Em seguida, a interface Gradio usa estas funções para criar um chatbot.
Ela usa a API Blocks para criar uma interface ChatBot. O botão Send Message usa a função respond para enviar solicitações ao ChatGPT.
import gradio as gr
with gr.Blocks() as demo:
session_id = gr.State(create_session_id)
with gr.Row():
with gr.Column(scale=2):
gr.Markdown('''## Chat''')
conversation = gr.Chatbot(label='conversation').style(height=300)
question = gr.Textbox(label='question', value=None)
send_btn = gr.Button('Send Message')
send_btn.click(
fn=respond,
inputs=[
session_id,
question
],
outputs=conversation,
)
demo.launch(server_name='127.0.0.1', server_port=8902)
Aqui está:
Agora, você tem um chatbot inteligente baseado em LLM com Milvus!
Resumo
Neste post, criamos pipelines Towhee para ingerir dados não estruturados, processá-los para embeddings e armazenar esses embeddings no Milvus. Em seguida, criamos um pipeline de consulta para a função de chat e conectamos o chatbot a um LLM. Por fim, obtivemos um chatbot inteligente.
Este tutorial demonstra como é fácil criar aplicações com Milvus. O Milvus traz inúmeras vantagens quando integrado a aplicações, especialmente aquelas que dependem de aprendizado de máquina e inteligência artificial. Ele oferece recursos de busca e análise de similaridade vetorial altamente eficientes, escaláveis e confiáveis, essenciais em aplicações como chatbots, sistemas de recomendação e reconhecimento de imagens ou texto.
Este post foi escrito por Eric Goebelbecker. Eric trabalhou nos mercados financeiros da cidade de Nova York por 25 anos, desenvolvendo infraestrutura para dados de mercado e redes do protocolo de troca de informações financeiras (FIX). Ele adora falar sobre o que torna as equipes eficazes (ou não tão eficazes!).
Continue lendo

Introducing Zilliz Cloud Global Cluster: Region-Level Resilience for Mission-Critical AI
Zilliz Cloud Global Cluster delivers multi-region resilience, automatic failover, and fast global AI search with built-in security and compliance.

Why Deepseek is Waking up AI Giants Like OpenAI And Why You Should Care
Discover how DeepSeek R1's open-source AI model with superior reasoning capabilities and lower costs is disrupting the AI landscape and challenging tech giants like OpenAI.

Vector Databases vs. Hierarchical Databases
Use a vector database for AI-powered similarity search; use a hierarchical database for organizing data in parent-child relationships with efficient top-down access patterns.



