Skip to content

Commit

Permalink
Merge pull request #1002 from solliancenet/aa-e2e-sdwza-examples
Browse files Browse the repository at this point in the history
E2E examples 12 & 12: KM Agent on SDZWA
  • Loading branch information
ciprianjichici authored May 24, 2024
2 parents dbbdbfe + 34facea commit 285e0d9
Show file tree
Hide file tree
Showing 10 changed files with 306 additions and 11 deletions.
78 changes: 78 additions & 0 deletions tests/dotnet/Core.Examples/Catalogs/AgentCatalog.cs
Original file line number Diff line number Diff line change
Expand Up @@ -176,6 +176,84 @@ public static class AgentCatalog
}
},
new KnowledgeManagementAgent
{
Name = TestAgentNames.SemanticKernelSDZWA,
Description = "Knowledge Management Agent that queries the San Diego Zoo Wildlife Alliance journals using SemanticKernel.",
InlineContext = false,
SessionsEnabled = true,
Vectorization = new AgentVectorizationSettings
{
DedicatedPipeline = false,
IndexingProfileObjectId = null,
TextEmbeddingProfileObjectId = null
},
ConversationHistory = new ConversationHistory
{
Enabled = true,
MaxHistory = 10
},
Gatekeeper = new Gatekeeper
{
UseSystemSetting = false
},
OrchestrationSettings = new OrchestrationSettings
{
Orchestrator = LLMOrchestrationServiceNames.SemanticKernel,
EndpointConfiguration = new Dictionary<string, object>
{
{ "auth_type", "key" },
{ "provider", "microsoft" },
{ "endpoint", "FoundationaLLM:AzureOpenAI:API:Endpoint" },
{ "api_key", "FoundationaLLM:AzureOpenAI:API:Key" },
{ "api_version", "FoundationaLLM:AzureOpenAI:API:Version" }
},
ModelParameters = new Dictionary<string, object>
{
{ "temperature", 0 },
{ "deployment_name", "completions" }
}
}
},
new KnowledgeManagementAgent
{
Name = TestAgentNames.LangChainSDZWA,
Description = "Knowledge Management Agent that queries the San Diego Zoo Wildlife Alliance journals using LangChain.",
InlineContext = false,
SessionsEnabled = true,
Vectorization = new AgentVectorizationSettings
{
DedicatedPipeline = false,
IndexingProfileObjectId = null,
TextEmbeddingProfileObjectId = null
},
ConversationHistory = new ConversationHistory
{
Enabled = true,
MaxHistory = 10
},
Gatekeeper = new Gatekeeper
{
UseSystemSetting = false
},
OrchestrationSettings = new OrchestrationSettings
{
Orchestrator = LLMOrchestrationServiceNames.LangChain,
EndpointConfiguration = new Dictionary<string, object>
{
{ "auth_type", "key" },
{ "provider", "microsoft" },
{ "endpoint", "FoundationaLLM:AzureOpenAI:API:Endpoint" },
{ "api_key", "FoundationaLLM:AzureOpenAI:API:Key" },
{ "api_version", "FoundationaLLM:AzureOpenAI:API:Version" }
},
ModelParameters = new Dictionary<string, object>
{
{ "temperature", 0 },
{ "deployment_name", "completions" }
}
}
},
new KnowledgeManagementAgent
{
Name = TestAgentNames.ConversationGeneratorAgent,
Description = "An agent that creates conversations based on product descriptions.",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,8 @@ public static class IndexingProfilesCatalog
public static readonly List<IndexingProfile> Items =
[
new IndexingProfile { Name = "indexing_profile_really_big", Indexer = IndexerType.AzureAISearchIndexer, Settings = new Dictionary<string, string>{ { "IndexName", "reallybig" }, { "TopN", "3" }, { "Filters", "" }, { "EmbeddingFieldName", "Embedding" }, { "TextFieldName", "Text" } }, ConfigurationReferences = new Dictionary<string, string>{ { "AuthenticationType", "FoundationaLLM:Vectorization:AzureAISearchIndexingService:AuthenticationType" }, { "Endpoint", "FoundationaLLM:Vectorization:AzureAISearchIndexingService:Endpoint" } } },
new IndexingProfile { Name = "indexing_profile_pdf", Indexer = IndexerType.AzureAISearchIndexer, Settings = new Dictionary<string, string>{ { "IndexName", "pdf" }, { "TopN", "3" }, { "Filters", "" }, { "EmbeddingFieldName", "Embedding" }, { "TextFieldName", "Text" } }, ConfigurationReferences = new Dictionary<string, string>{ { "AuthenticationType", "FoundationaLLM:Vectorization:AzureAISearchIndexingService:AuthenticationType" }, { "Endpoint", "FoundationaLLM:Vectorization:AzureAISearchIndexingService:Endpoint" } } }
new IndexingProfile { Name = "indexing_profile_pdf", Indexer = IndexerType.AzureAISearchIndexer, Settings = new Dictionary<string, string>{ { "IndexName", "pdf" }, { "TopN", "3" }, { "Filters", "" }, { "EmbeddingFieldName", "Embedding" }, { "TextFieldName", "Text" } }, ConfigurationReferences = new Dictionary<string, string>{ { "AuthenticationType", "FoundationaLLM:Vectorization:AzureAISearchIndexingService:AuthenticationType" }, { "Endpoint", "FoundationaLLM:Vectorization:AzureAISearchIndexingService:Endpoint" } } },
new IndexingProfile { Name = "indexing_profile_sdzwa", Indexer = IndexerType.AzureAISearchIndexer, Settings = new Dictionary<string, string>{ { "IndexName", "fllm-pdf" }, { "TopN", "3" }, { "Filters", "" }, { "EmbeddingFieldName", "Embedding" }, { "TextFieldName", "Text" } }, ConfigurationReferences = new Dictionary<string, string>{ { "AuthenticationType", "FoundationaLLM:Vectorization:AzureAISearchIndexingService:AuthenticationType" }, { "Endpoint", "FoundationaLLM:Vectorization:AzureAISearchIndexingService:Endpoint" } } }
];

public static List<IndexingProfile> GetIndexingProfiles()
Expand Down
26 changes: 22 additions & 4 deletions tests/dotnet/Core.Examples/Catalogs/PromptCatalog.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ namespace FoundationaLLM.Core.Examples.Catalogs
public static class PromptCatalog
{
#region multipart prompts

/// <summary>
/// Catalog of multipart prompts.
/// </summary>
Expand All @@ -25,8 +26,7 @@ Provide concise answers that are polite and professional.
Context:
The Rosetta Stone, discovered in 1799 by French soldiers in Egypt, is an ancient stele inscribed with the same text in three scripts: Egyptian hieroglyphs, Demotic script, and Ancient Greek. The stone was found in a small village in the Delta called Rosetta (Rashid). It dates back to 196 BC, during the reign of Pharaoh Ptolemy V. The Rosetta Stone proved crucial in deciphering Egyptian hieroglyphs, primarily through the efforts of the French scholar Jean-François Champollion in 1822. This breakthrough provided the key to understanding much about ancient Egyptian history and culture that had been lost for centuries.
The Rosetta Stone is a fragment of a larger stele that originally had no decorative elements but featured a decree affirming the royal cult of the 13-year-old Ptolemy V. The text of the decree was composed by a council of priests to honor the pharaoh. The reasons for the decree and its broader implications on Egyptian society during Ptolemy V’s reign are areas of ongoing research and debate.
Today, the Rosetta Stone is housed in the British Museum in London, where it remains one of the most visited and studied artifacts in their collection. Its historical and linguistic significance continues to make it a subject of scholarly and public fascination.
"
Today, the Rosetta Stone is housed in the British Museum in London, where it remains one of the most visited and studied artifacts in their collection. Its historical and linguistic significance continues to make it a subject of scholarly and public fascination."
},
new MultipartPrompt
{
Expand All @@ -37,8 +37,7 @@ Provide concise answers that are polite and professional.
Context:
The Rosetta Stone, discovered in 1799 by French soldiers in Egypt, is an ancient stele inscribed with the same text in three scripts: Egyptian hieroglyphs, Demotic script, and Ancient Greek. The stone was found in a small village in the Delta called Rosetta (Rashid). It dates back to 196 BC, during the reign of Pharaoh Ptolemy V. The Rosetta Stone proved crucial in deciphering Egyptian hieroglyphs, primarily through the efforts of the French scholar Jean-François Champollion in 1822. This breakthrough provided the key to understanding much about ancient Egyptian history and culture that had been lost for centuries.
The Rosetta Stone is a fragment of a larger stele that originally had no decorative elements but featured a decree affirming the royal cult of the 13-year-old Ptolemy V. The text of the decree was composed by a council of priests to honor the pharaoh. The reasons for the decree and its broader implications on Egyptian society during Ptolemy V’s reign are areas of ongoing research and debate.
Today, the Rosetta Stone is housed in the British Museum in London, where it remains one of the most visited and studied artifacts in their collection. Its historical and linguistic significance continues to make it a subject of scholarly and public fascination.
"
Today, the Rosetta Stone is housed in the British Museum in London, where it remains one of the most visited and studied artifacts in their collection. Its historical and linguistic significance continues to make it a subject of scholarly and public fascination."
},
new MultipartPrompt
{
Expand All @@ -55,6 +54,24 @@ Provide concise answers that are polite and professional."
Provide concise answers that are polite and professional."
},
new MultipartPrompt
{
Name = TestAgentNames.SemanticKernelSDZWA,
Description = $"Prompt template for the {TestAgentNames.SemanticKernelSDZWA} agent.",
Prefix = @"You are the San Diego Zoo assistant named Sandy.
You are responsible for answering questions related to the San Diego Zoo that is contained in the journal publications.
Only answer questions that relate to the Zoo and journal content.
Do not make anything up. Use only the data provided."
},
new MultipartPrompt
{
Name = TestAgentNames.LangChainSDZWA,
Description = $"Prompt template for the {TestAgentNames.LangChainSDZWA} agent.",
Prefix = @"You are the San Diego Zoo assistant named Sandy.
You are responsible for answering questions related to the San Diego Zoo that is contained in the journal publications.
Only answer questions that relate to the Zoo and journal content.
Do not make anything up. Use only the data provided."
},
new MultipartPrompt
{
Name = TestAgentNames.ConversationGeneratorAgent,
Description = $"Prompt template for the {TestAgentNames.ConversationGeneratorAgent} agent.",
Expand Down Expand Up @@ -82,6 +99,7 @@ Do you have any adventure watches?
"
}
];

#endregion

/// <summary>
Expand Down
8 changes: 8 additions & 0 deletions tests/dotnet/Core.Examples/Constants/TestAgentNames.cs
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,14 @@ public static class TestAgentNames
/// </summary>
public const string LangChainAgentName = "KMAgentWithLangChain";
/// <summary>
/// The name of the SDZWA semantic kernel agent.
/// </summary>
public const string SemanticKernelSDZWA = "KMAgentWithSemanticKernelSDZWA";
/// <summary>
/// The name of the SDZWA lang chain agent.
/// </summary>
public const string LangChainSDZWA = "KMAgentWithLangChainSDZWA";
/// <summary>
/// The name of the agent that is used to generate conversations about products.
/// </summary>
public const string ConversationGeneratorAgent = "ConversationGeneratorAgent";
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
using FoundationaLLM.Core.Examples.Constants;
using FoundationaLLM.Core.Examples.Interfaces;
using FoundationaLLM.Core.Examples.Setup;
using Xunit.Abstractions;

namespace FoundationaLLM.Core.Examples
{
/// <summary>
/// Example class for the Knowledge Management agent with LangChain.
/// </summary>
public class Example0011_KnowledgeManagementAgentWithSemanticKernel : BaseTest, IClassFixture<TestFixture>
{
private readonly IAgentConversationTestService _agentConversationTestService;

private string textEmbeddingProfileName = "text_embedding_profile_generic";
private string indexingProfileName = "indexing_profile_sdzwa";

public Example0011_KnowledgeManagementAgentWithSemanticKernel(ITestOutputHelper output, TestFixture fixture)
: base(output, fixture.ServiceProvider)
{
_agentConversationTestService = GetService<IAgentConversationTestService>();
}

[Fact]
public async Task RunAsync()
{
WriteLine("============ Knowledge Management agent with Semantic Kernel on SDZWA ============");
await RunExampleAsync();
}

private async Task RunExampleAsync()
{
var agentName = TestAgentNames.SemanticKernelSDZWA;
var userPrompts = new List<string>
{
"Who are you?",
"Tell me one interesting facts about the San Diego Zoo?",
"How many animals does the San Diego Zoo host?",
"What does the San Diego Zoo do to treat illness among it's inhabitants?"
};

WriteLine($"Send questions to the {agentName} agent.");

var response = await _agentConversationTestService.RunAgentConversationWithSession(
agentName, userPrompts, null, true, indexingProfileName, textEmbeddingProfileName);

WriteLine($"Agent conversation history:");

var invalidAgentResponsesFound = 0;
foreach (var message in response)
{
WriteLine($"- {message.Sender}: {message.Text}");

if (string.Equals(message.Sender, Common.Constants.Agents.InputMessageRoles.Assistant, StringComparison.CurrentCultureIgnoreCase) &&
message.Text == TestResponseMessages.FailedCompletionResponse)
{
invalidAgentResponsesFound++;
}
}

Assert.True(invalidAgentResponsesFound == 0, $"{invalidAgentResponsesFound} invalid agent responses found.");
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
using FoundationaLLM.Core.Examples.Constants;
using FoundationaLLM.Core.Examples.Interfaces;
using FoundationaLLM.Core.Examples.Setup;
using Xunit.Abstractions;

namespace FoundationaLLM.Core.Examples
{
/// <summary>
/// Example class for the Knowledge Management agent with SemanticKernel.
/// </summary>
public class Example0012_KnowledgeManagementAgentWithLangChain : BaseTest, IClassFixture<TestFixture>
{
private readonly IAgentConversationTestService _agentConversationTestService;

private string textEmbeddingProfileName = "text_embedding_profile_generic";
private string indexingProfileName = "indexing_profile_sdzwa";

public Example0012_KnowledgeManagementAgentWithLangChain(ITestOutputHelper output, TestFixture fixture)
: base(output, fixture.ServiceProvider)
{
_agentConversationTestService = GetService<IAgentConversationTestService>();
}

[Fact]
public async Task RunAsync()
{
WriteLine("============ Knowledge Management agent with Lang Chain on SDZWA ============");
await RunExampleAsync();
}

private async Task RunExampleAsync()
{
var agentName = TestAgentNames.LangChainSDZWA;
var userPrompts = new List<string>
{
"Who are you?",
"Tell me one interesting facts about the San Diego Zoo?",
"How many animals does the San Diego Zoo host?",
"What does the San Diego Zoo do to treat illness among it's inhabitants?"
};

WriteLine($"Send questions to the {agentName} agent.");

var response = await _agentConversationTestService.RunAgentConversationWithSession(
agentName, userPrompts, null, true, indexingProfileName, textEmbeddingProfileName);

WriteLine($"Agent conversation history:");

var invalidAgentResponsesFound = 0;
foreach (var message in response)
{
WriteLine($"- {message.Sender}: {message.Text}");

if (string.Equals(message.Sender, Common.Constants.Agents.InputMessageRoles.Assistant, StringComparison.CurrentCultureIgnoreCase) &&
message.Text == TestResponseMessages.FailedCompletionResponse)
{
invalidAgentResponsesFound++;
}
}

Assert.True(invalidAgentResponsesFound == 0, $"{invalidAgentResponsesFound} invalid agent responses found.");
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,8 @@ public interface IAgentConversationTestService
/// not enable this option if you wish to use pre-existing resources, such as the default FoundationaLLM agent.</param>
/// <returns></returns>
Task<IEnumerable<Message>> RunAgentConversationWithSession(string agentName,
List<string> userPrompts, string? sessionId = null, bool createAgent = false);
List<string> userPrompts, string? sessionId = null, bool createAgent = false, string? indexingProfileName = null,
string? textEmbeddingProfileName = null, string? textPartitioningProfileName = null);

/// <summary>
/// Runs a single completion with an agent using the Core API and a chat session.
Expand Down
Loading

0 comments on commit 285e0d9

Please sign in to comment.