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

推荐订阅源

Recorded Future
Recorded Future
小众软件
小众软件
C
Check Point Blog
MyScale Blog
MyScale Blog
V
Visual Studio Blog
博客园_首页
J
Java Code Geeks
人人都是产品经理
人人都是产品经理
腾讯CDC
云风的 BLOG
云风的 BLOG
爱范儿
爱范儿
量子位
N
Netflix TechBlog - Medium
宝玉的分享
宝玉的分享
博客园 - 叶小钗
H
Help Net Security
T
The Blog of Author Tim Ferriss
月光博客
月光博客
博客园 - 三生石上(FineUI控件)
P
Proofpoint News Feed
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
WordPress大学
WordPress大学
美团技术团队
有赞技术团队
有赞技术团队
Microsoft Azure Blog
Microsoft Azure Blog
IT之家
IT之家
M
MIT News - Artificial intelligence
S
Secure Thoughts
U
Unit 42
Google Online Security Blog
Google Online Security Blog
L
LINUX DO - 最新话题
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
Recent Announcements
Recent Announcements
F
Full Disclosure
The GitHub Blog
The GitHub Blog
V2EX - 技术
V2EX - 技术
D
DataBreaches.Net
Webroot Blog
Webroot Blog
Y
Y Combinator Blog
The Last Watchdog
The Last Watchdog
aimingoo的专栏
aimingoo的专栏
W
WeLiveSecurity
Blog — PlanetScale
Blog — PlanetScale
博客园 - 聂微东
Martin Fowler
Martin Fowler
阮一峰的网络日志
阮一峰的网络日志
cs.AI updates on arXiv.org
cs.AI updates on arXiv.org
V
V2EX
T
Tailwind CSS Blog
Application and Cybersecurity Blog
Application and Cybersecurity Blog

博客园 - 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 : 原创博客请在转载时保留原文链接或在文章开头加上本人博客地址,否则保留追究法律责任的权利。