Google AI Studio 作为一款低门槛的 GenAI 原型设计平台,深受广大开发者喜爱。然而,对于 C# 开发者来说,AI Studio 的“获取代码”功能目前尚不支持 C#,这无疑给将 AI Studio 中的 Gemini 模型集成到 .NET 应用中带来了一定的挑战。本文将介绍一种巧妙的解决方案,利用 Gemini 本身的能力,将 AI Studio 提供的 REST/curl 代码转换为 C# 代码,从而克服这一障碍,实现从原型到 .NET 应用的无缝过渡。
AI Studio:快速原型设计的理想平台
AI Studio 的核心优势在于其便捷性和高效性。开发者无需复杂的环境配置,即可快速迭代 prompt,测试不同的 Gemini 模型,并立即看到结果。这使得 AI Studio 成为 GenAI 领域探索和验证想法的理想平台。例如,你可以用 AI Studio 快速构建一个电影推荐系统,通过调整 prompt 和模型参数,优化推荐效果。假设你想让 Gemini 基于用户提供的电影列表推荐三部电影,并简要说明原因,你可以在 AI Studio 中快速搭建一个对话 prompt,并进行多次迭代优化。
Gemini:化身 C# 代码生成器
尽管 AI Studio 缺乏直接生成 C# 代码的功能,但我们可以借助 Gemini 的代码生成能力,将 AI Studio 提供的 REST/curl 代码转换成 C# 代码。这种方法的核心思路是:利用 Gemini 理解代码结构和语义的能力,将一种语言的代码翻译成另一种语言。 具体来说,我们可以将 AI Studio 生成的 curl 命令作为输入,编写一个详细的 prompt 指示 Gemini 将其转换为等效的 C# 代码。例如,可以明确告知 Gemini 使用 System.Net.Http.HttpClient
创建 C# 函数,并处理 JSON 序列化和反序列化。
REST/curl:连接 AI Studio 与 C# 的桥梁
AI Studio 的“获取代码”功能提供了多种编程语言的代码片段,其中 REST/curl 代码包含了与 Gemini API 交互的所有必要信息,包括请求头、请求体、API 接口地址等。这些信息是构建 C# 代码的基础。通过仔细分析 REST/curl 代码,我们可以了解如何向 Gemini API 发送请求,并解析返回的 JSON 数据。例如,通过分析 curl 命令,我们可以提取出请求的 URL、请求方法(POST)、请求头(Content-Type: application/json)以及请求体(包含 prompt 和其他参数的 JSON)。
C#:Gemini 集成的最终归宿
C# 作为一种强大的通用编程语言,广泛应用于企业级应用开发。将 Gemini 集成到 C# 应用中,可以为这些应用赋予强大的 AI 能力。例如,可以将 Gemini 集成到 CRM 系统中,自动分析客户反馈,并生成个性化的回复;或者将其集成到内容管理系统中,自动生成文章摘要和标签。使用 Gemini 生成的 C# 代码,可以快速构建与 Gemini API 交互的客户端,从而实现这些功能。需要注意的是,生成的代码通常需要进行一些调整和优化,例如添加错误处理、参数验证等。
实例演示:电影推荐系统的 C# 实现
为了更具体地说明上述方法,我们以一个电影推荐系统为例,演示如何将 AI Studio 中的原型转换为 C# 代码。
- AI Studio 原型设计: 在 AI Studio 中创建一个 Chat prompt,设置系统指令为“你是一个电影推荐专家,我会提供我喜欢的电影列表,你会推荐三部我可能喜欢的电影,并简要说明原因。” 添加一些示例对话,例如用户输入“我喜欢的电影有《黑客帝国》、《银翼杀手》和《星际穿越》”,模型回复推荐电影。
- 获取 curl 代码: 点击 AI Studio 的“获取代码”按钮,选择 REST 选项卡,复制生成的 curl 命令。
- 编写转换 prompt: 在 AI Studio 中创建一个新的 Chat prompt,输入以下指令:
创建一个 C# 函数,使用 System.Net.Http.HttpClient 与 Gemini API 交互。
**函数目标:** 该函数应接受一个 API 密钥(字符串)和一个用户喜欢的电影列表(字符串)作为参数。 它应该将此信息发送到 Gemini API,并以单个字符串形式返回模型的电影推荐。
提供此函数的完整 C# 代码,包括必要的 using 语句,位于单个 C# 代码块中。 该函数应处理请求的基本 JSON 序列化和响应的反序列化以提取文本内容。
CURL 请求:
[在此处粘贴您在步骤 2 中复制的 CURL 请求正文,确保最后一个用户消息的文本中存在“INSERT_INPUT_HERE”占位符]
将第二步获取的curl代码粘贴到上述prompt中。确保替换 [INSERT_USER_MOVIES_HERE]
为占位符 INSERT_INPUT_HERE
。
- 运行转换 prompt: 点击“运行”按钮,Gemini 将生成 C# 代码。
- 在 Visual Studio 中使用 C# 代码:
- 创建一个新的 .NET Console Application 项目。
- 将 Gemini 生成的 C# 代码复制到项目中。
- 确保添加必要的 using 语句,例如
using System;
、using System.Net.Http;
、using System.Text.Json;
。 - 修改
Program.cs
,调用生成的 C# 函数,并将 API 密钥和用户电影列表作为参数传递。 - 运行程序,查看 Gemini 的电影推荐。
生成的C#代码可能如下所示:
using System;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Text;
using System.Threading.Tasks;
using System.Text.Json;
using System.Text.Json.Nodes; // For easily modifying the JSON
using System.Linq;
public class GeminiApiClient
{
private readonly HttpClient _httpClient = new HttpClient();
private const string ApiBaseUrl = "https://generativelanguage.googleapis.com/v1beta/models/";
public async Task<string> GetMovieSuggestionsAsync(string apiKey, string modelId, string userMoviesList)
{
string requestUri = $"{ApiBaseUrl}{modelId}/generateContent?key={apiKey}";
// Base JSON structure (from your Step 3 prompt)
// We'll parse it and modify the dynamic part.
string baseJsonPayload = @"
{
""contents"": [
{
""role"": ""user"",
""parts"": [ { ""text"": ""My favorite movies are The Matrix, Blade Runner, and Interstellar."" } ]
},
{
""role"": ""model"",
""parts"": [ { ""text"": ""Okay, based on your love for The Matrix, Blade Runner, and Interstellar, it's clear you enjoy thought-provoking sci-fi... (full model response here)"" } ]
},
{
""role"": ""user"",
""parts"": [ { ""text"": ""INSERT_INPUT_HERE"" } ]
}
],
""generationConfig"": {
""responseMimeType"": ""text/plain""
}
// Potentially ""safetySettings"": [ ... ] here too
}";
// Parse the JSON string into a JsonNode
JsonNode requestNode = JsonNode.Parse(baseJsonPayload);
// Navigate to the part to be replaced and update it
// This assumes the structure matches exactly.
var contentsArray = requestNode["contents"].AsArray();
var lastUserContent = contentsArray.LastOrDefault(c => c["role"].GetValue<string>() == "user");
if (lastUserContent != null)
{
var partsArray = lastUserContent["parts"].AsArray();
if (partsArray.Any())
{
// Assuming the text to replace is in the first part of the last user message
partsArray[0]["text"] = userMoviesList;
}
}
string finalJsonBody = requestNode.ToJsonString();
var content = new StringContent(finalJsonBody, Encoding.UTF8, "application/json");
HttpResponseMessage response = await _httpClient.PostAsync(requestUri, content);
response.EnsureSuccessStatusCode();
string responseBody = await response.Content.ReadAsStringAsync();
// Basic parsing for the text response
try
{
using (JsonDocument doc = JsonDocument.Parse(responseBody))
{
JsonElement candidatesElement = doc.RootElement.GetProperty("candidates");
if (candidatesElement.EnumerateArray().Any())
{
JsonElement firstCandidate = candidatesElement.EnumerateArray().First();
JsonElement contentElement = firstCandidate.GetProperty("content");
JsonElement partsElement = contentElement.GetProperty("parts");
if (partsElement.EnumerateArray().Any())
{
return partsElement.EnumerateArray().First().GetProperty("text").GetString();
}
}
}
}
catch (Exception ex)
{
Console.WriteLine($"Error parsing response: {ex.Message}. Raw response: {responseBody}");
}
return $"Could not parse response. Raw: {responseBody}"; // Fallback
}
}
Program.cs
代码如下:
using System;
using System.Threading.Tasks;
using System.Net.Http;
class Program
{
static async Task Main(string[] args)
{
string apiKey = Environment.GetEnvironmentVariable("GEMINI_API_KEY");
string modelId = "gemini-2.0-flash"; // Or from your script
if (string.IsNullOrEmpty(apiKey))
{
Console.WriteLine("API key not found. Set GEMINI_API_KEY environment variable.");
return;
}
Console.WriteLine("Please list your favorite movies (comma-separated):");
string userMovies = Console.ReadLine();
if (string.IsNullOrWhiteSpace(userMovies))
{
Console.WriteLine("No movies entered.");
return;
}
try
{
GeminiApiClient client = new GeminiApiClient();
Console.WriteLine("\nGetting suggestions...\n");
string suggestions = await client.GetMovieSuggestionsAsync(apiKey, modelId, userMovies);
Console.WriteLine($"Gemini's Movie Suggestions:\n{suggestions}");
}
catch (HttpRequestException e)
{
Console.WriteLine($"API request error: {e.Message}");
}
catch (Exception e)
{
Console.WriteLine($"An unexpected error occurred: {e.Message}");
}
Console.ReadKey();
}
}
注意事项
- 错误处理: 生成的 C# 代码可能缺乏完善的错误处理机制,需要根据实际情况进行补充。例如,可以添加 try-catch 块来捕获 API 调用过程中可能出现的异常。
- JSON 解析: Gemini 生成的代码可能使用不同的 JSON 解析方法,例如
JsonDocument
或Newtonsoft.Json
。根据项目需求选择合适的 JSON 解析库。 - 参数验证: 为了保证代码的健壮性,建议对 API 密钥和用户电影列表进行参数验证,例如检查 API 密钥是否为空,电影列表是否包含非法字符。
- 异步编程: 与 Gemini API 的交互应该采用异步编程模式,避免阻塞主线程。
总结
尽管 AI Studio 目前不支持直接生成 C# 代码,但通过利用 Gemini 的代码生成能力,我们可以将 AI Studio 中的原型快速转换为 C# 代码,从而实现 Gemini 模型在 .NET 应用中的集成。 这种方法不仅适用于 C#,也可以应用于其他 AI Studio “获取代码”功能不支持的编程语言。 随着 AI Studio 功能的不断完善,相信未来会提供更多编程语言的支持,但在此之前,这种利用 Gemini 自助生成代码的方式,无疑是一种高效且灵活的解决方案。 希望本文能帮助 C# 开发者更好地利用 AI Studio 和 Gemini,加速 GenAI 应用的开发进程。