Skip to content

Convert Session Details to Embeddings

Step 4 of 5

Initial Configuration

Configure the Event Copilot Setup Page:

  • Start by opening the Event Copilot Setup page within Dynamics 365 Business Central.
  • Locate the field labeled Embeddings Deployment.
  • If you have been following the instructions provided in this workshop, enter 'text-embedding-ada-002' into the Embeddings Deployment field. This specifies the Azure OpenAI model deployment that your application will use for generating embeddings.

Getting Started

Open the Implementation File:

  • Navigate to "\src\6-AdvancedAssistantCopilot\Implementation\SessionEmbeddingImpl.Codeunit.al".
  • This file will contain all the necessary procedures to handle session embeddings.

Implementing Session Embeddings

1. Loop Sessions

  • You will add a procedure named GenerateSessionsEmbeddings that initiates the embedding generation process.

    procedure GenerateSessionsEmbeddings()
    var
        ConfirmMgtCodeunit: Codeunit "Confirm Management";
        Session: Record "GPT Session";
    begin
        if not ConfirmMgtCodeunit.GetResponse(ConfirmGenerateEmbeddingsQtn, false) then
            exit;
    
        if Session.FindSet() then
            repeat
                GeneratePayloadAndEmbedSession(Session);
            until Session.Next() = 0;
    
        Message(MsgEmbeddingsGenerated);
    end;
    
  • This code checks if the user confirms the action, then iterates over all session records to generate embeddings.

2. Embed Session

  • Create a helper procedure GeneratePayloadAndEmbedSession to handle payload generation and session embedding:
    local procedure GeneratePayloadAndEmbedSession(var Session: Record "GPT Session")
    var
        Payload: TextBuilder;
    begin
        DeletePreviousSessionEmbedding(Session."Code");
        GenerateSessionPayload(Payload, Session);
        EmbedSession(Payload.ToText(), Session);
    end;
    

3. Generate Payload Text

  • Implement GenerateSessionPayload to compile various session details into a single string:
    local procedure GenerateSessionPayload(var Payload: TextBuilder; var Session: Record "GPT Session")
    var
    begin
        Payload.AppendLine(Session.Name);
        Payload.AppendLine();
        Payload.AppendLine(Session.Description);
        Payload.AppendLine();
        Payload.AppendLine('Speakers:');
        Payload.AppendLine(Session.Speaker1);
        Payload.AppendLine(Session.Speaker2);
        Payload.AppendLine(Session.Speaker3);
        Payload.AppendLine(Session.Speaker4);
        Payload.AppendLine('Schedule:');
        Payload.AppendLine(Format(Session.Date, 0, 9));
        Payload.AppendLine(Format(Session."Start Time", 0, 9));
        Payload.AppendLine(Format(Session."End Time", 0, 9));
        Payload.AppendLine();
        Payload.AppendLine('Duration (min):');
        Payload.AppendLine(Format(Session."Durarion (min)"));
    end;
    

4. Embed Payload

  • Define EmbedSession to handle the communication with Azure OpenAI and store the embeddings:
    local procedure EmbedSession(Payload: Text; Session: Record "GPT Session")
    var
        Embedding: Record "GPT Session Embedding";
        VectorJArray: JsonArray;
        VectorText: Text;
    begin
        VectorJArray := GetAzureOpenAIEmbeddings(Payload);
        VectorJArray.WriteTo(VectorText);
    
        InsertEmbedding(Session, Payload, VectorText, Embedding);
        InsertEmbeddingVectors(Embedding."Session Code", VectorJArray);
    end;
    

5. Get And Store Embeddings

Implement the procedures GetAzureOpenAIEmbeddings, InsertEmbedding, InsertEmbeddingVectors and others that take care of the embedding generation and storage process.

Get Embeddings

Previosly, you used the Azure OpenAI codeunit to generate messages. Now, you will use it to get embeddings.

Some key points to remember:

  • Set the model type to Embeddings.
  • Use the GenerateEmbeddings method to get the embeddings.
  • Process the response to extract the JsonArray containing the embeddings.
procedure GetAzureOpenAIEmbeddings(Input: Text): JsonArray
var
    AzureOpenAI: Codeunit "Azure OpenAi";
    AOAIOperationResponse: Codeunit "AOAI Operation Response";
    CopilotSetup: Record "GPT Event Copilot Setup";
begin
    if not AzureOpenAI.IsEnabled(Enum::"Copilot Capability"::"GPT Event Assistant") then
        exit;

    AzureOpenAI.SetCopilotCapability(Enum::"Copilot Capability"::"GPT Event Assistant");

    AzureOpenAI.SetAuthorization(Enum::"AOAI Model Type"::Embeddings, CopilotSetup.GetEndpoint(), CopilotSetup.GetEmbeddingsDeployment(), CopilotSetup.GetSecretKey());
    AzureOpenAI.GenerateEmbeddings(Input, AOAIOperationResponse);

    if AOAIOperationResponse.IsSuccess() then
        exit(GetVectorArray(AOAIOperationResponse.GetResult()))
    else
        Error(AOAIOperationResponse.GetError());
end;

local procedure GetVectorArray(Response: Text) Result: JsonArray
var
    Vector: JsonObject;
    Tok: JsonToken;
begin
    Vector.ReadFrom(Response);
    Vector.Get('vector', Tok);
    exit(Tok.AsArray());
end;

Save Payload

Save the payload and link to the Session to the Session Embedding table.

local procedure InsertEmbedding(Session: Record "GPT Session"; Payload: Text; VectorText: Text; var Embedding: Record "GPT Session Embedding")
begin
    Embedding.Init();
    Embedding."Session Code" := Session."Code";
    Embedding.Payload := Payload;
    Embedding.Insert(true);
    Embedding.SaveVectorText(VectorText);
end;

Note

The SaveVectorText method saves the vector array to the blob field in the Session Embedding table. It's not nessary step, but it's useful for observing embeddings in the UI.

Convert JsonArray to List

We recieve the embeddings as a JsonArray. We need to convert it to a list of decimals to store in the Session Embedding Vector table.

procedure ConvertJsonArrayToListOfDecimals(EmbeddingArray: JsonArray) Result: List of [Decimal]
var
    i: Integer;
    EmbeddingValue: JsonToken;
begin
    for i := 0 to EmbeddingArray.Count() - 1 do begin
        EmbeddingArray.Get(i, EmbeddingValue);
        Result.Add(EmbeddingValue.AsValue().AsDecimal());
    end;
end;

Save Embeddings

Lastly, save the embedding vectors to the Session Embedding Vector table.

procedure InsertEmbeddingVectors(SessionCode: Code[20]; VectorJArray: JsonArray)
var
    Value: Decimal;
    Vector: List of [Decimal];
    i: Integer;
begin
    Vector := ConvertJsonArrayToListOfDecimals(VectorJArray);

    foreach Value in Vector do begin
        i += 1;
        InsertEmbeddingVector(SessionCode, i, Value);
    end;
end;

local procedure InsertEmbeddingVector(SessionCode: Code[20]; VectorId: Integer; Value: Decimal)
var
    EmbeddingVector: Record "GPT Session Embedding Vector";
begin
    EmbeddingVector.Init();
    EmbeddingVector."Session Code" := SessionCode;
    EmbeddingVector.VectorId := VectorId;
    EmbeddingVector.VectorValue := Value;
    EmbeddingVector.Insert(true);
end;

Testing the Implementation

  • Open the Business Central and navigate to the Projects page.
  • Select the project for which you have sessions and click on the Session action. This will open the Sessions page.
  • Click on the Embeddings action and then on the Generate action. This will generate embeddings for all the sessions.

Conclusion

By following this tutorial, students will be able to generate embeddings for sessions in Business Central. This is a crucial step in implementing semantic search capabilities in the Advanced Assistant Copilot. The embeddings generated in this process will be used to compare user queries with session details and provide relevant search results.

Next Steps

Proceed to the next part to understand how to implement semantic search in your copilot.