﻿# 介紹好用套件：PaLM.NET (透過 .NET 呼叫 PaLM API 服務)

這幾天在玩 Google 新推出的 [MakerSuite](https://makersuite.google.com/) 與 [PaLM API](https://developers.generativeai.google/) 服務，在研究的過程中我發現官網幾乎沒有提供 .NET 的範例程式，所以我就在研究的過程中順手寫了一個 [PaLM.NET](https://www.nuget.org/packages/PaLM.NET/) 類別庫，透過我寫的這個類別庫可以非常輕鬆的呼叫 PaLM API 服務，快速打造 Google 全新的 Generative AI 應用程式。

![PaLM.NET](https://stwillblogassets.blob.core.windows.net/files/images/external/stwillblogassets.blob.core.windows.net/e495a02d60b223e52d29-d0983756-e198-4da0-bb23-3ff079c2d143.webp)

> 注意: 目前 Google 的 PaLM API 有兩個版本，一個是 PaLM API in Vertex AI (企業用)，另一個是 PaLM API in Generative AI (個人用)，本篇文章是以 PaLM API in Generative AI 為主，而且該版本目前還在 private preview 階段，必須先到 [https://makersuite.google.com/](https://makersuite.google.com/) 加入等候清單，待 Google 通知後才能申請 API Key 來用。

### 申請 PaLM API 的 API Key

當你申請 [MakerSuite](https://makersuite.google.com/) 到之後，就可以到 [https://makersuite.google.com/app/apikey](https://makersuite.google.com/app/apikey) 建立一把全新的 API Key：

![Get API key | MakerSuite](https://stwillblogassets.blob.core.windows.net/files/images/external/stwillblogassets.blob.core.windows.net/2be871f06e6696310dd0-96fc5bf5-8fc6-4cdb-be43-05a2e027dec6.webp)

如果你選擇 `Create API key in new project` 的話，他會自動幫你在 Google Cloud Console 建立一個新的專案，並且把 PaLM API 服務加入到專案中，還會自動幫你建立好一把 API Key 來用！

![APIs & Services - Credentials - API Keys](https://stwillblogassets.blob.core.windows.net/files/images/external/stwillblogassets.blob.core.windows.net/143a5af2f5f0815aa9fe-8c752b5b-b513-4775-b2ea-9bd92e576f48.webp)

### 建立範例專案

1.  建立一個 Console 專案
    
    ```bash
    dotnet new console -n PaLM.NET.Samples
    cd PaLM.NET.Samples
    
    dotnet new gitignore
    ```
    
2.  安裝 [PaLM.NET](https://www.nuget.org/packages/PaLM.NET/) NuGet 套件
    
    ```bash
    dotnet add package PaLM.NET --version 0.1.0-alpha
    ```
    
3.  在 `Program.cs` 加入初始化 `PaLMClient` 程式碼
    
    先建立一個 `PaLMClient` 物件，並且傳入 API Key：
    
    ```csharp
    // 你可以考慮將 API Key 從環境變數傳入，或直接設定到變數上
    var apikey = Environment.GetEnvironmentVariable("GOOGLE_PALM_APIKEY");
    
    // 建立 PaLMClient 物件
    using var palm = new PaLMClient(apikey);
    ```
    
    有了 `PaLMClient` 物件之後，就可以透過 `palm` 物件來呼叫 PaLM API 服務了！
    

### 呼叫 PaLM API 服務

PaLM API 服務目前有三種用法，分別是：

1.  Text (文字接龍)
2.  Chat (聊天對話)
3.  Embeddings (建立文字向量)

我的 [PaLM.NET](https://www.nuget.org/packages/PaLM.NET/) 套件都有定義出 REST API 在傳遞 JSON 訊息的型別，所以都可以使用「強型別」的方式進行開發。

1.  Text (文字接龍)
    
    你只要先準備好 Text Prompt 的參數 (`TextOption`) 與相關提示內容，就可以發出 PaLM API 的呼叫，取得結果。
    
    ```csharp
    // 先設定 Text Prompt 的相關參數
    var textPromptOptions = new TextOption()
    {
        Temperature = 0,
        TopK = 40,
        TopP = 0.95,
        CandidateCount = 1,
        MaxOutputTokens = 1024
    };
    
    // 指定 Prompt 文字內容
    textPromptOptions.Prompt.Text = """
    Who are all the people and places named in the paragraph below? Respond in JSON.
    
    Paragraph: Apollo 11 launched from Cape Kennedy on July 16, 1969, carrying Commander Neil Armstrong, Command Module Pilot Michael Collins and Lunar Module Pilot Edwin "Buzz" Aldrin into an initial Earth-orbit of 114 by 116 miles. An estimated 650 million people watched Armstrong's televised image and heard his voice describe the event as he took "...one small step for a man, one giant leap for mankind" on July 20, 1969.
    """;
    
    // 執行 GenerateTextAsync 方法取得結果 ( TextResult 型別 )
    var text_result = await palm.GenerateTextAsync(textPromptOptions).Dump();
    
    // 如果 CandidateCount 參數設為 1，則代表回應只會有一個候選結果
    text_result.Candidates[0].Output.DumpJson();
    ```
    
2.  Chat (聊天對話)
    
    你只要先準備好 Message Prompt 的參數 (`MessageOption`) 與相關提示內容，就可以發出 PaLM API 的呼叫，取得結果。
    
    ```csharp
    var chatPromptOptions = new MessageOption()
    {
        Temperature = 0.9,
        TopK = 40,
        TopP = 0.95,
        CandidateCount = 1
    };
    
    // Optional
    // 設定 Model 的身分 (角色扮演)
    chatPromptOptions.Context = "Be an alien that lives on one of Jupiter's moons";
    
    // Optional
    // 設定一些對話的範例或歷史的對話內容
    chatPromptOptions.AddExample(
        input: "How's it going?",
        output: "I am doing well, thank you for asking. I am currently enjoying the beautiful view of Jupiter from my home on Europa. The atmosphere is very thin here, so I can see the stars very clearly. The surface of Europa is also very interesting. It is covered in ice, but there are cracks in the ice that reveal a liquid ocean below. Scientists believe that this ocean may contain life, so I am very excited to learn more about it.\n\nHow are you doing today?"
    );
    
    // Required
    // 設定你要提問的訊息
    chatPromptOptions.AddMessage("I'd like to visit, what should I do?");
    
    // 執行 GenerateMessageAsync 方法取得結果 ( MessageResult 型別 )
    var chat_result = await palm.GenerateMessageAsync(chatPromptOptions).Dump();
    
    // 如果 CandidateCount 參數設為 1，則代表回應只會有一個候選結果
    chat_result.Candidates[0].Content.Dump();
    ```
    
3.  Embeddings (建立文字向量)
    
    你只要先準備好 Embeddings 的參數 (`EmbeddingOption`) 與相關提示內容，就可以發出 PaLM API 的呼叫，取得結果。
    
    ```csharp
    var embeddingsOptions = new EmbeddingOption()
    {
        Text = "Be an alien that lives on one of Jupiter's moons"
    };
    
    // 執行 GenerateEmbeddingsAsync 方法取得結果 ( EmbeddingResult 型別 )
    var embeddings_result = await palm.GenerateEmbeddingsAsync(embeddingsOptions);
    
    // 所有的向量值會儲存在 EmbeddingResult.Embedding.Values 屬性中
    foreach (double value in embeddings_result.Embedding.Values)
    {
        Console.WriteLine(value);
    }
    ```
    

### 總結

你可以發現到我所設計的 [PaLM.NET](https://www.nuget.org/packages/PaLM.NET/) 類別庫，使用上還蠻簡單的，我隱藏了許多技術細節，所以你幾乎不用煩惱 HttpClient 要怎樣呼叫 PaLM 的 REST API、模型 ID 是什麼、要怎麼傳入參數等等，只要你有 API Key 就可以直接使用！

由於我之前就有深入研究過 OpenAI 的 API 服務，也研究過提示工程(Prompt Engineering)的相關技術，所以我在使用 PaLM API 的時候，幾乎沒有什麼門檻，很多觀念都是相通的，尤其是對 Prompting 的調校部分，這些都有蠻多學問的，建議可以多利用 [MakerSuite](https://makersuite.google.com/) 來體驗 PaLM API 的結果與品質，將你自己的 Prompt 調校到最佳狀態，然後再利用 [PaLM.NET](https://www.nuget.org/packages/PaLM.NET/) 來呼叫 PaLM API 服務，這樣你就可以得到最好的結果了！👍

最後，我這套 [PaLM.NET](https://www.nuget.org/packages/PaLM.NET/) 是一個開源套件，你可以到 [https://github.com/doggy8088/PaLM.NET](https://github.com/doggy8088/PaLM.NET) 查看我的原始碼，也歡迎對我的 [PaLM.NET](https://github.com/doggy8088/PaLM.NET) 做出貢獻，讓這個套件更加完善！😊

### 相關連結

-   [doggy8088/PaLM.NET](https://github.com/doggy8088/PaLM.NET): A PaLM API wrapper for .NET that supports .NET Standard 2.0.
-   [NuGet Gallery | PaLM.NET 0.1.0](https://www.nuget.org/packages/PaLM.NET/)
-   [MakerSuite](https://makersuite.google.com/)
-   PaLM API  |  Generative AI for Developers
    -   產品入口頁 - [MakerSuite](https://developers.generativeai.google/products/makersuite)
    -   產品入口頁 - [PaLM API](https://developers.generativeai.google/products/palm)
    -   [PaLM API Documentation](https://developers.generativeai.google/api)
    -   [Prompt gallery](https://developers.generativeai.google/prompt-gallery)
