mscraftsman / generative-ai

Gemini AI SDK for .NET and ASP.NET Core enables developers to use Google's state-of-the-art generative AI models to build AI-powered features and applications.
https://mscraftsman.github.io/generative-ai/
Apache License 2.0
39 stars 8 forks source link

Feature suggestion: Add logs with LogLevel using the Standard logging in .NET #6

Open doggy8088 opened 3 months ago

doggy8088 commented 3 months ago

There is not logging support in your core library (the Mscc.GenerativeAI package).

I wish there is a way to debug your library from the logs with proper LogLevel when something went wrong.

The Standard .NET Logging should be a good idea.

jochenkirstaetter commented 3 months ago

Thanks, I will look into it.

There should be an option to leverage dependency injection (DI) to provide access to the ILogger interface. However, that's usually bound to an application host or builder.

Good idea, and a solid addition to the package.

doggy8088 commented 3 months ago

@jochenkirstaetter I have a simple Embedding usage. It always return Response status code does not indicate success: 400 (Bad Request). error. It because there is no logs comes from your library. I have totally no idea how to debug this. With the same ApiKey, all other APIs are functional. Do you have any idea?

async Task Main()
{
    var googleAI = new GoogleAI(apiKey: Util.GetPassword("GEMINI_API_KEY"));

    var model = googleAI.GenerativeModel(model: Model.Embedding).Dump();

    var response = await model.GetModel().Dump();

    var embeddings = await model.EmbedContent(GetMarkdown());

    embeddings.Dump();
}

image

jochenkirstaetter commented 3 months ago

It looks like it is using the wrong model. Hmm, no then you would get a NotSupportedException as the method checks for the embedding model.

I'm going to check. What's the content of your markdown? Does it contain double quotes (")? Probably there's some escaping missing.

doggy8088 commented 3 months ago

Here is my markdown content:

string GetMarkdown()
{
    return """
Read more about [Mscc.GenerativeAI.Web](https://github.com/mscraftsman/generative-ai/blob/main/src/Mscc.GenerativeAI.Web) and how to add it to your ASP.NET (Core) web applications. Read more about [Mscc.GenerativeAI.Google](https://github.com/mscraftsman/generative-ai/blob/main/src/Mscc.GenerativeAI.Google).

## Install the package 🖥️

Install the package [Mscc.GenerativeAI](https://www.nuget.org/packages/Mscc.GenerativeAI/) from NuGet. You can install the package from the command line using either the command line or the NuGet Package Manager Console. Or you add it directly to your .NET project.

Add the package using the `dotnet` command line tool in your .NET project folder.

dotnet add package Mscc.GenerativeAI

Working with Visual Studio use the NuGet Package Manager to install the package Mscc.GenerativeAI.

PM> Install-Package Mscc.GenerativeAI

Alternatively, add the following line to your .csproj file.

<ItemGroup>
    <PackageReference Include="Mscc.GenerativeAI" Version="0.9.0" />
  </ItemGroup>

You can then add this code to your sources whenever you need to access any Gemini API provided by Google. This package works for Google AI (Google AI Studio) and Google Cloud Vertex AI.

Features (as per Gemini analysis) ✦

The provided code defines a C# library for interacting with Google's Generative AI models, specifically the Gemini models. It provides functionalities to:

The package also defines various helper classes and enums to represent different aspects of the Gemini API, such as model names, request parameters, and response data.

Authentication use cases 👥

The package supports the following use cases to authenticate.

This applies mainly to the instantiation procedure. """; }

doggy8088 commented 3 months ago

The model.GetModel() issue I mentioned here: https://github.com/mscraftsman/generative-ai/issues/13 I think it's not related to my Embedding usage.

I think the main point is the payload format.

Would you consider expose the full response body into the exception object? If I have that, the debugging experience will be much smoother.

doggy8088 commented 3 months ago

I tried using Postman to send request.

Here is my request payload which is serialized from EmbedContentRequest object.

var request = new EmbedContentRequest("Hello");
request.TaskType = TaskType.RetrievalDocument;
request.Title = "Hello World";
request.Content.Role = "user";

The JSON is:

{
    "model": "models/embedding-001",
    "content": {
        "parts": [
            {
                "text": "Hello"
            }
        ],
        "role": "user",
        "text": "Hello"
    },
    "taskType": "RETRIEVAL_DOCUMENT",
    "title": "Hello World"
}

The response body is:

{
    "error": {
        "code": 400,
        "message": "Invalid JSON payload received. Unknown name \"text\" at 'content': Cannot find field.",
        "status": "INVALID_ARGUMENT",
        "details": [
            {
                "@type": "type.googleapis.com/google.rpc.BadRequest",
                "fieldViolations": [
                    {
                        "field": "content",
                        "description": "Invalid JSON payload received. Unknown name \"text\" at 'content': Cannot find field."
                    }
                ]
            }
        ]
    }
}

That's weird. I checked the API document: https://ai.google.dev/api/rest/v1beta/Content#Part The text field should be valid!

Any idea?

doggy8088 commented 3 months ago

I found the bug here:

image

I'll raise a new issue for this. See here: https://github.com/mscraftsman/generative-ai/issues/14

jochenkirstaetter commented 3 months ago

That second key "text" is too much, and therefore a Bad Request.

jochenkirstaetter commented 3 months ago

Yes, that should be fine now. Or?

doggy8088 commented 3 months ago

It works perfectly now.

jochenkirstaetter commented 3 months ago

Great feedback, thanks.