前回のSemantic KernelにおけるAgentに関する記事では、現在では利用しているパッケージが古くなっているため、今回はそれを更新します。
元の記事は以下の通りです:
Semantic Kernel:Agent代理
桂素伟,公众号:桂迹 Semantic Kernel:Agent代理
以前のプロジェクトで使用していたNugetパッケージは以下の通りで、バージョンは1.18.2に留まっており、2024年9月4日現在のものです。
最新のAgentパッケージに変更されたものは以下の通りです:
以下に示すのは、最新のパッケージを用いて行った変更で、コード内のコメントが各タイプとメソッドの機能を説明しています。ここでは多くを語りません。現在の問題は、各エージェントを作成する際に、Nameには中国語を使用できないことです。そうでなければ、http 400エラーが発生します。この問題は今後改善されると信じています。
using Microsoft.SemanticKernel.Agents.Chat;
using Microsoft.SemanticKernel.Agents.OpenAI;
using Microsoft.SemanticKernel.Agents;
using Microsoft.SemanticKernel.ChatCompletion;
using Microsoft.SemanticKernel;
using System.ClientModel;
using System.Collections.ObjectModel;
using System.Reflection.Emit;
using System;
#pragma warning disable
var modelID = "gpt-4o";
var openAIKey = File.ReadAllText("c://gpt/key.txt");
var kernel = Kernel.CreateBuilder()
.AddOpenAIChatCompletion(modelID, openAIKey).Build();
//翻訳家のエージェントを作成
var agentTranslator = await CreateTranslatorAsync(kernel);
//審査員のエージェントを作成
var agentAuditor = await CreateAuditorAsync(kernel);
//代理チャットグループを作成し、まず翻訳家が翻訳し、その後審査員が審査
var chat = new AgentGroupChat(agentTranslator, agentAuditor)
{
ExecutionSettings = new()
{
// 代理メッセージに"採用する"というフレーズがある場合終了するTerminationStrategyのサブクラスを使用。
TerminationStrategy = new AdoptTerminationStrategy("採用する")
{
Agents = [agentAuditor],
MaximumIterations = 6,
}
}
};
//チャットメッセージを追加
var chatMessage = new ChatMessageContent(AuthorRole.User, File.ReadAllText("content.txt"));
chat.AddChatMessage(chatMessage);
Console.WriteLine(chatMessage);
var lastAgent = string.Empty;
Console.WriteLine();
// ここでは非同期ストリームで代理のメッセージを処理します。
await foreach (var response in chat.InvokeStreamingAsync())
{
if (string.IsNullOrEmpty(response.Content))
{
continue;
}
// 役割とエージェントの名前を入力
if (!lastAgent.Equals(response.AuthorName, StringComparison.Ordinal))
{
Console.WriteLine($"\n# {response.Role} - {response.AuthorName ?? "*"}:");
lastAgent = response.AuthorName ?? string.Empty;
}
Console.Write(response.Content);
}
//ChatMessageContent[] history = await chat.GetChatMessagesAsync().Reverse().ToArrayAsync();
//全コンテンツ
//for (int index = 0; index < history.Length; index++)
//{
// Console.WriteLine(history[index]);
//}
Console.WriteLine($"\n[完了しました: {chat.IsComplete}]");
async Task<ChatCompletionAgent> CreateAuditorAsync(Kernel kernel)
{
var agentTranslator = new ChatCompletionAgent()
{
Instructions = """
あなたは中日文翻訳の翻訳審査員であり、翻訳と審査に豊富な経験を持ち、翻訳の品質に高い要求を持ち、常に厳しい基準を設け、正確な翻訳を目指します。
目的は、与えられた翻訳が要求を満たしているかどうか、採用するかどうかを決定することです。
翻訳内容が受け入れられると判断された場合、"採用する"と言ってください。
""",
Name = "Auditor",
Kernel = kernel,
};
return agentTranslator;
}
async Task<OpenAIAssistantAgent> CreateTranslatorAsync(Kernel kernel)
{
var agentAuditor = await OpenAIAssistantAgent.CreateAsync(
clientProvider: OpenAIClientProvider.ForOpenAI(new ApiKeyCredential(openAIKey)),
definition: new OpenAIAssistantDefinition(modelID)
{
Instructions = """
あなたは中国語から日本語への翻訳者です。
ユーザーからの入力を、目の前のターゲットに集中し、正確で高品質な翻訳に変換します。
翻訳内容を充実させる際には、審査員からの提案を考慮してください。
""",
Name = "JapaneseTranslator",
},
kernel: kernel);
return agentAuditor;
}
class AdoptTerminationStrategy(string adoptCommand) : TerminationStrategy
{
protected override Task<bool> ShouldAgentTerminateAsync(Agent agent, IReadOnlyList<ChatMessageContent> history, CancellationToken cancellationToken)
=> Task.FromResult(history[history.Count - 1].Content?.Contains(adoptCommand, StringComparison.OrdinalIgnoreCase) ?? false);
}
実行結果:
(Translated by GPT)