오늘 아침 새롭게 출시된 Google의 새 오픈 소스 LLM인 Gemma 4를 바로 테스트해보고 싶어서 테스트 코드를 작성해봤습니다.
MS Agent Framework, Ollama, 그리고 MS Learn MCP 서버 툴 콜링까지 합친 온전한 예제를 손쉽게 만들 수 있었고 로컬에서도 꽤 의미있는 결과를 낼 수 있었습니다. Edge 디바이스 용으로 경량화된 환경, 그리고 애플 M2 Air 정도 되는 사양에서도 그럭저럭 쓸만한 결과가 나와서 흥미로웠습니다.
(이미 잘 아시겠지만, .NET은 애플 실리콘 맥에서도 너무나 자연스럽게 잘 작동합니다.)
아래 코드를 gemma4.cs 로 저장하고 dotnet run gemma4.cs 혹은 chmod +x gemma4.cs; ./gemma4.cs 로 Ollama가 떠 있는 상태에서 실행하시면 Model Pull부터 툴 콜링까지 한 번에 전개되는 것을 보실 수 있을 것입니다. ![]()
#!/usr/bin/env dotnet
#:package Microsoft.Agents.AI@1.*
#:package Microsoft.Extensions.AI@10.*
#:package OllamaSharp@5.*
#:package ModelContextProtocol@1.*
#:property PublishAot=false
using Microsoft.Extensions.AI;
using Microsoft.Agents.AI;
using OllamaSharp;
using ModelContextProtocol.Client;
var ollamaEndpoint = "http://localhost:11434";
var modelId = "gemma4";
var systemCard = "당신은 Ollama 안에서 실행되는 유능하고 유용한 로컬 AI 어시스턴트입니다. 모든 메시지는 한국어로 답해야 합니다.";
var prompt = "Windows Sandbox를 XML 방식으로 제어하는 방법이 궁금합니다.";
var option = new ChatClientAgentRunOptions()
{
ChatOptions = new()
{
Reasoning = new()
{
Effort = ReasoningEffort.High,
Output = ReasoningOutput.Full,
}
},
};
using var chatClient = new OllamaApiClient(ollamaEndpoint, modelId);
await foreach (var eachFragment in chatClient.PullModelAsync(modelId))
Console.WriteLine($"{eachFragment?.Status}: {eachFragment?.Percent}%");
var client = await McpClient.CreateAsync(new HttpClientTransport(new HttpClientTransportOptions() { Name = "microsoft_learn", Endpoint = new Uri("https://learn.microsoft.com/api/mcp"), }));
var agent = chatClient.AsAIAgent(
instructions: systemCard,
tools: (await client.ListToolsAsync()).Cast<AITool>().ToList());
var session = await agent.CreateSessionAsync().ConfigureAwait(false);
await foreach (var eachFragment in agent.RunStreamingAsync(prompt, session, option))
{
foreach (var eachContent in eachFragment.Contents)
{
if (eachContent is TextReasoningContent reasoning)
Console.Write(reasoning.Text);
else if (eachContent is TextContent text)
Console.Write(text.Text);
else
Console.WriteLine($"<< {eachContent.GetType()} >>");
}
}
