You can not select more than 25 topics Topics must start with a chinese character,a letter or number, can include dashes ('-') and can be up to 35 characters long.

FSM_Group_Chat.cs 6.7 kB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189
  1. // Copyright (c) Microsoft Corporation. All rights reserved.
  2. // FSM_Group_Chat.cs
  3. using System.Text;
  4. #region Using
  5. using AutoGen.Core;
  6. using AutoGen.OpenAI;
  7. using AutoGen.OpenAI.Extension;
  8. using OpenAI;
  9. using OpenAI.Chat;
  10. #endregion Using
  11. namespace AutoGen.Basic.Sample;
  12. #region FillFormTool
  13. public partial class FillFormTool
  14. {
  15. private string? name;
  16. private string? email;
  17. private string? phone;
  18. private string? address;
  19. private bool? receiveUpdates;
  20. [Function]
  21. public async Task<string> SaveProgress(
  22. string name,
  23. string email,
  24. string phone,
  25. string address,
  26. bool? receiveUpdates)
  27. {
  28. this.name = !string.IsNullOrEmpty(name) ? name : this.name;
  29. this.email = !string.IsNullOrEmpty(email) ? email : this.email;
  30. this.phone = !string.IsNullOrEmpty(phone) ? phone : this.phone;
  31. this.address = !string.IsNullOrEmpty(address) ? address : this.address;
  32. this.receiveUpdates = receiveUpdates ?? this.receiveUpdates;
  33. var missingInformationStringBuilder = new StringBuilder();
  34. if (string.IsNullOrEmpty(this.name))
  35. {
  36. missingInformationStringBuilder.AppendLine("Name is missing.");
  37. }
  38. if (string.IsNullOrEmpty(this.email))
  39. {
  40. missingInformationStringBuilder.AppendLine("Email is missing.");
  41. }
  42. if (string.IsNullOrEmpty(this.phone))
  43. {
  44. missingInformationStringBuilder.AppendLine("Phone is missing.");
  45. }
  46. if (string.IsNullOrEmpty(this.address))
  47. {
  48. missingInformationStringBuilder.AppendLine("Address is missing.");
  49. }
  50. if (this.receiveUpdates == null)
  51. {
  52. missingInformationStringBuilder.AppendLine("ReceiveUpdates is missing.");
  53. }
  54. if (missingInformationStringBuilder.Length > 0)
  55. {
  56. return missingInformationStringBuilder.ToString();
  57. }
  58. else
  59. {
  60. return "Application information is saved to database.";
  61. }
  62. }
  63. }
  64. #endregion FillFormTool
  65. public class FSM_Group_Chat
  66. {
  67. public static async Task<IAgent> CreateSaveProgressAgent(ChatClient client)
  68. {
  69. #region Create_Save_Progress_Agent
  70. var tool = new FillFormTool();
  71. var functionCallMiddleware = new FunctionCallMiddleware(
  72. functions: [tool.SaveProgressFunctionContract],
  73. functionMap: new Dictionary<string, Func<string, Task<string>>>
  74. {
  75. { tool.SaveProgressFunctionContract.Name!, tool.SaveProgressWrapper },
  76. });
  77. var chatAgent = new OpenAIChatAgent(
  78. chatClient: client,
  79. name: "application",
  80. systemMessage: """You are a helpful application form assistant who saves progress while user fills application.""")
  81. .RegisterMessageConnector()
  82. .RegisterMiddleware(functionCallMiddleware)
  83. .RegisterMiddleware(async (msgs, option, agent, ct) =>
  84. {
  85. var lastUserMessage = msgs.Last() ?? throw new Exception("No user message found.");
  86. var prompt = $"""
  87. Save progress according to the most recent information provided by user.
  88. ```user
  89. {lastUserMessage.GetContent()}
  90. ```
  91. """;
  92. return await agent.GenerateReplyAsync([lastUserMessage], option, ct);
  93. });
  94. #endregion Create_Save_Progress_Agent
  95. return chatAgent;
  96. }
  97. public static async Task<IAgent> CreateAssistantAgent(ChatClient chatClient)
  98. {
  99. #region Create_Assistant_Agent
  100. var chatAgent = new OpenAIChatAgent(
  101. chatClient: chatClient,
  102. name: "assistant",
  103. systemMessage: """You create polite prompt to ask user provide missing information""")
  104. .RegisterMessageConnector()
  105. .RegisterPrintMessage();
  106. #endregion Create_Assistant_Agent
  107. return chatAgent;
  108. }
  109. public static async Task<IAgent> CreateUserAgent(ChatClient chatClient)
  110. {
  111. #region Create_User_Agent
  112. var chatAgent = new OpenAIChatAgent(
  113. chatClient: chatClient,
  114. name: "user",
  115. systemMessage: """
  116. You are a user who is filling an application form. Simply provide the information as requested and answer the questions, don't do anything else.
  117. here's some personal information about you:
  118. - name: John Doe
  119. - email: 1234567@gmail.com
  120. - phone: 123-456-7890
  121. - address: 1234 Main St, Redmond, WA 98052
  122. - want to receive update? true
  123. """)
  124. .RegisterMessageConnector()
  125. .RegisterPrintMessage();
  126. #endregion Create_User_Agent
  127. return chatAgent;
  128. }
  129. public static async Task RunAsync()
  130. {
  131. var apiKey = Environment.GetEnvironmentVariable("OPENAI_API_KEY") ?? throw new Exception("Please set OPENAI_API_KEY environment variable.");
  132. var model = "gpt-4o-mini";
  133. var openaiClient = new OpenAIClient(apiKey);
  134. var chatClient = openaiClient.GetChatClient(model);
  135. var applicationAgent = await CreateSaveProgressAgent(chatClient);
  136. var assistantAgent = await CreateAssistantAgent(chatClient);
  137. var userAgent = await CreateUserAgent(chatClient);
  138. #region Create_Graph
  139. var userToApplicationTransition = Transition.Create(userAgent, applicationAgent);
  140. var applicationToAssistantTransition = Transition.Create(applicationAgent, assistantAgent);
  141. var assistantToUserTransition = Transition.Create(assistantAgent, userAgent);
  142. var workflow = new Graph(
  143. [
  144. userToApplicationTransition,
  145. applicationToAssistantTransition,
  146. assistantToUserTransition,
  147. ]);
  148. #endregion Create_Graph
  149. #region Group_Chat
  150. var groupChat = new GroupChat(
  151. members: [userAgent, applicationAgent, assistantAgent],
  152. workflow: workflow);
  153. #endregion Group_Chat
  154. var initialMessage = await assistantAgent.SendAsync("Generate a greeting meesage for user and start the conversation by asking what's their name.");
  155. var chatHistory = new List<IMessage> { initialMessage };
  156. await foreach (var msg in groupChat.SendAsync(chatHistory, maxRound: 30))
  157. {
  158. if (msg.GetContent().ToLower().Contains("application information is saved to database.") is true)
  159. {
  160. break;
  161. }
  162. }
  163. }
  164. }