Serve

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
using LangChain.Memory;
using LangChain.Providers.Ollama;
using LangChain.Serve;
using LangChain.Serve.Abstractions.Repository;
using Ollama;
using static LangChain.Chains.Chain;
using Message = LangChain.Providers.Message;
using MessageRole = LangChain.Providers.MessageRole;


var builder = WebApplication.CreateBuilder();



// 1. Add LangChainServe
builder.Services.AddLangChainServe();

// 2. Create a model
var provider = new OllamaProvider();
var model = new OllamaChatModel(provider, id: "llama3.1");

// 3. Optional. Add custom name generator
// After initiating conversation, this will generate a name for it
// If skipped, the conversation will be stored with current datetime as a name
builder.Services.AddCustomNameGenerator(async messages =>
{
    var template =
        @"You will be given conversation between User and Assistant. Your task is to give name to this conversation using maximum 3 words
Conversation:
{chat_history}
Your name: ";
    var conversationBufferMemory = await ConvertToConversationBuffer(messages);
    var chain = LoadMemory(conversationBufferMemory, "chat_history")
                | Template(template)
                | LLM(model);

    return await chain.RunAsync("text") ?? string.Empty;
});

// 4. Optional. Add swagger to be able to test the API
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();

var app = builder.Build();

// 5. Configure LangChainServe
app.UseLangChainServe(options =>
{
    // Register a model. Can be called multiple times to register multiple models
    // this will receive entire conversation and should return a response
    options.RegisterModel("Test model", async (messages) =>
    {
        var template = @"You are helpful assistant. Keep your answers short.
{chat_history}
Assistant:";
        // Convert messages to use with conversation buffer memory
        var conversationBufferMemory = await ConvertToConversationBuffer(messages);
        var chain = LoadMemory(conversationBufferMemory, "chat_history")
                    | Template(template)
                    | LLM(model);

        // get response and send it as AI answer
        var response = await chain.RunAsync("text");
        return new StoredMessage
        {
            Author = MessageAuthor.Ai,
            Content = response ?? string.Empty,
        };
    });
});

// 6. Optional. Add swagger middleware
app.UseSwagger();
app.UseSwaggerUI(c =>
{
    c.SwaggerEndpoint("/swagger/v1/swagger.json", "My API V1");
});
app.Run();
return;

async Task<ConversationBufferMemory> ConvertToConversationBuffer(IReadOnlyCollection<StoredMessage> list)
{
    var conversationBufferMemory = new ConversationBufferMemory
    {
        Formatter =
        {
            HumanPrefix = "User",
            AiPrefix = "Assistant",
        }
    };
    List<Message> converted = list
        .Select(x => new Message(x.Content, x.Author == MessageAuthor.User ? MessageRole.Human : MessageRole.Ai))
        .ToList();

    await conversationBufferMemory.ChatHistory.AddMessages(converted);

    return conversationBufferMemory;
}