La fonction AI_SIMILARITY compare la similarité sémantique de deux segments de texte et retourne un score compris entre 0 et 1. Utilisez cette fonction pour des cas d'usage tels que l'identification de tickets en double, la déduplication des questions-réponses ou le rapprochement de produits similaires.
Prérequis
Une instance Milvus avec son URL d'endpoint et ses identifiants d'authentification.
Un modèle de texte configuré, tel que
qwen3.7-max.(Pour Python) PyMilvus installé.
Format de la commande
La fonction AI_SIMILARITY prend en charge deux modes d'utilisation :
Interface REST — Envoyez une requête API directe pour comparer des paires de textes à la demande.
Fonction de collection — Définissez une fonction dans le schéma de la collection pour calculer automatiquement la similarité lors de l'insertion des données.
Interface REST
Interface REST
@id="c0043k7q2t43"
POST /v2/vectordb/ai/similarity
Content-Type: application/json
{
"model_name": "<model_name>",
"texts": ["<text_A>", "<text_B>"],
"params": {}
}
@id="cmdpysecsim01"
@id="cmdpyhsim0001"
Python
Python
@id="cmdpycodsim01"
schema = MilvusClient.create_schema(auto_id=True, enable_dynamic_field=False)
schema.add_field("id", DataType.INT64, is_primary=True)
schema.add_field("left_text", DataType.VARCHAR, max_length=4096)
schema.add_field("right_text", DataType.VARCHAR, max_length=4096)
schema.add_field("similarity", DataType.DOUBLE)
schema.add_field("dummy_vector", DataType.FLOAT_VECTOR, dim=2)
schema.add_function(
Function(
name="compare_texts",
function_type=texttransform_function_type(),
input_field_names=["left_text", "right_text"],
output_field_names=["similarity"],
params={
"provider": "aliyun_milvus",
"model_name": "<model_name>",
"task": "ai_similarity",
"temperature": "0",
},
)
)
Paramètres
| @id="p0050k7q2t50" Paramètre | @id="p0052k7q2t52" Description |
@id="p0003k7q2t03" model_name |
@id="p0005k7q2t05" Obligatoire. Nom du modèle de texte configuré. L'interface REST accepte également model. |
@id="p0008k7q2t08" texts |
@id="p0010k7q2t10" Obligatoire pour l'interface REST. La longueur doit être paire. [A,B,C,D] correspond à la comparaison des paires (A,B) et (C,D). |
@id="p0013k7q2t13" temperature |
@id="p0015k7q2t15" Facultatif. Définissez cette valeur à 0 pour obtenir un score plus stable. |
@id="p0018k7q2t18" max_concurrency/timeout_sec |
@id="p0020k7q2t20" Facultatif. Contrôle la concurrence et le délai d'expiration d'un appel unique. |
@id="p0023k7q2t23" provider/task |
@id="p0025k7q2t25" Obligatoire uniquement pour la fonction de collection. Valeurs fixes : aliyun_milvus et ai_similarity. |
Valeur de retour
Le nombre d'éléments dans data.output.outputs correspond au nombre de paires de textes. Chaque élément est une chaîne représentant un score. Lors de l'écriture dans une collection, ce score est interprété comme un type FLOAT ou DOUBLE. Les valeurs non analysables ou hors de l'intervalle 0–1 sont enregistrées sous la forme 0.
Exemple d'utilisation : identification des demandes de support client en double
Un système de support client doit déterminer si deux questions peuvent être traitées conjointement. L'exemple suivant utilise l'interface REST pour comparer deux paires de textes, ainsi que la fonction de collection pour calculer la similarité lors de l'insertion des données.
Interface REST
Interface REST
Avant d'exécuter le script, remplacez les espaces réservés MILVUS_REST_BASE_URL et MILVUS_AUTH_TOKEN par l'endpoint réel du cluster et vos identifiants.
@id="c0062k7q2t62"
#!/usr/bin/env bash
set -euo pipefail
MILVUS_REST_BASE_URL="http://c-xxxx.milvus.aliyuncs.com:19530"
MILVUS_AUTH_TOKEN="<yourUsername>:<yourPassword>"
post_json() {
local path="$1"
local body="$2"
curl -X POST \
"$MILVUS_REST_BASE_URL$path" \
-H "Authorization: Bearer $MILVUS_AUTH_TOKEN" \
-H "Content-Type: application/json" \
-d "$body"
}
MODEL_NAME="qwen3.7-max"
BODY=$(cat <<JSON
{
"model_name": "$MODEL_NAME",
"texts": [
"A cat is a mammal.", "Cats belong to mammals.",
"An apple is a fruit.", "Python is a programming language."
],
"params": {"max_concurrency": 2, "temperature": 0}
}
JSON
)
RESPONSE_BODY="$(post_json "/v2/vectordb/ai/similarity" "$BODY")"
if command -v jq >/dev/null 2>&1; then
echo "$RESPONSE_BODY" | jq .
[ "$(echo "$RESPONSE_BODY" | jq -r '.code // -1')" = "0" ] || exit 1
else
echo "$RESPONSE_BODY"
fi
# Expected: number of outputs equals number of text pairs, e.g., ["1","0.0"] (similar pairs score high, dissimilar pairs close to 0)
@id="pt0063k7q2t63"
@id="h0064k7q2t64"
Python
Python
@id="p0065k7q2t65"
Après avoir installé PyMilvus, remplacez les espaces réservés MILVUS_URI et MILVUS_TOKEN par l'adresse réelle du cluster et votre token avant l'exécution. Cet exemple inclut des fonctions utilitaires courantes intégrées directement dans le code.
@id="c0066k7q2t66"
from __future__ import annotations
from typing import Any
from pymilvus import DataType, Function, FunctionType, MilvusClient
MILVUS_URI = "http://c-xxxx.milvus.aliyuncs.com:19530"
MILVUS_TOKEN = "<yourUsername>:<yourPassword>"
DUMMY_VECTOR_DIM = 2
TEXTTRANSFORM_FUNCTION_TYPE = 9
def texttransform_function_type() -> Any:
for type_name in ("TEXTTRANSFORM", "TEXT_TRANSFORM", "TextTransform"):
function_type = getattr(FunctionType, type_name, None)
if function_type is not None:
return function_type
# Alibaba Cloud Milvus provides TEXTTRANSFORM as a managed extension (function type value 9);
# some pymilvus versions do not include this enum member yet, and Function(...) validates through FunctionType(...).
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 add_id(schema: Any) -> None:
schema.add_field("id", DataType.INT64, is_primary=True)
def add_dummy_vector(schema: Any) -> None:
schema.add_field("dummy_vector", DataType.FLOAT_VECTOR, dim=DUMMY_VECTOR_DIM)
def run_texttransform_example(*, client, collection_name, input_fields, output_field, function_name, function_params, rows) -> None:
if client.has_collection(collection_name):
client.drop_collection(collection_name)
schema = MilvusClient.create_schema(auto_id=True, enable_dynamic_field=False)
add_id(schema)
for name, data_type, max_length in input_fields:
field_params = {"max_length": max_length} if max_length is not None else {}
schema.add_field(name, data_type, **field_params)
output_name, output_data_type, output_max_length = output_field
output_params = {"max_length": output_max_length} if output_max_length is not None else {}
schema.add_field(output_name, output_data_type, **output_params)
add_dummy_vector(schema)
schema.add_function(
Function(
name=function_name,
function_type=texttransform_function_type(),
input_field_names=[name for name, _, _ in input_fields],
output_field_names=[output_name],
params=function_params,
)
)
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, rows)
client.flush(collection_name)
fields = [name for name, _, _ in input_fields] + [output_name]
for row in client.query(collection_name, filter="", output_fields=fields, limit=len(rows)):
print(row)
MODEL_NAME = "qwen3.7-max"
client = MilvusClient(uri=MILVUS_URI, token=MILVUS_TOKEN)
run_texttransform_example(
client=client,
collection_name="simple_ai_similarity",
input_fields=[("left_text", DataType.VARCHAR, 4096), ("right_text", DataType.VARCHAR, 4096)],
output_field=("similarity", DataType.DOUBLE, None),
function_name="compare_texts",
function_params={"provider": "aliyun_milvus", "model_name": MODEL_NAME, "task": "ai_similarity", "temperature": "0"},
rows=[{"left_text": "A cat is a mammal.", "right_text": "Cats belong to mammals.", "dummy_vector": [0.1, 0.2]}],
)
# Expected: similarity receives a score close to 1 (highly similar)
Les paires similaires (comme l'exemple chat/mammifère) obtiennent un score proche de 1, tandis que les paires dissemblables reçoivent un score voisin de 0. Dirigez les questions dont le score dépasse 0.85 vers la même file de traitement.