惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

C
Cyber Attacks, Cyber Crime and Cyber Security
N
News and Events Feed by Topic
Schneier on Security
Schneier on Security
Forbes - Security
Forbes - Security
Webroot Blog
Webroot Blog
PCI Perspectives
PCI Perspectives
www.infosecurity-magazine.com
www.infosecurity-magazine.com
A
Arctic Wolf
Google Online Security Blog
Google Online Security Blog
T
Troy Hunt's Blog
T
Tenable Blog
L
Lohrmann on Cybersecurity
C
Cisco Blogs
罗磊的独立博客
Exploit-DB.com RSS Feed
Exploit-DB.com RSS Feed
T
Threat Research - Cisco Blogs
Attack and Defense Labs
Attack and Defense Labs
T
The Exploit Database - CXSecurity.com
有赞技术团队
有赞技术团队
V2EX - 技术
V2EX - 技术
GbyAI
GbyAI
P
Proofpoint News Feed
雷峰网
雷峰网
Cisco Talos Blog
Cisco Talos Blog
Hacker News - Newest:
Hacker News - Newest: "LLM"
Cloudbric
Cloudbric
K
Kaspersky official blog
C
CXSECURITY Database RSS Feed - CXSecurity.com
S
Securelist
M
MIT News - Artificial intelligence
H
Heimdal Security Blog
Vercel News
Vercel News
S
SegmentFault 最新的问题
U
Unit 42
Help Net Security
Help Net Security
S
Schneier on Security
人人都是产品经理
人人都是产品经理
爱范儿
爱范儿
Microsoft Azure Blog
Microsoft Azure Blog
H
Hackread – Cybersecurity News, Data Breaches, AI and More
cs.CV updates on arXiv.org
cs.CV updates on arXiv.org
T
Threatpost
I
Intezer
cs.AI updates on arXiv.org
cs.AI updates on arXiv.org
P
Palo Alto Networks Blog
Application and Cybersecurity Blog
Application and Cybersecurity Blog
博客园 - 三生石上(FineUI控件)
J
Java Code Geeks
宝玉的分享
宝玉的分享
Latest news
Latest news

博客园 - Yaopengfei

第五节:Claude Code的用法实操汇总 第十五节:LlamaIndex框架使用2() 第十四节:LlamaIndex框架介绍和入门1(基本用法、提示词、节点等) 第三节:Trae的基本使用 和 Skill的详细用法 第二节:Python基础2 第十三节:FastApi入门以及AI智能体案例落地实操 第二节:GitHub Copilot 用法(基于VSCode/VS、添加DeepSeek/千问等任意模型) 第一节:AI工具总览(Copilot、Cursor、Claude Code、OpenCode、Codex、Trae等) 第一节:Python基础1(数据类型、命名规范、输入输出、运算符、类型转换等) 第十节:预检索-索引优化(摘要、父子、假设问题、元数据、混合索引) 第十二节:MinerU处理复制PDF 和 综合性金融案例实战 第十一节:多检索查询、混合检索(多检索+RRF重排)、检索后优化(文档压缩) 第九节:RAG进阶和Advanced RAG简介 博文阅读密码验证 - 博客园 第七节:LangChain框架Chain链和Agent代理详解 第六节:LangChain框架Model和数据检索详解 第五节:LangChain框架简介和快速入门(模型、模板、解释器、向量、RAG、代理) 第四节:补充pip相关指令大全 第三节:RAG基础(概念、工作流程、文档分块、向量和Embedding、RAG案例等等) 博文阅读密码验证 - 博客园 第一节:Python相关环境安装和配置(Python、PyCharm、Anaconda) 第三十六节:EFCore10.0新增功能和中断性变更 第七节:框架版本大升级(CoreMvc10.x + EFCore10.x) 第五十二节:Core10.0中OpenApi自定义文档(Swagger) 博文阅读密码验证 - 博客园 第三节:C#13、C#14新语法(数字字符串比较、Null分配、扩展成员新写法等等)
第二节:如何理解Embedding以及基于内存库简单实操
Yaopengfei · 2026-01-21 · via 博客园 - Yaopengfei

一.  说明

  Embedding可以理解为将一个内容进行向量化,便于比较相似度

  这里使用的是阿里千问的“text-embedding-v4”模型

二. 实操

 (1) 先将一些内容向量化,存入库中,这里使用list集合代替,其中key为原内容,value为调用embedding接口后的内容

 (2) 输入一个内容,同样调用embedding接口获取向量结果

 (3) 去库中逐个比对相似度,比对方法使用封装的CalculateCosineSimilarity

 (4) 获取相似度前三的内容,进行输出

代码分享:


Console.WriteLine("=== Embedding Similarity Demo ===\n");

var apiKey = "sk-xxx";
var endpoint = "https://dashscope.aliyuncs.com/compatible-mode/v1/";
var model = "text-embedding-v4";
var embeddingClient = new OpenAIClient(
                        new ApiKeyCredential(apiKey),
                        new OpenAIClientOptions { Endpoint = new Uri(endpoint) }
                       ).GetEmbeddingClient(model);


// 1.一些不同的主题
var sampleTexts = new[]
{
    "C# is a popular programming language for data science and machine learning.",
    "I love cooking Italian pasta with fresh tomatoes and basil.",
    "The football match was exciting, with the final score being 3-2.",
    "Machine learning algorithms can identify patterns in large datasets.",
    "The recipe calls for two cups of flour and three eggs.",
    "Basketball requires good coordination and teamwork skills.",
    "Neural networks are inspired by biological brain structures.",
    "Baking bread at home requires patience and the right temperature.",
    "The soccer team won the championship after months of training.",
    "Deep learning has revolutionized computer vision and natural language processing."
};
Console.WriteLine("Generating embeddings for sample texts...\n");

// 2.将上面的text进行embedding,将原text和embedding后的结果存放到List中
var textEmbeddings = new List<(string text, float[] embedding)>();
int count = 1;
foreach (var text in sampleTexts)
{
    ClientResult<OpenAIEmbedding> embeddingResult = await embeddingClient.GenerateEmbeddingAsync(text);
    float[] embedding = embeddingResult.Value.ToFloats().ToArray();
    textEmbeddings.Add((text, embedding));
    Console.WriteLine($"{count}:{text}");
    count++;
}
Console.WriteLine($"\nStored {textEmbeddings.Count} text embeddings (dimension: {textEmbeddings[0].embedding.Length})\n");


//3. 自己输入一个内容,寻找库中相似度前三的内容
while (true)
{
    Console.WriteLine("\n" + new string('-', 70));
    Console.Write("Enter your query (or 'quit' to exit): ");
    var query = Console.ReadLine();
    if (string.IsNullOrWhiteSpace(query) || query.ToLower() == "quit")
    {
        Console.WriteLine("Goodbye!");
        break;
    }

    Console.WriteLine($"\nSearching for: \"{query}\"");
    Console.WriteLine("Generating query embedding...");

    //3.1 计算输入内容的embedding
    var queryEmbeddingResult = await embeddingClient.GenerateEmbeddingAsync(query);
    var queryEmbedding = queryEmbeddingResult.Value.ToFloats().ToArray();
    Console.WriteLine(queryEmbedding.Length);
    Console.WriteLine(string.Join(',', queryEmbedding));


    //3.2 去库中进行相似度的匹配
    //利用CalculateCosineSimilarity方法循环匹配
    var similarities = new List<(string text, double similarity)>();
    foreach (var (text, embedding) in textEmbeddings)
    {
        double similarity = CalculateCosineSimilarity(queryEmbedding, embedding);   //计算相似度
        similarities.Add((text, similarity));
    }

    //3.3 找出相似度前三的,输出
    var topResults = similarities.OrderByDescending(x => x.similarity).Take(3).ToList();
    Console.WriteLine("\nTop 3 Most Similar Texts:");
    Console.WriteLine(new string('=', 70));

    for (int i = 0; i < topResults.Count; i++)
    {
        var (text, similarity) = topResults[i];
        Console.WriteLine($"\n{i + 1}. Similarity: {similarity:F4} ({similarity * 100:F2}%)");
        Console.WriteLine($"   Text: {text}");
    }
}

//比对向量相似度方法
static double CalculateCosineSimilarity(float[] vector1, float[] vector2)
{
    if (vector1.Length != vector2.Length)
    {
        throw new ArgumentException("Vectors must have the same dimension");
    }
    double dotProduct = 0;
    double magnitude1 = 0;
    double magnitude2 = 0;
    for (int i = 0; i < vector1.Length; i++)
    {
        dotProduct += vector1[i] * vector2[i];
        magnitude1 += vector1[i] * vector1[i];
        magnitude2 += vector2[i] * vector2[i];
    }
    magnitude1 = Math.Sqrt(magnitude1);
    magnitude2 = Math.Sqrt(magnitude2);
    if (magnitude1 == 0 || magnitude2 == 0)
    {
        return 0;
    }
    return dotProduct / (magnitude1 * magnitude2);
}

!

  • 作       者 : Yaopengfei(姚鹏飞)
  • 博客地址 : http://www.cnblogs.com/yaopengfei/
  • 声     明1 : 如有错误,欢迎讨论,请勿谩骂^_^。
  • 声     明2 : 原创博客请在转载时保留原文链接或在文章开头加上本人博客地址,否则保留追究法律责任的权利。