¡Te enseñaré paso a paso cómo construir un chatbot de IA usando Milvus y Towhee!

Como líder en bases de datos vectoriales, Milvus es adecuado para una variedad de aplicaciones de IA que requieren capacidades de búsqueda de vectores eficientes y escalables.

Por ejemplo, si desea crear un proceso de gestión de datos para un chatbot, Milvus debe ser la base de datos vectorial preferida. Entonces, para hacer que el desarrollo de esta aplicación sea más fácil de administrar y comprender mejor, es necesario utilizar Towhee ( https://towhee.io/ ). Towhee es un marco emergente de aprendizaje automático (ML) que simplifica el proceso de implementación y orquestación de modelos ML complejos.

A continuación, presentaré cómo usar Milvus + Towhee para crear un chatbot de IA básico a través de Python. Este artículo se centrará en cómo procesar y analizar datos no estructurados y almacenar y consultar datos vectoriales.

01. Configurar el entorno

Primero, cree un entorno virtual Python para ejecutar el chatbot.

La siguiente es una sesión de shell de Linux. Cree y active el entorno con la ayuda de la sesión de Shell y actualice pip a la última versión.

[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

A continuación, instale los paquetes necesarios para ejecutar su código: Pandas, Jupyter, Langchain, Towhee, Unstructured, Milvus, PymMilvus, frase_transformers y Gradio.

(chatbot_venv) [egoebelbecker@ares milvus_chatbot]$ pip install pandas jupyter langchain towhee unstructured milvus pymilvus sentence_transformers gradio
Collecting pandas
  Obtaining dependency information for pandas from https://files.pythonhosted.org/packages/d0/28/88b81881c056376254618fad622a5e94b5126db8c61157ea1910cd1c040a/pandas-2.0.3-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.metadata
  Using cached pandas-2.0.3-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.metadata (18 kB)
Collecting jupyter
  Using cached jupyter-1.0.0-py2.py3-none-any.whl (2.7 kB)
(snip)
Installing collected packages: 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
Successfully installed 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]$

Visite el enlace https://gist.github.com/egoebelbecker/07059b88a1c4daa96ec07937f8ca77b3 para obtener el Jupyter Notebook que cubre todo el código de este tutorial. Descargue Notebook, inicie Jupyter y cargue 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

02. Construye un chatbot

Una vez que todo esté listo, puedes construir el chatbot.

Almacenamiento de documento

El robot necesita almacenar el bloque de documentos y el vector del bloque de documentos extraídos con Towhee. En este paso, necesitamos usar Milvus.

Instale la versión ligera de Milvus Lite y ejecute el servidor Milvus usando el siguiente 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 …

O ejecute el código en el cuaderno:

from milvus import default_server

# 启动 Milvus 服务
default_server.start()

# 停止 Milvus 服务
default_server.stop()

Establezca variables de aplicación y obtenga la clave API de OpenAI

A continuación, configure las variables y limpie los archivos SQLite antiguos; usaremos SQLite para almacenar el historial de chat.

  • MILVUS_URI: información de conexión del servidor Milvus, resuelta en host y puerto.

  • MILVUS_HOST: el host donde se ejecuta Milvus.

  • MILVUS_PORT: el puerto en el que escucha el servidor.

  • DROP_EXIST: elimina las colecciones de Milvus existentes al inicio.

  • EMBED_MODEL: modelo de sentencia_transformadores utilizado para generar vectores de incrustación

  • COLLECTION_NAME: el nombre de la colección Milvus utilizada para almacenar datos vectoriales

  • DIM: dimensiones de los vectores de texto generados por el modelo.

  • OPENAI_API_KEY: clave para la API del modelo de lenguaje grande (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')

Ejecute el código anterior para definir las variables e ingrese la clave API de OpenAI.

Canalización de ejemplo

A continuación, los datos deben descargarse y almacenarse en Milvus. Pero antes de eso, aprendamos cómo utilizar la canalización para procesar datos no estructurados.

Usaré la página de inicio del sitio web oficial de Towhee como ejemplo de fuente de documentos para la demostración. También puede probar otros sitios web de documentos diferentes para comprender cómo la canalización procesa diferentes conjuntos de datos.

El siguiente código utiliza el oleoducto Towhee:

  • entrada: crea una nueva canalización y pasa los datos de origen.

  • map: utilice ops.text_loader() para analizar la URL y asignarla a 'doc'.

  • flat_map: utilice ops.text_splitter() para dividir el documento en fragmentos para su posterior almacenamiento.

  • salida: seleccione la salida de datos, lista para usar.

Pase esta canalización a DataCollection y observe cómo funciona.

from towhee import pipe, ops, DataCollectionpipe_load = (  

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()

El siguiente es el resultado:

Ejemplo de canalización de incrustación

A continuación, consulte el siguiente ejemplo de canalización de incorporación para convertir estos bloques de documentos en vectores. La canalización ejecuta ops.sentence_embedding.sbert() en cada bloque de documentos a través de map(). En el ejemplo, pasamos 1 bloque 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()

Ejecute este código para ver cómo esta canalización convierte fragmentos de documentos individuales en vectores.

Configurando Milvus

Cree una colección para almacenar datos.

En el siguiente código, usamos MILVUS_HOST y MILVUS_PORT para conectarnos a Milvus, eliminar todas las colecciones existentes y definir la función create_collection() para crear una nueva colección.

El esquema de la nueva Colección es el siguiente:

  • id: identificador, el tipo de datos es un número entero.

  • incrustación - vector, tipo de datos vector flotante.

  • texto: el texto del bloque de documento correspondiente al vector, el tipo de datos es cadena.

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

    # 创建 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

Insertar tubería

Ahora, inserta el vector de texto en Milvus.

El siguiente código funciona:

  • Crear nueva colección

  • Cargar nuevos datos del documento

  • Cortar un documento nuevo en trozos

  • Utilice EMBED_MODEL para generar vectores para bloques de texto

  • Inserte el vector de bloque de texto y los datos del bloque de texto correspondiente en 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')
)

A través del siguiente código, convertimos el contenido de la página de la enciclopedia de Frodo Baggins en un vector de texto rápido y lo insertamos en Milvus.

project_name = 'towhee_demo'
data_source = 'https://en.wikipedia.org/wiki/Frodo_Baggins'
mr = load_data(COLLECTION_NAME, data_source)

print('Doc chunks inserted:', len(mr.to_list()))

Finalmente, se insertaron un total de 408 vectores de bloques de texto:

2023-07-31 16:50:53,369 - 139993906521792 - node.py-node:167 - INFO: Begin to run Node-_input2023-07-31 16:50:53,371 - 139993906521792 - node.py-node:167 - INFO: Begin to run Node-create_collection-02023-07-31 16:50:53,373 - 139993881343680 - node.py-node:167 - INFO: Begin to run Node-text-loader-12023-07-31 16:50:53,374 - 139993898129088 - node.py-node:167 - INFO: Begin to run Node-text-splitter-22023-07-31 16:50:53,376 - 139993872950976 - node.py-node:167 - INFO: Begin to run Node-sentence-embedding/sbert-32023-07-31 16:50:53,377 - 139993385268928 - node.py-node:167 - INFO: Begin to run Node-np-normalize-42023-07-31 16:50:53,378 - 139993376876224 - node.py-node:167 - INFO: Begin to run Node-ann-insert/osschat-milvus-52023-07-31 16:50:53,379 - 139993368483520 - node.py-node:167 - INFO: Begin to run Node-_output

(snip)

Categories:
2023-07-31 18:07:53,530 - 140552729257664 - logger.py-logger:14 - DETAIL: Skipping sentence because does not exceed 5 word tokens
Categories
2023-07-31 18:07:53,532 - 140552729257664 - logger.py-logger:14 - DETAIL: Skipping sentence because does not exceed 3 word tokens
Hidden categories
2023-07-31 18:07:53,533 - 140552729257664 - logger.py-logger:14 - DETAIL: Skipping sentence because does not exceed 3 word tokens
Hidden categories
2023-07-31 18:07:53,533 - 140552729257664 - logger.py-logger:14 - DETAIL: Not narrative. Text does not contain a verb:

Hidden categories: 
2023-07-31 18:07:53,534 - 140552729257664 - logger.py-logger:14 - DETAIL: Skipping sentence because does not exceed 5 word tokens
Hidden categories

Doc chunks inserted: 408

03. Buscar en la base de conocimientos.

Los vectores de bloques de texto se han almacenado en Milvus y ahora se pueden realizar consultas de vectores.

La siguiente función crea una canalización de consultas. ¡Tenga en cuenta que este es el paso más crítico de este tutorial!

ops.ann_search.osschat_milvus(host=MILVUS_HOST, port=MILVUS_PORT, 
                              **{'metric_type': 'IP', 'limit': 3, 'output_fields': ['text']}))

OSSChat_milvus ( https://towhee.io/ann-search/osschat-milvus) consulta la base de datos vectorial Milvus en busca de fragmentos de documentos que coincidan con el texto de la consulta.

El siguiente es el código completo de la canalización de consultas:

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')
)

Ahora, puede intentar consultar las siguientes preguntas:

query = 'Who is Frodo Baggins?'
DataCollection(pipe_search(project_name, query)).show()

No es difícil encontrar que el modelo que utilizamos arrojó 3 resultados coincidentes (nota: limit=3 se especificó anteriormente en ann_search.osschat_milvus):

04. Agregar modelo de lenguaje grande (LLM)

A continuación, es necesario agregar LLM al chatbot. De esta forma, los usuarios pueden iniciar una conversación con el chatbot. En este ejemplo, utilizaremos el servicio modelo detrás de OpenAI ChatGPT: GPT-3.5.

registro de chat

Para que las respuestas de LLM sean más precisas, necesitamos almacenar los registros de chat de usuarios y robots, y llamar a estos registros al realizar consultas. SQLite se puede utilizar para administrar registros de chat.

Las siguientes funciones se utilizan para recuperar registros de chat:

<section id="nice" data-tool="mdnice编辑器" data-website="https://www.mdnice.com" style="font-size: 16px; padding: 0 10px; line-height: 1.6; word-spacing: 0px; letter-spacing: 0px; word-break: break-word; word-wrap: break-word; text-align: left; color: #3E3E3E; font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, 'PingFang SC', Cambria, Cochin, Georgia, Times, 'Times New Roman', serif;"><pre class="custom" data-tool="mdnice编辑器" style="margin-top: 10px; margin-bottom: 10px; border-radius: 5px; box-shadow: rgba(0, 0, 0, 0.55) 0px 2px 10px; text-align: left;"><span style="display: block; background: url(https://files.mdnice.com/user/3441/876cad08-0422-409d-bb5a-08afec5da8ee.svg); height: 30px; width: 100%; background-size: 40px; background-repeat: no-repeat; background-color: #282c34; margin-bottom: -7px; border-radius: 5px; background-position: 10px 10px;"></span><code class="hljs" style="overflow-x: auto; padding: 16px; color: #abb2bf; display: -webkit-box; font-family: Operator Mono, Consolas, Monaco, Menlo, monospace; font-size: 12px; -webkit-overflow-scrolling: touch; padding-top: 15px; background: #282c34; border-radius: 5px;">query = 'Who is Frodo Baggins?'
DataCollection(pipe_search(project_name, query)).show()
</code></pre>
</section>

La siguiente función el usuario almacena el historial de chat:

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')
)

Canal de consultas de LLM

Cree una canalización para pasar la consulta a LLM.

Esta canalización de consultas de LLM puede:

  • Busque en la base de datos de vectores Milvus según las preguntas de consulta de los usuarios

  • Recuperar y almacenar el historial de chat actual

  • Transfiera preguntas de usuario, resultados de búsqueda de Milvus y registros de chat a ChatGPT

  • Registre las preguntas y respuestas de esta ronda.

  • Volver a la respuesta final

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', )
)

Antes de conectarnos a la interfaz gráfica de usuario (GUI), debemos probar el siguiente Pipeline.

new_query = 'Where did Frodo take the ring?'
DataCollection(chat(COLLECTION_NAME, new_query, session_id)).show()

El siguiente es el resultado y los resultados:

¡Felicidades! ¡Este oleoducto se construyó con éxito! ¡A continuación, puedes construir la interfaz Gradio!

Interfaz de radio

Primero, se necesitan algunas funciones para crear una ID de sesión a través de UUID, aceptar y responder a las consultas de los usuarios en la interfaz.

import uuidimport 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

Luego, la interfaz de Gradio construye un chatbot a través de estas funciones. La API de bloques se utiliza para crear interfaces de chatbot. El botón Enviar mensaje envía la solicitud a ChatGPT a través de la función de respuesta.

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)

La interfaz es la siguiente:

¡En este punto, se completa un chatbot inteligente que combina la recuperación de vectores y la generación de LLM!

05. Resumen

En resumen, primero creamos el canal Towhee para procesar datos no estructurados, convertirlos en vectores y almacenarlos en la base de datos de vectores Milvus. Luego, se creó un canal de consultas y se conectó LLM al chatbot. Finalmente, se construye una interfaz básica de chatbot.

En resumen, Milvus es altamente escalable, proporciona funciones eficientes de búsqueda de similitudes de vectores y puede ayudar a los desarrolladores a crear fácilmente aplicaciones de aprendizaje automático e inteligencia artificial, como robots de chat, sistemas de recomendación, reconocimiento de imágenes o texto, etc. ¡Espero que todos utilicen Milvus para crear mejores aplicaciones!

  • Autor de este artículo

Eric Goebelbecker vive actualmente en Nueva York y tiene 25 años de experiencia en los mercados financieros. Es responsable de construir la infraestructura para la red del protocolo de Intercambio de Información Financiera (FIX) y los sistemas de análisis de datos de mercado. A Eric le apasiona explorar herramientas y software que mejoren la productividad del equipo.


  • Si tiene algún problema al utilizar los productos Milvus o Zilliz, puede agregar el asistente WeChat "zilliz-tech" para unirse al grupo de comunicación.

  • Bienvenido a seguir la cuenta pública de WeChat "Zilliz" para conocer la información más reciente.

Multado con 200 yuanes y más de 1 millón de yuanes confiscados You Yuxi: La importancia de los documentos chinos de alta calidad El servidor de migración de núcleo duro de Musk Solon para JDK 21, ¡los hilos virtuales son increíbles! ! ! El control de congestión de TCP salva Internet Flutter para OpenHarmony está aquí El período LTS del kernel de Linux se restaurará de 6 años a 2 años Go 1.22 solucionará el error de la variable del bucle for Svelte construyó una "nueva rueda" - runas Google celebra su 25 aniversario
{{o.nombre}}
{{m.nombre}}

Supongo que te gusta

Origin my.oschina.net/u/4209276/blog/10114595
Recomendado
Clasificación