Catatan
Akses ke halaman ini memerlukan otorisasi. Anda dapat mencoba masuk atau mengubah direktori.
Akses ke halaman ini memerlukan otorisasi. Anda dapat mencoba mengubah direktori.
Penting
Ini adalah dokumen yang diarsipkan.
Penting
Fitur ini berada dalam tahap eksperimental tetapi tidak lagi dipertahankan. Untuk penggantian, lihat Orkestrasi Obrolan Grup dan panduan migrasi Bermigrasi dari AgentChat ke Orkestrasi Obrolan Grup.
Gambaran Umum
Dalam sampel ini, kita akan mengeksplorasi cara menggunakan AgentGroupChat untuk mengoordinasikan kolaborasi dua agen berbeda yang bekerja untuk meninjau dan menulis ulang konten yang disediakan pengguna. Setiap agen diberi peran yang berbeda:
- Peninjau: Meninjau dan memberikan arahan kepada Writer.
- Penulis: Memperbarui konten pengguna berdasarkan input Peninjau.
Langkah-langkah dalam pendekatan ini akan dipecah satu per satu untuk menggarisbawahi bagian-bagian utama dari proses pengodean.
Memulai Langkah Awal
Sebelum melanjutkan pengkodian fitur, pastikan lingkungan pengembangan Anda sepenuhnya disiapkan dan dikonfigurasi.
Petunjuk / Saran
Sampel ini menggunakan file teks opsional sebagai bagian dari pemrosesan. Jika Anda ingin menggunakannya, Anda dapat mengunduhnya di sini. Tempatkan file di direktori kerja kode Anda.
Mulailah dengan membuat proyek Konsol. Kemudian, sertakan referensi paket berikut untuk memastikan semua dependensi yang diperlukan tersedia.
Untuk menambahkan dependensi paket dari baris perintah, gunakan dotnet perintah :
dotnet add package Azure.Identity
dotnet add package Microsoft.Extensions.Configuration
dotnet add package Microsoft.Extensions.Configuration.Binder
dotnet add package Microsoft.Extensions.Configuration.UserSecrets
dotnet add package Microsoft.Extensions.Configuration.EnvironmentVariables
dotnet add package Microsoft.SemanticKernel.Connectors.AzureOpenAI
dotnet add package Microsoft.SemanticKernel.Agents.Core --prerelease
Jika mengelola paket NuGet di Visual Studio, pastikan
Include prereleasedicentang.
File proyek (.csproj) harus berisi definisi berikut PackageReference :
<ItemGroup>
<PackageReference Include="Azure.Identity" Version="<stable>" />
<PackageReference Include="Microsoft.Extensions.Configuration" Version="<stable>" />
<PackageReference Include="Microsoft.Extensions.Configuration.Binder" Version="<stable>" />
<PackageReference Include="Microsoft.Extensions.Configuration.UserSecrets" Version="<stable>" />
<PackageReference Include="Microsoft.Extensions.Configuration.EnvironmentVariables" Version="<stable>" />
<PackageReference Include="Microsoft.SemanticKernel.Agents.Core" Version="<latest>" />
<PackageReference Include="Microsoft.SemanticKernel.Connectors.AzureOpenAI" Version="<latest>" />
</ItemGroup>
Agent Framework bersifat eksperimental dan memerlukan pemadaman peringatan. Ini dapat diatasi sebagai properti dalam file proyek (.csproj):
<PropertyGroup>
<NoWarn>$(NoWarn);CA2007;IDE1006;SKEXP0001;SKEXP0110;OPENAI001</NoWarn>
</PropertyGroup>
Petunjuk / Saran
Sampel ini menggunakan file teks opsional sebagai bagian dari pemrosesan. Jika Anda ingin menggunakannya, Anda dapat mengunduhnya di sini. Tempatkan file di direktori kerja kode Anda.
Mulailah dengan menginstal paket Semantic Kernel Python.
pip install semantic-kernel
Selanjutnya tambahkan impor yang diperlukan.
import asyncio
import os
from semantic_kernel import Kernel
from semantic_kernel.agents import AgentGroupChat, ChatCompletionAgent
from semantic_kernel.agents.strategies import (
KernelFunctionSelectionStrategy,
KernelFunctionTerminationStrategy,
)
from semantic_kernel.connectors.ai.open_ai import AzureChatCompletion
from semantic_kernel.contents import ChatHistoryTruncationReducer
from semantic_kernel.functions import KernelFunctionFromPrompt
Fitur saat ini tidak tersedia di Java.
Konfigurasi
Sampel ini memerlukan pengaturan konfigurasi untuk terhubung ke layanan jarak jauh. Anda harus menentukan pengaturan untuk OpenAI atau Azure OpenAI.
# OpenAI
dotnet user-secrets set "OpenAISettings:ApiKey" "<api-key>"
dotnet user-secrets set "OpenAISettings:ChatModel" "gpt-4o"
# Azure OpenAI
dotnet user-secrets set "AzureOpenAISettings:ApiKey" "<api-key>" # Not required if using token-credential
dotnet user-secrets set "AzureOpenAISettings:Endpoint" "<model-endpoint>"
dotnet user-secrets set "AzureOpenAISettings:ChatModelDeployment" "gpt-4o"
Kelas berikut digunakan dalam semua contoh Agen. Pastikan untuk menyertakannya dalam proyek Anda untuk memastikan fungsionalitas yang tepat. Kelas ini berfungsi sebagai komponen dasar untuk contoh berikut.
using System.Reflection;
using Microsoft.Extensions.Configuration;
namespace AgentsSample;
public class Settings
{
private readonly IConfigurationRoot configRoot;
private AzureOpenAISettings azureOpenAI;
private OpenAISettings openAI;
public AzureOpenAISettings AzureOpenAI => this.azureOpenAI ??= this.GetSettings<Settings.AzureOpenAISettings>();
public OpenAISettings OpenAI => this.openAI ??= this.GetSettings<Settings.OpenAISettings>();
public class OpenAISettings
{
public string ChatModel { get; set; } = string.Empty;
public string ApiKey { get; set; } = string.Empty;
}
public class AzureOpenAISettings
{
public string ChatModelDeployment { get; set; } = string.Empty;
public string Endpoint { get; set; } = string.Empty;
public string ApiKey { get; set; } = string.Empty;
}
public TSettings GetSettings<TSettings>() =>
this.configRoot.GetRequiredSection(typeof(TSettings).Name).Get<TSettings>()!;
public Settings()
{
this.configRoot =
new ConfigurationBuilder()
.AddEnvironmentVariables()
.AddUserSecrets(Assembly.GetExecutingAssembly(), optional: true)
.Build();
}
}
Cara tercepat untuk memulai konfigurasi yang tepat untuk menjalankan kode sampel adalah dengan membuat .env file di akar proyek Anda (tempat skrip Anda dijalankan). Sampel mengharuskan Anda memiliki sumber daya Azure OpenAI atau OpenAI yang siap digunakan.
Atur pengaturan berikut di file .env Anda untuk Azure OpenAI atau OpenAI.
AZURE_OPENAI_API_KEY="..."
AZURE_OPENAI_ENDPOINT="https://<resource-name>.openai.azure.com/"
AZURE_OPENAI_CHAT_DEPLOYMENT_NAME="..."
AZURE_OPENAI_API_VERSION="..."
OPENAI_API_KEY="sk-..."
OPENAI_ORG_ID=""
OPENAI_CHAT_MODEL_ID=""
Setelah dikonfigurasi, masing-masing kelas layanan AI akan mengambil variabel yang diperlukan dan menggunakannya selama instansiasi.
Fitur saat ini tidak tersedia di Java.
Pengkodean
Proses pengkodian untuk sampel ini melibatkan:
- Penyiapan - Menginisialisasi pengaturan dan plug-in.
-
AgentDefinisi - Buat dua instansChatCompletionAgent(Peninjau dan Penulis). -
Obrolan Definisi - Buat
AgentGroupChatdan strategi terkait. - Chat Loop - Tulis loop yang menggerakkan interaksi antara pengguna dan agen.
Contoh lengkap kode disediakan di bagian Akhir . Lihat bagian tersebut untuk implementasi lengkap.
Pengaturan
Sebelum membuat ChatCompletionAgent, pengaturan konfigurasi, plugin, dan Kernel harus diinisialisasi.
Buat instans kelas Settings yang dirujuk pada bagian Konfigurasi sebelumnya.
Settings settings = new();
Fitur saat ini tidak tersedia di Java.
Sekarang inisialisasikan instansi Kernel dengan IChatCompletionService.
IKernelBuilder builder = Kernel.CreateBuilder();
builder.AddAzureOpenAIChatCompletion(
settings.AzureOpenAI.ChatModelDeployment,
settings.AzureOpenAI.Endpoint,
new AzureCliCredential());
Kernel kernel = builder.Build();
Inisialisasi objek kernel:
kernel = Kernel()
Fitur saat ini tidak tersedia di Java.
Mari kita juga membuat instans Kernel kedua melalui kloning dan menambahkan plug-in yang akan memungkinkan tinjauan untuk menempatkan konten yang diperbarui di clip-board.
Kernel toolKernel = kernel.Clone();
toolKernel.Plugins.AddFromType<ClipboardAccess>();
Fitur saat ini tidak tersedia di Java.
Plugin Clipboard dapat didefinisikan sebagai bagian dari sampel.
private sealed class ClipboardAccess
{
[KernelFunction]
[Description("Copies the provided content to the clipboard.")]
public static void SetClipboard(string content)
{
if (string.IsNullOrWhiteSpace(content))
{
return;
}
using Process clipProcess = Process.Start(
new ProcessStartInfo
{
FileName = "clip",
RedirectStandardInput = true,
UseShellExecute = false,
});
clipProcess.StandardInput.Write(content);
clipProcess.StandardInput.Close();
}
}
Fitur saat ini tidak tersedia di Java.
Pengertian Agen
Mari kita nyatakan nama agen sebagai const sehingga mereka mungkin dirujuk dalam strategi AgentGroupChat:
const string ReviewerName = "Reviewer";
const string WriterName = "Writer";
Kami akan mendeklarasikan nama agen sebagai "Peninjau" dan "Penulis."
REVIEWER_NAME = "Reviewer"
COPYWRITER_NAME = "Writer"
Fitur saat ini tidak tersedia di Java.
Menentukan agen Peninjau menggunakan pola yang dijelaskan dalam Cara: Agen Penyelesaian Obrolan.
Di sini Peninjau diberi peran menanggapi input pengguna, memberikan arahan ke agen Penulis, dan memverifikasi hasil agen Penulis.
ChatCompletionAgent agentReviewer =
new()
{
Name = ReviewerName,
Instructions =
"""
Your responsibility is to review and identify how to improve user provided content.
If the user has providing input or direction for content already provided, specify how to address this input.
Never directly perform the correction or provide example.
Once the content has been updated in a subsequent response, you will review the content again until satisfactory.
Always copy satisfactory content to the clipboard using available tools and inform user.
RULES:
- Only identify suggestions that are specific and actionable.
- Verify previous suggestions have been addressed.
- Never repeat previous suggestions.
""",
Kernel = toolKernel,
Arguments =
new KernelArguments(
new AzureOpenAIPromptExecutionSettings()
{
FunctionChoiceBehavior = FunctionChoiceBehavior.Auto()
})
};
agent_reviewer = ChatCompletionAgent(
kernel=kernel,
name=REVIEWER_NAME,
instructions="""
Your responsibility is to review and identify how to improve user provided content.
If the user has provided input or direction for content already provided, specify how to address this input.
Never directly perform the correction or provide an example.
Once the content has been updated in a subsequent response, review it again until it is satisfactory.
RULES:
- Only identify suggestions that are specific and actionable.
- Verify previous suggestions have been addressed.
- Never repeat previous suggestions.
""",
)
Fitur saat ini tidak tersedia di Java.
Agen Writer serupa, tetapi tidak memerlukan spesifikasi Pengaturan Eksekusi karena tidak dikonfigurasi dengan plug-in.
Di sini Penulis diberi tugas tujuan tunggal, ikuti arah dan tulis ulang konten.
ChatCompletionAgent agentWriter =
new()
{
Name = WriterName,
Instructions =
"""
Your sole responsibility is to rewrite content according to review suggestions.
- Always apply all review direction.
- Always revise the content in its entirety without explanation.
- Never address the user.
""",
Kernel = kernel,
};
Agen Writer memiliki kesamaan. Diberikan sebuah tugas dengan satu tujuan: ikuti arahan dan tulis ulang kontennya.
agent_writer = ChatCompletionAgent(
kernel=kernel,
name=WRITER_NAME,
instructions="""
Your sole responsibility is to rewrite content according to review suggestions.
- Always apply all review directions.
- Always revise the content in its entirety without explanation.
- Never address the user.
""",
)
Fitur saat ini tidak tersedia di Java.
Definisi Percakapan
Untuk menentukan AgentGroupChat, perlu mempertimbangkan strategi dalam memilih giliran Agent dan kapan harus keluar dari perulangan Obrolan. Untuk kedua pertimbangan ini, kami akan menentukan Fungsi Prompt Kernel.
Orang pertama yang merenungkan pilihan Agent:
Menggunakan AgentGroupChat.CreatePromptFunctionForStrategy menyediakan mekanisme yang nyaman untuk menghindari pengodean HTML dari parameter pesan.
KernelFunction selectionFunction =
AgentGroupChat.CreatePromptFunctionForStrategy(
$$$"""
Examine the provided RESPONSE and choose the next participant.
State only the name of the chosen participant without explanation.
Never choose the participant named in the RESPONSE.
Choose only from these participants:
- {{{ReviewerName}}}
- {{{WriterName}}}
Always follow these rules when choosing the next participant:
- If RESPONSE is user input, it is {{{ReviewerName}}}'s turn.
- If RESPONSE is by {{{ReviewerName}}}, it is {{{WriterName}}}'s turn.
- If RESPONSE is by {{{WriterName}}}, it is {{{ReviewerName}}}'s turn.
RESPONSE:
{{$lastmessage}}
""",
safeParameterNames: "lastmessage");
selection_function = KernelFunctionFromPrompt(
function_name="selection",
prompt=f"""
Examine the provided RESPONSE and choose the next participant.
State only the name of the chosen participant without explanation.
Never choose the participant named in the RESPONSE.
Choose only from these participants:
- {REVIEWER_NAME}
- {WRITER_NAME}
Rules:
- If RESPONSE is user input, it is {REVIEWER_NAME}'s turn.
- If RESPONSE is by {REVIEWER_NAME}, it is {WRITER_NAME}'s turn.
- If RESPONSE is by {WRITER_NAME}, it is {REVIEWER_NAME}'s turn.
RESPONSE:
{{{{$lastmessage}}}}
"""
)
Fitur saat ini tidak tersedia di Java.
Yang kedua akan mengevaluasi kapan harus keluar dari loop Obrolan
const string TerminationToken = "yes";
KernelFunction terminationFunction =
AgentGroupChat.CreatePromptFunctionForStrategy(
$$$"""
Examine the RESPONSE and determine whether the content has been deemed satisfactory.
If content is satisfactory, respond with a single word without explanation: {{{TerminationToken}}}.
If specific suggestions are being provided, it is not satisfactory.
If no correction is suggested, it is satisfactory.
RESPONSE:
{{$lastmessage}}
""",
safeParameterNames: "lastmessage");
termination_keyword = "yes"
termination_function = KernelFunctionFromPrompt(
function_name="termination",
prompt=f"""
Examine the RESPONSE and determine whether the content has been deemed satisfactory.
If the content is satisfactory, respond with a single word without explanation: {termination_keyword}.
If specific suggestions are being provided, it is not satisfactory.
If no correction is suggested, it is satisfactory.
RESPONSE:
{{{{$lastmessage}}}}
"""
)
Fitur saat ini tidak tersedia di Java.
Kedua Strategi ini hanya akan membutuhkan pengetahuan tentang pesan Obrolan terbaru. Ini akan mengurangi penggunaan token dan membantu meningkatkan performa:
ChatHistoryTruncationReducer historyReducer = new(1);
history_reducer = ChatHistoryTruncationReducer(target_count=1)
Fitur saat ini tidak tersedia di Java.
Akhirnya kita siap untuk menggabungkan semuanya ke dalam definisi AgentGroupChat kita.
Pembuatan AgentGroupChat melibatkan:
- Sertakan kedua agen dalam konstruktor.
- Definisikan
KernelFunctionSelectionStrategymenggunakan instansKernelFunctiondanKernelyang telah ditentukan sebelumnya. - Definisikan
KernelFunctionTerminationStrategymenggunakan instansKernelFunctiondanKernelyang telah ditentukan sebelumnya.
Perhatikan bahwa setiap strategi bertanggung jawab untuk mengurai hasilnya KernelFunction .
AgentGroupChat chat =
new(agentReviewer, agentWriter)
{
ExecutionSettings = new AgentGroupChatSettings
{
SelectionStrategy =
new KernelFunctionSelectionStrategy(selectionFunction, kernel)
{
// Always start with the editor agent.
InitialAgent = agentReviewer,
// Save tokens by only including the final response
HistoryReducer = historyReducer,
// The prompt variable name for the history argument.
HistoryVariableName = "lastmessage",
// Returns the entire result value as a string.
ResultParser = (result) => result.GetValue<string>() ?? agentReviewer.Name
},
TerminationStrategy =
new KernelFunctionTerminationStrategy(terminationFunction, kernel)
{
// Only evaluate for editor's response
Agents = [agentReviewer],
// Save tokens by only including the final response
HistoryReducer = historyReducer,
// The prompt variable name for the history argument.
HistoryVariableName = "lastmessage",
// Limit total number of turns
MaximumIterations = 12,
// Customer result parser to determine if the response is "yes"
ResultParser = (result) => result.GetValue<string>()?.Contains(TerminationToken, StringComparison.OrdinalIgnoreCase) ?? false
}
}
};
Console.WriteLine("Ready!");
Pembuatan AgentGroupChat melibatkan:
- Sertakan kedua agen dalam konstruktor.
- Definisikan
KernelFunctionSelectionStrategymenggunakan instansKernelFunctiondanKernelyang telah ditentukan sebelumnya. - Definisikan
KernelFunctionTerminationStrategymenggunakan instansKernelFunctiondanKernelyang telah ditentukan sebelumnya.
Perhatikan bahwa setiap strategi bertanggung jawab untuk mengurai hasilnya KernelFunction .
chat = AgentGroupChat(
agents=[agent_reviewer, agent_writer],
selection_strategy=KernelFunctionSelectionStrategy(
initial_agent=agent_reviewer,
function=selection_function,
kernel=kernel,
result_parser=lambda result: str(result.value[0]).strip() if result.value[0] is not None else WRITER_NAME,
history_variable_name="lastmessage",
history_reducer=history_reducer,
),
termination_strategy=KernelFunctionTerminationStrategy(
agents=[agent_reviewer],
function=termination_function,
kernel=kernel,
result_parser=lambda result: termination_keyword in str(result.value[0]).lower(),
history_variable_name="lastmessage",
maximum_iterations=10,
history_reducer=history_reducer,
),
)
lastmessage
history_variable_name sesuai dengan KernelFunctionSelectionStrategy dan perintah KernelFunctionTerminationStrategy yang ditentukan di atas. Di sinilah pesan terakhir ditempatkan saat merender prompt.
Fitur saat ini tidak tersedia di Java.
Perulangan Obrolan
Akhirnya, kita dapat mengoordinasikan interaksi antara pengguna dan AgentGroupChat. Mulailah dengan membuat loop kosong.
Catatan: Tidak seperti contoh lain, tidak ada riwayat eksternal atau utas yang dikelola di sini.
AgentGroupChatmengelola riwayat percakapan secara internal.
bool isComplete = false;
do
{
} while (!isComplete);
is_complete: bool = False
while not is_complete:
# operational logic
Fitur saat ini tidak tersedia di Java.
Sekarang mari kita tangkap input pengguna di dalam loop sebelumnya. Dalam hal ini:
- Input kosong akan diabaikan
- Istilah
EXITakan memberi sinyal bahwa percakapan selesai - Istilah
RESETakan menghapus riwayatAgentGroupChat - Istilah apa pun yang dimulai dengan
@akan diperlakukan sebagai jalur file yang kontennya akan disediakan sebagai input - Input yang valid akan ditambahkan ke
AgentGroupChatsebagai pesan pengguna .
Console.WriteLine();
Console.Write("> ");
string input = Console.ReadLine();
if (string.IsNullOrWhiteSpace(input))
{
continue;
}
input = input.Trim();
if (input.Equals("EXIT", StringComparison.OrdinalIgnoreCase))
{
isComplete = true;
break;
}
if (input.Equals("RESET", StringComparison.OrdinalIgnoreCase))
{
await chat.ResetAsync();
Console.WriteLine("[Conversation has been reset]");
continue;
}
if (input.StartsWith("@", StringComparison.Ordinal) && input.Length > 1)
{
string filePath = input.Substring(1);
try
{
if (!File.Exists(filePath))
{
Console.WriteLine($"Unable to access file: {filePath}");
continue;
}
input = File.ReadAllText(filePath);
}
catch (Exception)
{
Console.WriteLine($"Unable to access file: {filePath}");
continue;
}
}
chat.AddChatMessage(new ChatMessageContent(AuthorRole.User, input));
Sekarang mari kita tangkap input pengguna di dalam loop sebelumnya. Dalam hal ini:
- Input kosong akan diabaikan.
- Istilah
exitakan memberi sinyal bahwa percakapan selesai. - Istilah
resetakan menghapus riwayatAgentGroupChat. - Istilah apa pun yang dimulai dengan
@akan diperlakukan sebagai jalur file yang kontennya akan disediakan sebagai input. - Input yang valid akan ditambahkan ke
AgentGroupChatsebagai pesan pengguna .
Logika operasi di dalam pengulangan while terlihat seperti:
print()
user_input = input("User > ").strip()
if not user_input:
continue
if user_input.lower() == "exit":
is_complete = True
break
if user_input.lower() == "reset":
await chat.reset()
print("[Conversation has been reset]")
continue
# Try to grab files from the script's current directory
if user_input.startswith("@") and len(user_input) > 1:
file_name = user_input[1:]
script_dir = os.path.dirname(os.path.abspath(__file__))
file_path = os.path.join(script_dir, file_name)
try:
if not os.path.exists(file_path):
print(f"Unable to access file: {file_path}")
continue
with open(file_path, "r", encoding="utf-8") as file:
user_input = file.read()
except Exception:
print(f"Unable to access file: {file_path}")
continue
# Add the current user_input to the chat
await chat.add_chat_message(message=user_input)
Fitur saat ini tidak tersedia di Java.
Untuk memulai kolaborasi Agent sebagai respons terhadap input pengguna dan memunculkan respons Agent, panggil AgentGroupChat; namun sebelumnya, pastikan untuk mengatur ulang status Penyelesaian dari pemanggilan sebelumnya.
Catatan: Kegagalan layanan dikenali dan ditampilkan untuk menghindari kegagalan perulangan percakapan.
chat.IsComplete = false;
try
{
await foreach (ChatMessageContent response in chat.InvokeAsync())
{
Console.WriteLine();
Console.WriteLine($"{response.AuthorName.ToUpperInvariant()}:{Environment.NewLine}{response.Content}");
}
}
catch (HttpOperationException exception)
{
Console.WriteLine(exception.Message);
if (exception.InnerException != null)
{
Console.WriteLine(exception.InnerException.Message);
if (exception.InnerException.Data.Count > 0)
{
Console.WriteLine(JsonSerializer.Serialize(exception.InnerException.Data, new JsonSerializerOptions() { WriteIndented = true }));
}
}
}
try:
async for response in chat.invoke():
if response is None or not response.name:
continue
print()
print(f"# {response.name.upper()}:\n{response.content}")
except Exception as e:
print(f"Error during chat invocation: {e}")
# Reset the chat's complete flag for the new conversation round.
chat.is_complete = False
Fitur saat ini tidak tersedia di Java.
Akhir
Menggabungkan semua langkah, kami sudah memiliki kode lengkap untuk contoh ini. Implementasi lengkap disediakan di bawah ini.
Coba gunakan input yang disarankan ini:
- Hai
- {"message: "halo dunia"}
- {"message": "halo dunia"}
- Semantic Kernel (SK) adalah SDK sumber terbuka yang memungkinkan pengembang untuk membangun dan mengatur alur kerja AI kompleks yang melibatkan pemrosesan bahasa alami (NLP) dan model pembelajaran mesin. Ini menyediakan platform fleksibel untuk mengintegrasikan kemampuan AI seperti pencarian semantik, ringkasan teks, dan sistem dialog ke dalam aplikasi. Dengan SK, Anda dapat dengan mudah menggabungkan layanan dan model AI yang berbeda, menentukan hubungannya, dan mengatur interaksi di antara mereka.
- jadikan ini dua paragraf
- Terima kasih
- @.\WomensSuffrage.txt
- bagus, tapi apakah itu sudah siap untuk dosen saya di kampus?
using System;
using System.ComponentModel;
using System.Diagnostics;
using System.IO;
using System.Text.Json;
using System.Threading.Tasks;
using Azure.Identity;
using Microsoft.SemanticKernel;
using Microsoft.SemanticKernel.Agents;
using Microsoft.SemanticKernel.Agents.Chat;
using Microsoft.SemanticKernel.Agents.History;
using Microsoft.SemanticKernel.ChatCompletion;
using Microsoft.SemanticKernel.Connectors.AzureOpenAI;
namespace AgentsSample;
public static class Program
{
public static async Task Main()
{
// Load configuration from environment variables or user secrets.
Settings settings = new();
Console.WriteLine("Creating kernel...");
IKernelBuilder builder = Kernel.CreateBuilder();
builder.AddAzureOpenAIChatCompletion(
settings.AzureOpenAI.ChatModelDeployment,
settings.AzureOpenAI.Endpoint,
new AzureCliCredential());
Kernel kernel = builder.Build();
Kernel toolKernel = kernel.Clone();
toolKernel.Plugins.AddFromType<ClipboardAccess>();
Console.WriteLine("Defining agents...");
const string ReviewerName = "Reviewer";
const string WriterName = "Writer";
ChatCompletionAgent agentReviewer =
new()
{
Name = ReviewerName,
Instructions =
"""
Your responsibility is to review and identify how to improve user provided content.
If the user has providing input or direction for content already provided, specify how to address this input.
Never directly perform the correction or provide example.
Once the content has been updated in a subsequent response, you will review the content again until satisfactory.
Always copy satisfactory content to the clipboard using available tools and inform user.
RULES:
- Only identify suggestions that are specific and actionable.
- Verify previous suggestions have been addressed.
- Never repeat previous suggestions.
""",
Kernel = toolKernel,
Arguments = new KernelArguments(new AzureOpenAIPromptExecutionSettings() { FunctionChoiceBehavior = FunctionChoiceBehavior.Auto() })
};
ChatCompletionAgent agentWriter =
new()
{
Name = WriterName,
Instructions =
"""
Your sole responsibility is to rewrite content according to review suggestions.
- Always apply all review direction.
- Always revise the content in its entirety without explanation.
- Never address the user.
""",
Kernel = kernel,
};
KernelFunction selectionFunction =
AgentGroupChat.CreatePromptFunctionForStrategy(
$$$"""
Examine the provided RESPONSE and choose the next participant.
State only the name of the chosen participant without explanation.
Never choose the participant named in the RESPONSE.
Choose only from these participants:
- {{{ReviewerName}}}
- {{{WriterName}}}
Always follow these rules when choosing the next participant:
- If RESPONSE is user input, it is {{{ReviewerName}}}'s turn.
- If RESPONSE is by {{{ReviewerName}}}, it is {{{WriterName}}}'s turn.
- If RESPONSE is by {{{WriterName}}}, it is {{{ReviewerName}}}'s turn.
RESPONSE:
{{$lastmessage}}
""",
safeParameterNames: "lastmessage");
const string TerminationToken = "yes";
KernelFunction terminationFunction =
AgentGroupChat.CreatePromptFunctionForStrategy(
$$$"""
Examine the RESPONSE and determine whether the content has been deemed satisfactory.
If content is satisfactory, respond with a single word without explanation: {{{TerminationToken}}}.
If specific suggestions are being provided, it is not satisfactory.
If no correction is suggested, it is satisfactory.
RESPONSE:
{{$lastmessage}}
""",
safeParameterNames: "lastmessage");
ChatHistoryTruncationReducer historyReducer = new(1);
AgentGroupChat chat =
new(agentReviewer, agentWriter)
{
ExecutionSettings = new AgentGroupChatSettings
{
SelectionStrategy =
new KernelFunctionSelectionStrategy(selectionFunction, kernel)
{
// Always start with the editor agent.
InitialAgent = agentReviewer,
// Save tokens by only including the final response
HistoryReducer = historyReducer,
// The prompt variable name for the history argument.
HistoryVariableName = "lastmessage",
// Returns the entire result value as a string.
ResultParser = (result) => result.GetValue<string>() ?? agentReviewer.Name
},
TerminationStrategy =
new KernelFunctionTerminationStrategy(terminationFunction, kernel)
{
// Only evaluate for editor's response
Agents = [agentReviewer],
// Save tokens by only including the final response
HistoryReducer = historyReducer,
// The prompt variable name for the history argument.
HistoryVariableName = "lastmessage",
// Limit total number of turns
MaximumIterations = 12,
// Customer result parser to determine if the response is "yes"
ResultParser = (result) => result.GetValue<string>()?.Contains(TerminationToken, StringComparison.OrdinalIgnoreCase) ?? false
}
}
};
Console.WriteLine("Ready!");
bool isComplete = false;
do
{
Console.WriteLine();
Console.Write("> ");
string input = Console.ReadLine();
if (string.IsNullOrWhiteSpace(input))
{
continue;
}
input = input.Trim();
if (input.Equals("EXIT", StringComparison.OrdinalIgnoreCase))
{
isComplete = true;
break;
}
if (input.Equals("RESET", StringComparison.OrdinalIgnoreCase))
{
await chat.ResetAsync();
Console.WriteLine("[Conversation has been reset]");
continue;
}
if (input.StartsWith("@", StringComparison.Ordinal) && input.Length > 1)
{
string filePath = input.Substring(1);
try
{
if (!File.Exists(filePath))
{
Console.WriteLine($"Unable to access file: {filePath}");
continue;
}
input = File.ReadAllText(filePath);
}
catch (Exception)
{
Console.WriteLine($"Unable to access file: {filePath}");
continue;
}
}
chat.AddChatMessage(new ChatMessageContent(AuthorRole.User, input));
chat.IsComplete = false;
try
{
await foreach (ChatMessageContent response in chat.InvokeAsync())
{
Console.WriteLine();
Console.WriteLine($"{response.AuthorName.ToUpperInvariant()}:{Environment.NewLine}{response.Content}");
}
}
catch (HttpOperationException exception)
{
Console.WriteLine(exception.Message);
if (exception.InnerException != null)
{
Console.WriteLine(exception.InnerException.Message);
if (exception.InnerException.Data.Count > 0)
{
Console.WriteLine(JsonSerializer.Serialize(exception.InnerException.Data, new JsonSerializerOptions() { WriteIndented = true }));
}
}
}
} while (!isComplete);
}
private sealed class ClipboardAccess
{
[KernelFunction]
[Description("Copies the provided content to the clipboard.")]
public static void SetClipboard(string content)
{
if (string.IsNullOrWhiteSpace(content))
{
return;
}
using Process clipProcess = Process.Start(
new ProcessStartInfo
{
FileName = "clip",
RedirectStandardInput = true,
UseShellExecute = false,
});
clipProcess.StandardInput.Write(content);
clipProcess.StandardInput.Close();
}
}
}
Menyatukan semua langkah, kita sekarang sudah memiliki kode akhir untuk contoh ini. Implementasi lengkap ditunjukkan di bawah ini.
Anda dapat mencoba menggunakan salah satu input yang disarankan. Saat obrolan agen dimulai, agen akan bertukar pesan dengan beberapa iterasi sampai agen peninjau puas dengan pekerjaan copywriter. Perulangan while memastikan percakapan berlanjut, bahkan jika obrolan awalnya dianggap selesai, dengan mengatur ulang bendera is_complete ke False.
- Rozes merah, violetz biru.
- Semantic Kernel (SK) adalah SDK sumber terbuka yang memungkinkan pengembang untuk membangun dan mengatur alur kerja AI kompleks yang melibatkan pemrosesan bahasa alami (NLP) dan model pembelajaran mesin. Ini menyediakan platform fleksibel untuk mengintegrasikan kemampuan AI seperti pencarian semantik, ringkasan teks, dan sistem dialog ke dalam aplikasi. Dengan SK, Anda dapat dengan mudah menggabungkan layanan dan model AI yang berbeda, menentukan hubungannya, dan mengatur interaksi di antara mereka.
- Buat dua paragraf ini
- Terima kasih
- @WomensSuffrage.txt
- Ini bagus, tapi apakah sudah siap untuk dosen saya di perguruan tinggi?
Petunjuk / Saran
Anda dapat mereferensikan file apa pun dengan menyediakan @<file_path_to_file>. Untuk merujuk teks "WomensSuffrage" yang disebutkan sebelumnya, unduh dari sini dan letakkan di direktori kerja Anda saat ini. Anda kemudian dapat mereferensikannya dengan @WomensSuffrage.txt.
import asyncio
import os
from semantic_kernel import Kernel
from semantic_kernel.agents import AgentGroupChat, ChatCompletionAgent
from semantic_kernel.agents.strategies import (
KernelFunctionSelectionStrategy,
KernelFunctionTerminationStrategy,
)
from semantic_kernel.connectors.ai.open_ai import AzureChatCompletion
from semantic_kernel.contents import ChatHistoryTruncationReducer
from semantic_kernel.functions import KernelFunctionFromPrompt
"""
The following sample demonstrates how to create a simple,
agent group chat that utilizes a Reviewer Chat Completion
Agent along with a Writer Chat Completion Agent to
complete a user's task.
"""
# Define agent names
REVIEWER_NAME = "Reviewer"
WRITER_NAME = "Writer"
def create_kernel() -> Kernel:
"""Creates a Kernel instance with an Azure OpenAI ChatCompletion service."""
kernel = Kernel()
kernel.add_service(service=AzureChatCompletion())
return kernel
async def main():
# Create a single kernel instance for all agents.
kernel = create_kernel()
# Create ChatCompletionAgents using the same kernel.
agent_reviewer = ChatCompletionAgent(
kernel=kernel,
name=REVIEWER_NAME,
instructions="""
Your responsibility is to review and identify how to improve user provided content.
If the user has provided input or direction for content already provided, specify how to address this input.
Never directly perform the correction or provide an example.
Once the content has been updated in a subsequent response, review it again until it is satisfactory.
RULES:
- Only identify suggestions that are specific and actionable.
- Verify previous suggestions have been addressed.
- Never repeat previous suggestions.
""",
)
agent_writer = ChatCompletionAgent(
kernel=kernel,
name=WRITER_NAME,
instructions="""
Your sole responsibility is to rewrite content according to review suggestions.
- Always apply all review directions.
- Always revise the content in its entirety without explanation.
- Never address the user.
""",
)
# Define a selection function to determine which agent should take the next turn.
selection_function = KernelFunctionFromPrompt(
function_name="selection",
prompt=f"""
Examine the provided RESPONSE and choose the next participant.
State only the name of the chosen participant without explanation.
Never choose the participant named in the RESPONSE.
Choose only from these participants:
- {REVIEWER_NAME}
- {WRITER_NAME}
Rules:
- If RESPONSE is user input, it is {REVIEWER_NAME}'s turn.
- If RESPONSE is by {REVIEWER_NAME}, it is {WRITER_NAME}'s turn.
- If RESPONSE is by {WRITER_NAME}, it is {REVIEWER_NAME}'s turn.
RESPONSE:
{{{{$lastmessage}}}}
""",
)
# Define a termination function where the reviewer signals completion with "yes".
termination_keyword = "yes"
termination_function = KernelFunctionFromPrompt(
function_name="termination",
prompt=f"""
Examine the RESPONSE and determine whether the content has been deemed satisfactory.
If the content is satisfactory, respond with a single word without explanation: {termination_keyword}.
If specific suggestions are being provided, it is not satisfactory.
If no correction is suggested, it is satisfactory.
RESPONSE:
{{{{$lastmessage}}}}
""",
)
history_reducer = ChatHistoryTruncationReducer(target_count=5)
# Create the AgentGroupChat with selection and termination strategies.
chat = AgentGroupChat(
agents=[agent_reviewer, agent_writer],
selection_strategy=KernelFunctionSelectionStrategy(
initial_agent=agent_reviewer,
function=selection_function,
kernel=kernel,
result_parser=lambda result: str(result.value[0]).strip() if result.value[0] is not None else WRITER_NAME,
history_variable_name="lastmessage",
history_reducer=history_reducer,
),
termination_strategy=KernelFunctionTerminationStrategy(
agents=[agent_reviewer],
function=termination_function,
kernel=kernel,
result_parser=lambda result: termination_keyword in str(result.value[0]).lower(),
history_variable_name="lastmessage",
maximum_iterations=10,
history_reducer=history_reducer,
),
)
print(
"Ready! Type your input, or 'exit' to quit, 'reset' to restart the conversation. "
"You may pass in a file path using @<path_to_file>."
)
is_complete = False
while not is_complete:
print()
user_input = input("User > ").strip()
if not user_input:
continue
if user_input.lower() == "exit":
is_complete = True
break
if user_input.lower() == "reset":
await chat.reset()
print("[Conversation has been reset]")
continue
# Try to grab files from the script's current directory
if user_input.startswith("@") and len(user_input) > 1:
file_name = user_input[1:]
script_dir = os.path.dirname(os.path.abspath(__file__))
file_path = os.path.join(script_dir, file_name)
try:
if not os.path.exists(file_path):
print(f"Unable to access file: {file_path}")
continue
with open(file_path, "r", encoding="utf-8") as file:
user_input = file.read()
except Exception:
print(f"Unable to access file: {file_path}")
continue
# Add the current user_input to the chat
await chat.add_chat_message(message=user_input)
try:
async for response in chat.invoke():
if response is None or not response.name:
continue
print()
print(f"# {response.name.upper()}:\n{response.content}")
except Exception as e:
print(f"Error during chat invocation: {e}")
# Reset the chat's complete flag for the new conversation round.
chat.is_complete = False
if __name__ == "__main__":
asyncio.run(main())
Anda mungkin menemukan kode lengkap, seperti yang ditunjukkan di atas, dalam repositori kami.
Fitur saat ini tidak tersedia di Java.