Todos os produtos
Search
Central de documentação

Vector Retrieval Service for Milvus:Construa um pipeline de análise de voz no atendimento ao cliente e correspondência inteligente de FAQ com o Alibaba Cloud Milvus

Última atualização: Oct 20, 2026

Este tópico descreve como usar seis AI Functions do Alibaba Cloud Milvus para montar um pipeline de processamento de voz no atendimento ao cliente. Nele, as gravações são transcritas automaticamente em texto no momento da escrita, as informações pessoais (PII) são mascaradas antes da ingestão, os FAQs são vetorizados na escrita, as respostas padrão são correspondidas com precisão via recuperação semântica e reranking de modelos grandes, e o reconhecimento de sentimento e a classificação de chamados são concluídos automaticamente para as conversas.

Visão geral da solução

O maior ativo de dados acumulado diariamente pelo atendimento ao cliente online e telefônico é o volume massivo de gravações de chamadas e mensagens de voz. Um contact center de médio porte lida facilmente com dezenas de milhares de chamadas por dia, com durações de gravação medidas em milhares de horas. Essas gravações contêm as demandas mais autênticas dos clientes, a qualidade do service dos agentes e possíveis riscos de opinião pública. No entanto, a maioria das equipes ainda as trata como dados frios, arquivados apenas para fins de conformidade. Para ativar esses ativos de voz, você precisa:

  • Converter áudio em texto: Transcreva chamadas e mensagens de voz em massa para um texto pesquisável e analisável. Este é o pré-requisito para tudo o que vem a seguir.

  • Construir uma base de conhecimento pesquisável: Acumule respostas históricas de alta qualidade, manuais de product e FAQs em uma base de conhecimento com busca semântica, que bots e agentes possam consultar em tempo real.

  • Correspondência inteligente de FAQ: Uma pergunta coloquial do usuário deve atingir o FAQ padrão com precisão, em vez de depender da sorte com palavras-chave.

  • Reconhecimento de sentimento e intenção: Identifique flutuações na emoção do cliente durante as chamadas para dar suporte a alertas em tempo real e inspeção de qualidade pós-chamada.

  • Inspeção de qualidade e mascaramento para conformidade: O texto transcrito geralmente contém informações pessoais sensíveis, como números de celular, números de documentos de identidade e números de cartão bancário, que devem ser mascarados antes da ingestão, análise ou compartilhamento.

Para reunir esse conjunto de capacidades, as soluções tradicionais geralmente precisam encadear quatro ou mais sistemas: um service de ASR, um banco de dados vetorial, uma plataforma externa de NLP e um service de reranking. Os dados trafegam de um lado para o outro entre vários sistemas, o código de integração continua se acumulando e uma falha em qualquer elo compromete todo o pipeline. Além disso, o texto bruto transcrito fluindo para service externos cria o risco de vazamento de informações pessoais sensíveis, enquanto o mascaramento costuma ser colocado no final do pipeline ou até mesmo omitido.

As AI Functions do Alibaba Cloud Milvus convergem essas capacidades para o mesmo banco de dados vetorial. A inferência do modelo é acionada automaticamente dentro do Milvus durante a escrita e a recuperação, e os dados nunca saem da instância. Este tópico usa seis Functions:

Function

Finalidade

Uso no pipeline de voz do atendimento ao cliente

AI_AUDIO_TRANSCRIBE

Transcreve gravações em texto automaticamente na escrita, sem necessidade de chamar um ASR no lado da aplicação primeiro.

Transforma gravações massivas de chamadas em texto pesquisável e analisável.

AI_PII_MASK

Mascara automaticamente informações sensíveis, como números de celular, documentos de identidade e cartões bancários no texto.

Garante que apenas o texto mascarado entre na base de conhecimento e no banco de dados de análise, antecipando a conformidade no pipeline.

AI_EMBEDDING

Converte automaticamente o texto do FAQ em vetores na escrita.

Permite que solicitações coloquiais, como "como conecto minha instância à Internet", sejam encontradas por recuperação semântica.

AI_RERANK

Reordena os candidatos recuperados por relevância em relação à consulta.

Coloca o FAQ que melhor se encaixa na intenção na primeira posição, corrigindo o ruído da recuperação vetorial.

AI_SENTIMENT

Determina a tendência de sentimento de uma conversa.

Agrega rótulos de sentimento para dar suporte à inspeção de qualidade de volume total e alertas de opinião pública.

AI_CLASSIFY

Classifica as conversas em categorias de chamados.

Suporta a classificação e o roteamento automático de chamados.

Pré-requisitos

  • É necessário que você crie uma instância do Milvus 2.6. As AI Functions dependem do kernel 2.6 e não exigem vinculação separada a um service de modelo após a criação.

  • Para acessar a instância pela Internet, ative o Internet Access na guia Security Configuration da página de detalhes da instância e adicione o IP de saída do cliente à lista de permissões de acesso à Internet.

  • O pymilvus deve estar instalado. Os exemplos neste tópico são verificados com o pymilvus 3.0.0.

  • As gravações a serem transcritas devem estar em um endereço real para que o servidor baixe.

Nota

A RESTful API e o gRPC compartilham a porta 19530. Você deve incluir explicitamente a porta ao fazer a chamada, por exemplo http://c-xxx.milvus.aliyuncs.com:19530. Omitir a porta usa como padrão a porta 80 e causa um tempo limite de conexão.

Aviso

O endereço de áudio deve ser um endereço para que o servidor realmente baixe. Em ambientes de produção, recomendamos o uso de uma URL assinada de curta duração do seu próprio bucket do OSS. Se você passar um placeholder ou um endereço expirado, o erro Failed to download multimodal content será relatado.

Procedimento

Prepare o código compartilhado

O código a seguir contém a configuração de conexão, o wrapper de chamada REST e um fallback de compatibilidade para o tipo de função TEXTTRANSFORM, que são compartilhados pelas etapas subsequentes. Substitua MILVUS_URI e MILVUS_TOKEN pelas informações reais da sua instância.

from __future__ import annotations

import json
import time
from typing import Any
from urllib.error import HTTPError
from urllib.request import Request, urlopen

from pymilvus import DataType, Function, FunctionType, MilvusClient

# ==================== Connection configuration ====================
MILVUS_URI = "http://c-xxx.milvus.aliyuncs.com:19530"  # The port must be written as 19530
MILVUS_TOKEN = "root:xxx"
MILVUS_REST_BASE_URL = MILVUS_URI

client = MilvusClient(uri=MILVUS_URI, token=MILVUS_TOKEN)

# AI_AUDIO_TRANSCRIBE / AI_PII_MASK / AI_SENTIMENT / AI_CLASSIFY are all Functions of the
# TEXTTRANSFORM type (function type value 9), distinguished by the task parameter.
# Some pymilvus versions do not have this member in the FunctionType enum, so a compatibility fallback is provided below.
TEXTTRANSFORM_FUNCTION_TYPE = 9

def texttransform_function_type() -> Any:
    for type_name in ("TEXTTRANSFORM", "TEXT_TRANSFORM", "TextTransform"):
        ft = getattr(FunctionType, type_name, None)
        if ft is not None:
            return ft
    existing = getattr(FunctionType, "_value2member_map_", {}).get(TEXTTRANSFORM_FUNCTION_TYPE)
    if existing is not None:
        return existing
    extension = int.__new__(FunctionType, TEXTTRANSFORM_FUNCTION_TYPE)
    extension._name_ = "TEXTTRANSFORM"
    extension._value_ = TEXTTRANSFORM_FUNCTION_TYPE
    FunctionType._value2member_map_[TEXTTRANSFORM_FUNCTION_TYPE] = extension
    FunctionType._member_map_["TEXTTRANSFORM"] = extension
    return extension

def post_json(path: str, body: dict[str, Any], timeout: int = 120,
              retries: int = 3) -> tuple[int, dict[str, Any]]:
    """Unified wrapper for the REST real-time APIs (these call large models, so retries make them more stable)."""
    last: tuple[int, dict[str, Any]] | None = None
    for _ in range(retries):
        request = Request(
            f"{MILVUS_REST_BASE_URL.rstrip('/')}{path}",
            data=json.dumps(body, ensure_ascii=False).encode("utf-8"),
            headers={"Authorization": f"Bearer {MILVUS_TOKEN}",
                     "Content-Type": "application/json"},
            method="POST",
        )
        try:
            with urlopen(request, timeout=timeout) as response:
                status, data = response.status, json.loads(response.read().decode("utf-8"))
        except HTTPError as exc:
            status, data = exc.code, json.loads(exc.read().decode("utf-8"))
        last = (status, data)
        if status == 200 and data.get("code") == 0:
            return status, data
        time.sleep(1)
    return last
Nota

AI_AUDIO_TRANSCRIBE, AI_PII_MASK, AI_SENTIMENT e AI_CLASSIFY são todas Functions do tipo TEXTTRANSFORM (valor de tipo de função 9), diferenciadas pelo parâmetro task. AI_EMBEDDING e AI_RERANK possuem suas próprias constantes FunctionType independentes.

Etapa 1: Transcreva as gravações

Transcreva gravações de chamadas em texto em massa. Após anexar o AI_AUDIO_TRANSCRIBE a uma coleção, o texto transcrito é gerado automaticamente quando você escreve os endereços de áudio, sem necessidade de chamar um service de ASR no lado da aplicação primeiro.

# ==================== Step 1: AI_AUDIO_TRANSCRIBE audio transcription ====================
collection_name = "cs_transcribe"
if client.has_collection(collection_name):
    client.drop_collection(collection_name)

schema = MilvusClient.create_schema(auto_id=True, enable_dynamic_field=False)
schema.add_field("id", DataType.INT64, is_primary=True)
schema.add_field("audio_url", DataType.VARCHAR, max_length=4096)   # Audio input field
schema.add_field("transcript", DataType.VARCHAR, max_length=4096)  # Transcription output field
# A collection must contain at least one vector field. This step does not perform vector retrieval,
# so a 2-dimensional placeholder field is used to satisfy the constraint;
# after it is declared as nullable=True, you no longer need to pass this field on insert.
schema.add_field("dummy_vector", DataType.FLOAT_VECTOR, dim=2, nullable=True)
schema.add_function(
    Function(
        name="transcribe_audio",
        function_type=texttransform_function_type(),
        input_field_names=["audio_url"],
        output_field_names=["transcript"],
        params={
            "provider": "aliyun_milvus",
            "model_name": "qwen3-asr-flash",
            "task": "ai_audio_transcribe",
            "language": "zh",
            "enable_itn": "true",     # Normalizes spoken numbers, for example "one three eight" becomes 138
        },
    )
)

index_params = client.prepare_index_params()
index_params.add_index(field_name="dummy_vector", index_type="AUTOINDEX", metric_type="COSINE")
client.create_collection(collection_name=collection_name, schema=schema,
                        index_params=index_params)

# audio_url must be a real address that the server side can download from; in production, use a short-lived signed URL from your own OSS bucket
audio_urls = [
    "https://<your-bucket>.oss-cn-hangzhou.aliyuncs.com/calls/call_0001.mp3",
    "https://<your-bucket>.oss-cn-hangzhou.aliyuncs.com/calls/call_0002.wav",
]
client.insert(collection_name, [{"audio_url": u} for u in audio_urls])
client.flush(collection_name)

for row in client.query(collection_name, filter="",
                       output_fields=["audio_url", "transcript"], limit=10):
    print(f"{row['audio_url'].split('/')[-1]} -> {row['transcript']}")

O enable_itn ativa a normalização inversa de texto, que converte leituras coloquiais de números na forma escrita padrão, facilitando a recuperação e o processamento estruturado subsequentes.

Nota

Uma coleção deve conter pelo menos um campo vetorial; caso contrário, a criação da coleção relata schema does not contain vector field. Esta etapa não executa recuperação vetorial, portanto, um campo de espaço reservado bidimensional é usado para satisfazer a restrição. Após ser declarado como nullable=True, você não precisa mais passar esse campo no insert. Se o nullable não for adicionado, omitir esse campo relata Insert missed an field dummy_vector.

Etapa 2: Mascaramento de PII

O texto transcrito geralmente contém informações pessoais sensíveis, como números de celular, números de documentos de identidade e números de cartão bancário. Conclua o mascaramento antes de o texto entrar na base de conhecimento ou no banco de dados de análise, antecipando a conformidade no pipeline em vez de deixá-la para o final. São fornecidos dois usos: a API REST em tempo real e uma coleção no momento da escrita.

# ==================== Step 2: AI_PII_MASK masking ====================
# 2.1 REST real-time API: mask text before it is ingested
status, data = post_json(
    "/v2/vectordb/ai/pii_mask",
    {
        "model_name": "qwen3.7-max",
        "texts": ["Hello, my mobile phone number is 13812345678 and my ID card number is 110101199003071234. Please help me check my ticket."],
        "params": {
            "pii_types": ["PERSON", "PHONE", "ID_CARD"],
            "mask_char": "*",
            "preserve_length": True,   # Keep the original length after masking
            "temperature": 0,
        },
    },
)
assert status == 200 and data.get("code") == 0, data
for item in data["data"]["output"]["outputs"]:
    print(item)

# 2.2 Write-time collection: the masked field is automatically generated when content is ingested
collection_name = "cs_pii_mask"
if client.has_collection(collection_name):
    client.drop_collection(collection_name)

schema = MilvusClient.create_schema(auto_id=True, enable_dynamic_field=False)
schema.add_field("id", DataType.INT64, is_primary=True)
schema.add_field("content", DataType.VARCHAR, max_length=4096)
schema.add_field("masked", DataType.VARCHAR, max_length=4096)
schema.add_field("dummy_vector", DataType.FLOAT_VECTOR, dim=2, nullable=True)
schema.add_function(
    Function(
        name="mask_pii",
        function_type=texttransform_function_type(),
        input_field_names=["content"],
        output_field_names=["masked"],
        params={
            "provider": "aliyun_milvus",
            "model_name": "qwen3.7-max",
            "task": "ai_pii_mask",
            "pii_types": "PERSON,PHONE,ID_CARD",
            "mask_char": "*",
            "preserve_length": "true",
            "temperature": "0",
        },
    )
)
index_params = client.prepare_index_params()
index_params.add_index(field_name="dummy_vector", index_type="AUTOINDEX", metric_type="COSINE")
client.create_collection(collection_name=collection_name, schema=schema,
                        index_params=index_params)

client.insert(collection_name,
              [{"content": "Hello, my mobile phone number is 13812345678. Please help me check my ticket."}])
client.flush(collection_name)
for row in client.query(collection_name, filter="", output_fields=["masked"], limit=1):
    print(row["masked"])

Quando o preserve_length é true, o comprimento original de caracteres é preservado após o mascaramento, o que retém as características de formato sem expor os valores originais. Saída real:

Hello, my mobile phone number is *********** and my ID card number is ******************. Please help me check my ticket.

O número de celular de 11 dígitos é mascarado com 11 asteriscos, e o número do documento de identidade de 18 dígitos é mascarado com 18 asteriscos. A diferença entre os dois usos é: a API REST em tempo real é adequada para processamento único antes do fluxo de entrada de dados, enquanto a coleção no momento da escrita é ideal para reter o resultado mascarado junto com o texto original para auditoria.

Etapa 3: Construa a base de conhecimento de FAQ

Escreva as perguntas de FAQ e as respostas padrão em uma coleção. O AI_EMBEDDING executa a vetorização automaticamente na escrita, portanto, o lado da aplicação não precisa chamar um modelo de embedding primeiro.

# ==================== Step 3: AI_EMBEDDING builds the FAQ knowledge base ====================
collection_name = "cs_faq_kb"
if client.has_collection(collection_name):
    client.drop_collection(collection_name)

schema = MilvusClient.create_schema(auto_id=True, enable_dynamic_field=False)
schema.add_field("id", DataType.INT64, is_primary=True)
schema.add_field("content", DataType.VARCHAR, max_length=4096)   # FAQ question text
schema.add_field("answer", DataType.VARCHAR, max_length=4096)    # Standard answer
schema.add_field("embedding", DataType.FLOAT_VECTOR, dim=1024)
schema.add_function(
    Function(
        name="embed_content",
        function_type=FunctionType.TEXTEMBEDDING,
        input_field_names=["content"],
        output_field_names=["embedding"],
        params={
            "provider": "aliyun_milvus",
            "model_name": "text-embedding-v4",
            "dim": 1024,
            "max_client_batch_size": 10,
            "max_concurrency": 1,
        },
    )
)
index_params = client.prepare_index_params()
index_params.add_index(
    field_name="embedding",
    index_type="HNSW",
    metric_type="COSINE",
    params={"M": 16, "efConstruction": 200},
)
client.create_collection(collection_name=collection_name, schema=schema,
                        index_params=index_params)

faqs = [
    {"content": "How do I enable Internet access for a Serverless Milvus instance?",
     "answer": "Enable Internet access and configure the whitelist on the instance details page in the console."},
    {"content": "What should I do if I forget my console logon password?", "answer": "Reset it through the password retrieval process in Account Center."},
    {"content": "Why is my bill higher than expected?", "answer": "Check the usage details, focusing on compute and storage usage."},
    {"content": "How do I create a collection and write vectors?",
     "answer": "Use create_collection to define the schema and then insert."},
    {"content": "Does scaling up an instance affect online business?", "answer": "Scaling is an online operation and usually does not interrupt services."},
]
client.insert(collection_name, faqs)
client.flush(collection_name)
client.load_collection(collection_name)
Nota

Este exemplo usa o text-embedding-v4 (que suporta vários idiomas e dimensões personalizadas). O AI center também fornece modelos como o qwen3.7-text-embedding. Para isso, visualize os modelos disponíveis no momento e suas dimensões na guia Model Service do AI Center no console e selecione um modelo com base no seu idioma e nos requisitos de efeito. O dim do campo vetorial deve ser consistente com o dim nos parâmetros da Function.

Etapas 4 e 5: Recuperação semântica e reranking de modelo grande

A pergunta coloquial de um usuário passa primeiro pela recuperação vetorial para recordar os candidatos Top-N e, em seguida, um modelo de reranking executa uma classificação de granularidade fina pela relevância real em relação à consulta. Somente as duas etapas combinadas podem atingir o FAQ padrão de forma confiável.

# ==================== Step 4: Semantic retrieval to recall FAQs ====================
query = "How can I make my instance reachable from the Internet?"
result = client.search(
    collection_name="cs_faq_kb",
    data=[query],
    anns_field="embedding",
    limit=3,
    output_fields=["content", "answer"],
)
for rank, hit in enumerate(result[0], 1):
    print(f"{rank}. [similarity {hit['distance']:.4f}] {hit['entity']['content']}")

# ==================== Step 5: AI_RERANK reranking ====================
# 5.1 REST real-time API: independently rerank a given batch of candidates
status, data = post_json(
    "/v2/vectordb/ai/rerank",
    {
        "model_name": "qwen3-rerank",
        "query": query,
        "documents": [
            "How do I enable Internet access for a Serverless Milvus instance?",
            "Does scaling up an instance affect online business?",
            "How do I create a collection and write vectors?",
        ],
        "params": {"max_concurrency": 2, "timeout_sec": 10},
    },
)
assert status == 200 and data.get("code") == 0, data
ranked = sorted(data["data"]["output"]["results"],
                key=lambda x: x["relevance_score"], reverse=True)
for rank, item in enumerate(ranked, 1):
    print(f"{rank}. [relevance {item['relevance_score']:.4f}] candidate index={item['index']}")

# 5.2 Attach a ranker during search to complete recall and reranking in one call
reranker = Function(
    name="rerank_faq",
    function_type=FunctionType.RERANK,
    input_field_names=["content"],
    params={
        "reranker": "model",
        "provider": "aliyun_milvus",
        "model_name": "qwen3-rerank",
        "queries": [query],
        "max_concurrency": 2,
        "timeout_sec": 10,
    },
)
result = client.search(
    collection_name="cs_faq_kb",
    data=[query],
    anns_field="embedding",
    limit=3,
    output_fields=["content", "answer"],
    ranker=reranker,
)
for rank, hit in enumerate(result[0], 1):
    e = hit["entity"]
    print(f"{rank}. [rerank score {hit['distance']:.4f}] {e['content']} | answer: {e['answer']}")

Tome como exemplo a consulta "How can I make my instance reachable from the Internet?". Os dados medidos são os seguintes. Esta comparação de antes e depois ilustra claramente o valor do reranking:

FAQ candidato

Etapa 4: recuperação vetorial

Etapa 5: após o reranking

How do I enable Internet access for a Serverless Milvus instance?

① 0,6141

① 0,5883

What should I do if I forget my console logon password?

② 0,5613

③ 0,2607

Does scaling up an instance affect online business?

③ 0,4757

② 0,3356

A recuperação vetorial classificou "What should I do if I forget my console logon password?" em segundo lugar (0,5613), mas não é relevante em intenção para "torná-la acessível pela Internet". Este é exatamente o comportamento típico da recuperação puramente vetorial ser "recuperada, mas não precisa": a similaridade superficial do texto não é baixa, mas a intenção real está distante. Após o reranking, esta entrada é empurrada para o terceiro lugar (0,2607), e a entrada semanticamente mais próxima de "dimensionamento de instância" sobe para o segundo lugar. Para um bot de atendimento ao cliente, a precisão do Top-1 determina diretamente a qualidade da resposta, portanto, a etapa de reranking não deve ser omitida.

Nota

A diferença entre os dois usos de reranking: a API REST em tempo real é adequada para cenários em que você já tem a lista de candidatos e precisa apenas do reranking; anexar um ranker no search mescla a recuperação e a classificação de granularidade fina em uma única chamada, encurtando o pipeline. A API REST não suporta top_n e retorna uma pontuação para cada candidato. Se você precisar de truncamento, classifique por pontuação no lado da aplicação e pegue você mesmo as N principais entradas.

Nota

O reranking de texto puro não exige o parâmetro is_multimodal. Esse parâmetro é necessário apenas para reranking multimodal (usando o qwen3-vl-rerank para pontuar candidatos de imagem e vídeo). Passá-lo para candidatos de texto puro não altera os resultados de pontuação.

Etapa 6: Reconhecimento de sentimento e classificação de chamados

Anexe duas Functions ao texto da conversa mascarada ao mesmo tempo: uma determina a tendência de sentimento para inspeção de qualidade e alerta de opinião pública, e a outra classifica a conversa em uma categoria de chamado para roteamento automático. Ambas são concluídas automaticamente na escrita.

# ==================== Step 6: AI_SENTIMENT sentiment recognition + AI_CLASSIFY ticket classification ====================
collection_name = "cs_qc"
if client.has_collection(collection_name):
    client.drop_collection(collection_name)

schema = MilvusClient.create_schema(auto_id=True, enable_dynamic_field=False)
schema.add_field("id", DataType.INT64, is_primary=True)
schema.add_field("content", DataType.VARCHAR, max_length=4096)     # Masked conversation text
schema.add_field("sentiment", DataType.VARCHAR, max_length=64)     # Sentiment output
schema.add_field("category", DataType.VARCHAR, max_length=64)      # Ticket category output
schema.add_field("dummy_vector", DataType.FLOAT_VECTOR, dim=2, nullable=True)
schema.add_function(
    Function(
        name="analyze_sentiment",
        function_type=texttransform_function_type(),
        input_field_names=["content"], output_field_names=["sentiment"],
        params={"provider": "aliyun_milvus", "model_name": "qwen3.7-max",
                "task": "ai_sentiment", "categories": "positive,negative,neutral",
                "temperature": "0"},
    )
)
schema.add_function(
    Function(
        name="classify_ticket",
        function_type=texttransform_function_type(),
        input_field_names=["content"], output_field_names=["category"],
        params={"provider": "aliyun_milvus", "model_name": "qwen3.7-max",
                "task": "ai_classify", "labels": "Account,Inquiry,Fault,Billing",
                "prompt": "Classify based on the topic that the customer question belongs to.", "temperature": "0"},
    )
)
index_params = client.prepare_index_params()
index_params.add_index(field_name="dummy_vector", index_type="AUTOINDEX", metric_type="COSINE")
client.create_collection(collection_name=collection_name, schema=schema,
                        index_params=index_params)

client.insert(collection_name, [
    {"content": "I have already called three times about this problem of yours, and it still has not been resolved. This is so disappointing!"},
    {"content": "How do I enable Internet access for a Serverless Milvus instance?"},
])
client.flush(collection_name)
for row in client.query(collection_name, filter="",
                        output_fields=["content", "sentiment", "category"], limit=10):
    print(f"sentiment={row['sentiment']:<10} category={row['category']:<6} | {row['content'][:28]}")

Resultados medidos:

Texto da conversa

Sentimento

Categoria do chamado

I have already called three times about this problem of yours, and it still has not been resolved. This is so disappointing!

negative

Fault

How do I enable Internet access for a Serverless Milvus instance?

neutral

Inquiry

Várias Functions podem ser anexadas a uma única coleção, desde que seus campos de saída não entrem em conflito. Neste exemplo, sentiment e category são preenchidos por uma das duas Functions, portanto, escrever um único registro gera tanto o rótulo de sentimento quanto a categoria do chamado.

Aviso

Os resultados de sentimento e classificação são julgamentos do modelo, e não determinações factuais. Mantenha uma etapa de revisão manual antes de ações de alto impacto, como escalonamento de chamados ou deslistagem de service.

Valor da solução

Dimensão

Solução tradicional (ASR + banco de dados vetorial + NLP + service de reranking)

Alibaba Cloud Milvus

Número de sistemas

4 ou mais, com dados trafegando entre vários lugares

1, com dados nunca saindo da instância

Transcrição de áudio

O lado da aplicação chama o ASR primeiro e depois escreve no banco de dados

Transcrição na escrita

Pipeline de vetorização

O lado da aplicação chama o embedding e depois escreve

Vetorização na escrita

Mascaramento de PII

Frequentemente colocado no final do pipeline e facilmente omitido

Mascaramento na ingestão, com a conformidade antecipada

Recuperação e reranking

Exige a implantação de um service de modelo de reranking adicional

O AI_RERANK é integrado e pode ser concluído em um único search

Sentimento e classificação

Exige uma plataforma externa de NLP

O AI_SENTIMENT / AI_CLASSIFY são integrados

Os cenários que podem ser estendidos incluem:

  • Assistência ao agente em tempo real: Integre a recuperação e o reranking à bancada do agente para enviar os scripts e conhecimentos mais adequados enquanto a chamada está em andamento.

  • Inspeção de qualidade em lote: As gravações históricas podem ser combinadas com o AI_BATCH para transcrição offline de volume total, mascaramento e rotulagem de classificação de sentimento, elevando a cobertura da inspeção de qualidade de amostragem para volume total.

  • Alerta de opinião pública: Acione processos de alerta e escalonamento em tempo real para chamados cuja saída do AI_SENTIMENT seja negative.

Considerações de conformidade

  • Certifique-se de concluir a notificação de gravação e autorização do cliente antes de processar as gravações.

  • Use sempre URLs assinadas de curta duração com privilégio mínimo para mídias e não incorpore credenciais de longo prazo nas URLs.

  • É obrigatório que você defina períodos de retenção explícitos para áudio bruto, texto transcrito, rótulos de sentimento e registros de revisão, e exclua ou anonimize-os após o vencimento. Garanta também que os dados derivados sejam descartados em sincronia com a exclusão dos dados de source ou a retirada da autorização.

  • Os resultados de sentimento e classificação são julgamentos do modelo, e não determinações factuais. Mantenha uma etapa de revisão manual antes de ações de alto impacto, como deslistagem ou escalonamento.