MoneyTree.AI 1.0.4

MoneyTree.AI 人工智能集成

📋 概述

MoneyTree.AI 是 MoneyTree 框架的 AI 集成模块,基于 Microsoft.Extensions.AI 抽象层封装,提供大语言模型对话、文本向量嵌入、RAG(检索增强生成)等 AI 能力。支持 OpenAI、DeepSeek、Ollama 等多种 LLM 提供商。

属性 说明
NuGet 包 MoneyTree.AI
外部依赖 MoneyTree.CoreMoneyTree.EFCore.VectorStoreMicrosoft.Extensions.AIOllamaSharp
定位 AI 能力集成与桥接
支持的 LLM OpenAI / DeepSeek / Ollama / 兼容 OpenAI 格式的任意模型

🏗️ 项目文件结构

MoneyTree.AI/
├── MoneyTree.AI.csproj
├── GlobalUsings.cs
├── Core/
│   ├── ChatService.cs              # 封装 IChatClient,提供同步和流式对话
│   ├── EmbeddingService.cs         # 封装 IEmbeddingGenerator,文本转向量
│   └── RagService.cs               # RAG 核心逻辑,依赖 IVectorStore 和 IEmbeddingGenerator
└── Extensions/
    └── AIExtensions.cs             # DI 注册扩展,提供 AddMoneyTreeAI 方法

🚀 快速开始

使用 Ollama 本地模型

// Program.cs
using MoneyTree.AI.Extensions;

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddMoneyTreeAI(options =>
{
    options.ProviderType = AIProviderType.Ollama;
    options.Endpoint = "http://localhost:11434";
    options.Model = "qwen2.5";
    options.EmbeddingModel = "nomic-embed-text";
});

var app = builder.Build();
app.Run();

使用 DeepSeek

using MoneyTree.EFCore.Extensions;
using MoneyTree.EFCore.PostgreSql.Extensions;
using MoneyTree.EFCore.VectorStore.Extensions;
using MoneyTree.AI.Extensions;

var builder = WebApplication.CreateBuilder(args);

// 向量存储(使用 PostgreSQL pgvector)
builder.Services.AddMoneyTreeEFCore<AppDbContext>(db =>
{
    db.UsePostgreSql<AppDbContext>("Host=localhost;Database=mydb");
});
builder.Services.AddEFCoreVectorStore<PostgreSqlVectorStore>();

// AI 服务 — DeepSeek
builder.Services.AddMoneyTreeAI(options =>
{
    options.ProviderType = AIProviderType.OpenAI;
    options.Endpoint = "https://api.deepseek.com/v1";
    options.ApiKey = "sk-your-deepseek-api-key";
    options.Model = "deepseek-chat";
    options.EmbeddingModel = "text-embedding-3-small";
});

var app = builder.Build();
app.Run();

使用 OpenAI

builder.Services.AddMoneyTreeAI(options =>
{
    options.ProviderType = AIProviderType.OpenAI;
    options.ApiKey = "sk-your-openai-api-key";
    options.Model = "gpt-4o-mini";
});

💬 核心服务

ChatService — 对话服务

封装 IChatClient,提供同步和流式对话能力:

public class DocumentService
{
    private readonly ChatService _chat;

    public DocumentService(ChatService chat)
    {
        _chat = chat;
    }

    // 简单对话
    public async Task<string> AskAsync(string question)
    {
        return await _chat.ChatAsync(question);
    }

    // 带系统提示的对话
    public async Task<string> AskWithSystemPromptAsync(string question)
    {
        return await _chat.ChatAsync(
            question,
            systemPrompt: "你是一个专业的客服助手,请用中文简洁回答。");
    }

    // 流式对话
    public async IAsyncEnumerable<string> AskStreamingAsync(string question)
    {
        await foreach (var chunk in _chat.ChatStreamingAsync(question))
        {
            yield return chunk;
        }
    }
}

EmbeddingService — 向量嵌入服务

封装 IEmbeddingGenerator,用于文本向量化:

public class DocumentService
{
    private readonly EmbeddingService _embedding;

    public DocumentService(EmbeddingService embedding)
    {
        _embedding = embedding;
    }

    // 生成嵌入向量
    public async Task<float[]> EmbedAsync(string text)
    {
        return await _embedding.GenerateAsync(text);
    }
}

RagService — RAG 检索增强生成

结合向量存储和 LLM 实现知识库问答:

public class DocumentService
{
    private readonly RagService _rag;

    public DocumentService(RagService rag)
    {
        _rag = rag;
    }

    // 索引文档到知识库
    public async Task IndexDocumentAsync(string id, string content)
    {
        await _rag.AddDocumentAsync(id, content, new Dictionary<string, string>
        {
            ["title"] = "产品手册",
            ["category"] = "技术文档"
        });
    }

    // 基于知识库问答
    public async Task<string> AskWithKnowledgeAsync(string question)
    {
        return await _rag.AskAsync(question, topK: 5);
    }

    // 流式知识库问答
    public async IAsyncEnumerable<string> AskWithKnowledgeStreamingAsync(string question)
    {
        await foreach (var chunk in _rag.AskStreamingAsync(question))
        {
            yield return chunk;
        }
    }
}

🌊 SSE 流式响应

将 AI 对话流通过 Server-Sent Events 推送到前端:

// Chat 流式终结点
app.MapGet("/api/ai/chat-stream", async (
    string question,
    ChatService chat,
    HttpResponse response,
    CancellationToken ct) =>
{
    response.ContentType = "text/event-stream";
    response.Headers.Append("Cache-Control", "no-cache");

    await foreach (var chunk in chat.ChatStreamingAsync(question, cancellationToken: ct))
    {
        await response.WriteAsync($"data: {chunk}\n\n", ct);
        await response.Body.FlushAsync(ct);
    }

    await response.WriteAsync("data: [DONE]\n\n", ct);
});

// RAG 流式终结点
app.MapGet("/api/ai/rag-stream", async (
    string question,
    RagService rag,
    HttpResponse response,
    CancellationToken ct) =>
{
    response.ContentType = "text/event-stream";
    response.Headers.Append("Cache-Control", "no-cache");

    await foreach (var chunk in rag.AskStreamingAsync(question, cancellationToken: ct))
    {
        await response.WriteAsync($"data: {chunk}\n\n", ct);
        await response.Body.FlushAsync(ct);
    }

    await response.WriteAsync("data: [DONE]\n\n", ct);
});

🏁 完整启动配置

以下是同时集成数据库、向量存储和 AI 服务的完整启动配置示例:

using MoneyTree.EFCore.Extensions;
using MoneyTree.EFCore.PostgreSql.Extensions;
using MoneyTree.EFCore.VectorStore.Extensions;
using MoneyTree.AI.Extensions;

var builder = WebApplication.CreateBuilder(args);

// 数据库
builder.Services.AddMoneyTreeEFCore<AppDbContext>(db =>
{
    db.UsePostgreSql<AppDbContext>(
        builder.Configuration.GetConnectionString("Default")!);
});

// 向量存储
builder.Services.AddEFCoreVectorStore<PostgreSqlVectorStore>();

// AI 服务
builder.Services.AddMoneyTreeAI(options =>
{
    options.ProviderType = AIProviderType.OpenAI;
    options.Endpoint = "https://api.deepseek.com/v1";
    options.ApiKey = builder.Configuration["AI:ApiKey"]!;
    options.Model = "deepseek-chat";
});

var app = builder.Build();
app.Run();

No packages depend on MoneyTree.AI.

Version Downloads Last updated
1.0.4 1 7/21/2026
1.0.3 1 7/12/2026