diff --git a/src/ChatApp.WebApi/Agents/CreativeWriterSession.cs b/src/ChatApp.WebApi/Agents/CreativeWriterSession.cs index 950349e..61171ec 100644 --- a/src/ChatApp.WebApi/Agents/CreativeWriterSession.cs +++ b/src/ChatApp.WebApi/Agents/CreativeWriterSession.cs @@ -8,6 +8,8 @@ using Microsoft.SemanticKernel.Agents.Chat; using Microsoft.SemanticKernel.Connectors.AzureOpenAI; using System.Text; +using Microsoft.SemanticKernel.PromptTemplates.Liquid; +using Microsoft.SemanticKernel.Prompty; namespace ChatApp.WebApi.Agents; @@ -20,7 +22,7 @@ public class CreativeWriterSession(Kernel kernel, Kernel bingKernel, Kernel vect internal async IAsyncEnumerable ProcessStreamingRequest(CreateWriterRequest createWriterRequest) { - ChatCompletionAgent researcherAgent = new(ReadFileForPromptTemplateConfig("./Agents/Prompts/researcher.yaml")) + ChatCompletionAgent researcherAgent = new(ReadPromptyFileForTemplateConfig("./Agents/Prompts/researcher.prompty"), new LiquidPromptTemplateFactory()) { Name = ResearcherName, Kernel = bingKernel, @@ -28,7 +30,7 @@ internal async IAsyncEnumerable ProcessStreamingRequest(C LoggerFactory = bingKernel.LoggerFactory }; - ChatCompletionAgent marketingAgent = new(ReadFileForPromptTemplateConfig("./Agents/Prompts/marketing.yaml")) + ChatCompletionAgent marketingAgent = new(ReadPromptyFileForTemplateConfig("./Agents/Prompts/marketing.prompty"), new LiquidPromptTemplateFactory()) { Name = MarketingName, Kernel = vectorSearchKernel, @@ -60,7 +62,7 @@ internal async IAsyncEnumerable ProcessStreamingRequest(C }); } - ChatCompletionAgent writerAgent = new(ReadFileForPromptTemplateConfig("./Agents/Prompts/writer.yaml")) + ChatCompletionAgent writerAgent = new(ReadPromptyFileForTemplateConfig("./Agents/Prompts/writer.prompty"), new LiquidPromptTemplateFactory()) { Name = WriterName, Kernel = kernel, @@ -68,7 +70,7 @@ internal async IAsyncEnumerable ProcessStreamingRequest(C LoggerFactory = kernel.LoggerFactory }; - ChatCompletionAgent editorAgent = new(ReadFileForPromptTemplateConfig("./Agents/Prompts/editor.yaml")) + ChatCompletionAgent editorAgent = new(ReadPromptyFileForTemplateConfig("./Agents/Prompts/editor.prompty"), new LiquidPromptTemplateFactory()) { Name = EditorName, Kernel = kernel, @@ -107,6 +109,13 @@ private static PromptTemplateConfig ReadFileForPromptTemplateConfig(string fileN string yaml = File.ReadAllText(fileName); return KernelFunctionYaml.ToPromptTemplateConfig(yaml); } + private static PromptTemplateConfig ReadPromptyFileForTemplateConfig(string fileName) + { + string prompty = File.ReadAllText(fileName); + #pragma warning disable SKEXP0040 // Type is for evaluation purposes only and is subject to change or removal in future updates. Suppress this diagnostic to proceed. + return KernelFunctionPrompty.ToPromptTemplateConfig(prompty); + #pragma warning restore SKEXP0040 // Type is for evaluation purposes only and is subject to change or removal in future updates. + } private static KernelArguments CreateFunctionChoiceAutoBehavior() { diff --git a/src/ChatApp.WebApi/Agents/Prompts/editor.prompty b/src/ChatApp.WebApi/Agents/Prompts/editor.prompty new file mode 100644 index 0000000..44514db --- /dev/null +++ b/src/ChatApp.WebApi/Agents/Prompts/editor.prompty @@ -0,0 +1,34 @@ +--- +name: Editor Agent +description: Given an article and some feedback, this agent decides whether to accept or reject the feedback. +model: + api: chat + configuration: + type: azure_openai + azure_deployment: gpt-4o + parameters: + max_tokens: 1200 + temperature: 0.2 +inputs: + article: + type: string + default: " " +sample: + article: ${file:article.txt} +--- +system: + +You are an editor at a publishing company. Your responsiblity is to review and identify how to improve the written article. + Never directly perform the correction or provide example. + Once the article has been updated in a subsequent response, you will review the article again until satisfactory. + + RULES: + - Only identify suggestions that are specific and actionable. + - Verify previous suggestions have been addressed. + - Never repeat previous suggestions. + + If the article is good and all your feedback was adressed, in other words, if + the writer is done, you should end your feedback with: "Article accepted, no further rework necessary." + + Or if the article needs work or the old feedback was not adressed, in other words, if the writer + needs to do more work, you should respond with *Review Feedback* including your new feedback and the review of the feedback from before. \ No newline at end of file diff --git a/src/ChatApp.WebApi/Agents/Prompts/marketing.prompty b/src/ChatApp.WebApi/Agents/Prompts/marketing.prompty new file mode 100644 index 0000000..12db05d --- /dev/null +++ b/src/ChatApp.WebApi/Agents/Prompts/marketing.prompty @@ -0,0 +1,24 @@ +--- +name: Marketing Agent +description: >- + This agent is designed to help a writer by formulating expert queries + and providing the writer with the information they need. +model: + api: chat + configuration: + type: azure_openai + azure_deployment: gpt-4o +sample: + product_context: Can you find the latest camping trends and what folks are doing in the winter? +--- +system: + # Marketing Agent + You are an AI assistant who helps people find information from a product search index. + You have access to a variety of tools that can help. + Given some context, you create 5 specialized queries and + use these tools return the most relevant information for a writer to use when writing marketing articles. + + # Context + Use the following context to provide a set of specialized queries to the search index: + + {{product_context}} diff --git a/src/ChatApp.WebApi/Agents/Prompts/researcher.prompty b/src/ChatApp.WebApi/Agents/Prompts/researcher.prompty new file mode 100644 index 0000000..96a48a5 --- /dev/null +++ b/src/ChatApp.WebApi/Agents/Prompts/researcher.prompty @@ -0,0 +1,53 @@ +--- +name: Researcher Agent +description: >- + This agent is designed to help a writer by formulating expert queries + and providing the writer with the information they need. +model: + api: chat + configuration: + type: azure_openai + azure_deployment: gpt-4o +sample: + instructions: Can you find the latest camping trends and what folks are doing in the winter? + feedback: Can you dig find some information about the latest camping trends and what folks are doing in the winter? +--- +system: +# Researcher Agent +You are an expert researcher that helps put together information for a writer who +is putting together an article. You have access to a variety of tools that can help. +Given some context and writer feedback, you can use these tools to help the writer +by formulating expert queries and providing the writer with the information they need. +Your queries should be descriptive and match the provided instructions. + +# Context +{{research_context}} + +# Feedback +Use this feedback to help you refine your queries and responses - if there is any feedback: + +{{feedback}} + +# Market Codes +The following are the market codes for the countries and regions that are supported by +the Microsoft Bing API and should be used when formulating your queries. Use the language +in the context to determine the market code using the following list of supported +languages - do not use any other language or market code not listed here: + +Portuguese, pt-BR +Danish, da-DK +Finnish, fi-FI +French, fr-FR +German, de-DE +Traditional Chinese, zh-HK +Italian, it-IT +Japanese, ja-JP +Korean, ko-KR +Dutch, nl-NL +Norwegian, no-NO +Polish, pl-PL +Russian, ru-RU +Spanish, es-ES +Swedish, sv-SE +Turkish, tr-TR +English, en-US diff --git a/src/ChatApp.WebApi/Agents/Prompts/writer.prompty b/src/ChatApp.WebApi/Agents/Prompts/writer.prompty new file mode 100644 index 0000000..0368e20 --- /dev/null +++ b/src/ChatApp.WebApi/Agents/Prompts/writer.prompty @@ -0,0 +1,62 @@ +--- +name: Writer Agent +description: + This writer agent takes a request from a user as well as research provider by a web researcher to produce a document. +model: + api: chat + configuration: + type: azure_openai + azure_deployment: gpt-4o +inputs: + research_context: + type: string + default: " " +--- +template: + # Writer Agent + You are an expert copywriter who can take research from a web researcher as well as some product + information from marketing to produce a fun and engaging article that can be used as a magazine + article or a blog post. The goal is to engage the reader and provide them with a fun and informative + article. The article should be between 800 and 1000 words. Use the following instructions as the basis + of your article: + + # Research + {{research_context}} + + # Web Research + Use this research to write the article. The research can include entities, web search results, and + news search results. While it is ok to use the research as a basis for the article, please do not + copy and paste the research verbatim. Instead, use the research to write a fun and engaging article. + Do not invent information that is not in the research. + + {{research_results}} + + # Product Information + {{product_context}} + + # Product Information + Use this product information to write the article. The product information can include product names and + descriptions. While it is ok to use the product information as a basis for the article, please do not + copy and paste the product information verbatim. Instead, use the product information to write a fun and + engaging article. Do not invent information that is not in the product information. + + {{product_results}} + + # Article + Write a fun and engaging article that includes the research and product information. The article should + be between 800 and 1000 words. The goal is to engage the reader and provide them with a fun and informative + article. + + # Final Instructions + Try to keep your writing short and to the point. The goal is to engage the reader and provide them with + a fun and informative article. The article should be between 800 and 1200 words. + + # Assignment: + {{assignment}} + Please format the article as markdown but do not include ```markdown``` in the document. + + # Review Feedback + If you recieved any feedback, your sole responsiblity is to rewrite the article according to review suggestions. + - Always apply all review direction + - Always revise the content in its entirety without explanation + - Never address the user \ No newline at end of file diff --git a/src/ChatApp.WebApi/ChatApp.WebApi.csproj b/src/ChatApp.WebApi/ChatApp.WebApi.csproj index 9ce97f2..215aa92 100644 --- a/src/ChatApp.WebApi/ChatApp.WebApi.csproj +++ b/src/ChatApp.WebApi/ChatApp.WebApi.csproj @@ -17,6 +17,7 @@ + @@ -34,6 +35,9 @@ PreserveNewest + + PreserveNewest + PreserveNewest