1717using Microsoft . SemanticKernel ;
1818using Microsoft . SemanticKernel . Agents ;
1919using Microsoft . SemanticKernel . Agents . Chat ;
20+ using Microsoft . SemanticKernel . Agents . Orchestration . GroupChat ;
21+ using Microsoft . SemanticKernel . Agents . Orchestration . Handoff ;
22+ using Microsoft . SemanticKernel . Agents . Runtime . InProcess ;
2023using Microsoft . SemanticKernel . AudioToText ;
2124using Microsoft . SemanticKernel . ChatCompletion ;
2225using Microsoft . SemanticKernel . Connectors . AzureAISearch ;
3639using Qdrant . Client . Grpc ;
3740using SemanticKernelFun . Data ;
3841using SemanticKernelFun . Models ;
42+ using SemanticKernelFun . Plugins ;
3943using SemanticKernelFun . Plugins . TransferOrderPlanner ;
4044using SemanticKernelFun . Plugins . TripPlanner ;
4145using Spectre . Console ;
@@ -1499,12 +1503,220 @@ You are limited to American cities only. Keep your responses clear and concise."
14991503 }
15001504 }
15011505
1502- OpenAI . Chat . ChatCompletion finalCompletion = await chatClient . CompleteChatAsync (
1506+ ChatCompletion finalCompletion = await chatClient . CompleteChatAsync (
15031507 conversationMessages ,
15041508 options
15051509 ) ;
15061510
15071511 Console . WriteLine ( finalCompletion . Content . First ( ) . Text ) ;
15081512 }
15091513 }
1514+
1515+ public static async Task RunMultiAgentSloganOrchestration ( AzureAIConfig azureAIConfig )
1516+ {
1517+ // Set up kernel (adjust this as needed for your config)
1518+ var kernel = KernelHelper . GetKernelChatCompletion ( azureAIConfig ) ;
1519+
1520+ // Define the agents inline
1521+ var writer = new ChatCompletionAgent
1522+ {
1523+ Name = "CopyWriter" ,
1524+ Description = "A copy writer" ,
1525+ Instructions = """
1526+ You are a copywriter with ten years of experience and are known for brevity and a dry humor.
1527+ The goal is to refine and decide on the single best copy as an expert in the field.
1528+ Only provide a single proposal per response.
1529+ You're laser focused on the goal at hand.
1530+ Don't waste time with chit chat.
1531+ Consider suggestions when refining an idea.
1532+ """ ,
1533+ Kernel = kernel ,
1534+ } ;
1535+
1536+ var editor = new ChatCompletionAgent
1537+ {
1538+ Name = "Reviewer" ,
1539+ Description = "An editor." ,
1540+ Instructions = """
1541+ You are an art director who has opinions about copywriting born of a love for David Ogilvy.
1542+ The goal is to determine if the given copy is acceptable to print.
1543+ If so, state that it is approved.
1544+ If not, provide insight on how to refine suggested copy without example.
1545+ """ ,
1546+ Kernel = kernel ,
1547+ } ;
1548+
1549+ // Define orchestration with a custom group manager and simple console output
1550+ var orchestration = new GroupChatOrchestration (
1551+ new CustomRoundRobinGroupChatManager
1552+ {
1553+ MaximumInvocationCount = 5 ,
1554+ InteractiveCallback = ( ) =>
1555+ {
1556+ var input = new Microsoft . SemanticKernel . ChatMessageContent (
1557+ AuthorRole . User ,
1558+ "I like it"
1559+ ) ;
1560+ Console . WriteLine ( $ "\n # USER INPUT: { input . Content } \n ") ;
1561+ return ValueTask . FromResult ( input ) ;
1562+ } ,
1563+ } ,
1564+ writer ,
1565+ editor
1566+ )
1567+ {
1568+ ResponseCallback = async content =>
1569+ {
1570+ Console . WriteLine ( $ "\n 📨 { content . Role } [{ content . AuthorName } ]: { content . Content } ") ;
1571+ await Task . CompletedTask ;
1572+ } ,
1573+ } ;
1574+
1575+ // Start the runtime
1576+ var runtime = new InProcessRuntime ( ) ;
1577+ await runtime . StartAsync ( ) ;
1578+
1579+ // Initial input
1580+ string input =
1581+ "Create a slogan for a new electric SUV that is affordable and fun to drive." ;
1582+ Console . WriteLine ( $ "\n 🚗 Initial Prompt: { input } ") ;
1583+
1584+ var result = await orchestration . InvokeAsync ( input , runtime ) ;
1585+ string output = await result . GetValueAsync ( TimeSpan . FromSeconds ( 30 ) ) ;
1586+
1587+ Console . WriteLine ( $ "\n 🎯 Final Output:\n { output } ") ;
1588+
1589+ await runtime . RunUntilIdleAsync ( ) ;
1590+
1591+ Console . WriteLine ( "\n ✅ Done. Press any key to exit." ) ;
1592+ Console . ReadKey ( ) ;
1593+ }
1594+
1595+ private class CustomRoundRobinGroupChatManager : RoundRobinGroupChatManager
1596+ {
1597+ public override ValueTask < GroupChatManagerResult < bool > > ShouldRequestUserInput (
1598+ ChatHistory history ,
1599+ CancellationToken cancellationToken = default
1600+ )
1601+ {
1602+ var last = history . LastOrDefault ( ) ;
1603+ if ( last ? . AuthorName == "Reviewer" )
1604+ {
1605+ return ValueTask . FromResult (
1606+ new GroupChatManagerResult < bool > ( true )
1607+ {
1608+ Reason = "Reviewer has spoken; requesting user input." ,
1609+ }
1610+ ) ;
1611+ }
1612+
1613+ return ValueTask . FromResult (
1614+ new GroupChatManagerResult < bool > ( false ) { Reason = "User input not yet needed." }
1615+ ) ;
1616+ }
1617+ }
1618+
1619+ public static async Task RunMultiAgentTriageOrchestration ( AzureAIConfig azureAIConfig )
1620+ {
1621+ var kernel = KernelHelper . GetKernelChatCompletion ( azureAIConfig ) ;
1622+
1623+ kernel . ImportPluginFromObject ( new TicketPlugin ( ) ) ;
1624+ kernel . ImportPluginFromObject ( new KnowledgePlugin ( ) ) ;
1625+
1626+ // AGENTS
1627+ var triageAgent = new ChatCompletionAgent
1628+ {
1629+ Name = "TriageAgent" ,
1630+ Description =
1631+ "Responsible for triaging incoming support requests and routing them to the appropriate department." ,
1632+ Instructions = """
1633+ You triage employee requests. Route to ITAgent (tech), HRAgent (HR), or FinanceAgent (money-related).
1634+ """ ,
1635+ Kernel = kernel ,
1636+ } ;
1637+
1638+ var itAgent = new ChatCompletionAgent
1639+ {
1640+ Name = "ITAgent" ,
1641+ Description =
1642+ "Handles IT-related support requests such as software, hardware, network, or login issues." ,
1643+ Instructions = """
1644+ You're an IT support agent. Troubleshoot technical issues.
1645+ If unresolved, call TicketPlugin.CreateTicket(issue, "IT").
1646+ """ ,
1647+ Kernel = kernel ,
1648+ } ;
1649+
1650+ var hrAgent = new ChatCompletionAgent
1651+ {
1652+ Name = "HRAgent" ,
1653+ Description =
1654+ "Handles human resources support like PTO, benefits, job roles, and employee policies." ,
1655+ Instructions = """
1656+ You're an HR support agent. Help with PTO, benefits, and policies.
1657+ Use KnowledgePlugin.GetPolicy if asked about HR policy.
1658+ """ ,
1659+ Kernel = kernel ,
1660+ } ;
1661+
1662+ var financeAgent = new ChatCompletionAgent
1663+ {
1664+ Name = "FinanceAgent" ,
1665+ Description =
1666+ "Handles finance-related support such as payroll, reimbursements, and budgeting policies." ,
1667+ Instructions = """
1668+ You're a finance agent. Help with payroll, reimbursements, and expense policies.
1669+ Use KnowledgePlugin.GetPolicy or TicketPlugin as needed.
1670+ """ ,
1671+ Kernel = kernel ,
1672+ } ;
1673+
1674+ var handoffs = OrchestrationHandoffs
1675+ . StartWith ( triageAgent )
1676+ . Add ( triageAgent , itAgent , hrAgent , financeAgent )
1677+ . Add ( itAgent , triageAgent , "Hand back if not a tech issue" )
1678+ . Add ( hrAgent , triageAgent , "Hand back if not an HR issue" )
1679+ . Add ( financeAgent , triageAgent , "Hand back if not finance" ) ;
1680+
1681+ var orchestration = new HandoffOrchestration (
1682+ handoffs ,
1683+ triageAgent ,
1684+ itAgent ,
1685+ hrAgent ,
1686+ financeAgent
1687+ )
1688+ {
1689+ InteractiveCallback = async ( ) =>
1690+ {
1691+ Console . Write ( "\n 🧑💼 You: " ) ;
1692+ var input = await Task . Run ( ( ) => Console . ReadLine ( ) ) ;
1693+
1694+ return new Microsoft . SemanticKernel . ChatMessageContent (
1695+ AuthorRole . User ,
1696+ input ?? ""
1697+ ) ;
1698+ } ,
1699+
1700+ ResponseCallback = async msg =>
1701+ {
1702+ Console . WriteLine ( $ "\n 📣 { msg . Role } [{ msg . AuthorName } ]: { msg . Content } ") ;
1703+ await Task . CompletedTask ;
1704+ } ,
1705+ } ;
1706+
1707+ // RUN IT
1708+ Console . WriteLine ( "Enter a support request:" ) ;
1709+ Console . Write ( "> " ) ;
1710+ var input = Console . ReadLine ( ) ?? "I need help accessing my pay stubs." ;
1711+
1712+ var runtime = new InProcessRuntime ( ) ;
1713+ await runtime . StartAsync ( ) ;
1714+
1715+ var result = await orchestration . InvokeAsync ( input , runtime ) ;
1716+ var final = await result . GetValueAsync ( ) ;
1717+
1718+ Console . WriteLine ( $ "\n ✅ Final result: { final } ") ;
1719+ Console . WriteLine ( "\n Press any key to exit..." ) ;
1720+ Console . ReadKey ( ) ;
1721+ }
15101722}
0 commit comments