﻿
{"id":27866,"date":"2025-05-25T22:40:30","date_gmt":"2025-05-25T22:40:30","guid":{"rendered":"https:\/\/www.gencayyildiz.com\/blog\/?p=27866"},"modified":"2025-05-25T22:40:30","modified_gmt":"2025-05-25T22:40:30","slug":"autogen-ile-coklu-yapay-zeka-ajan-sistemi-gelistirme","status":"publish","type":"post","link":"https:\/\/www.gencayyildiz.com\/blog\/autogen-ile-coklu-yapay-zeka-ajan-sistemi-gelistirme\/","title":{"rendered":"AutoGen \u0130le \u00c7oklu Yapay Zek\u00e2 Ajan Sistemi Geli\u015ftirme"},"content":{"rendered":"<div id=\"fb-root\"><\/div>\n<p>Merhaba,<\/p>\n<p>Bir \u00f6nceki <a href=\"https:\/\/www.gencayyildiz.com\/blog\/autogen-nedir-derinlemesine-teorik-inceleyelim\/\" target=\"_blank\">AutoGen Nedir? Derinlemesine Teorik \u0130nceleyelim&#8230;<\/a> ba\u015fl\u0131kl\u0131 i\u00e7eri\u011fimizde AutoGen&#8217;i teorik boyutta masaya yat\u0131rm\u0131\u015f ve tam teferruatl\u0131 bir incelemede bulunmu\u015ftuk. Bu i\u00e7eri\u011fimizde ise edindi\u011fimiz teorik zemin \u00fczerine art\u0131k pratik bir in\u015fada bulunacak ve AutoGen ile \u00e7oklu yapay zek\u00e2 ajan sistemlerinin (multi-agent systems) nas\u0131l geli\u015ftirilebilece\u011finin derinliklerine temas ediyor olaca\u011f\u0131z. O halde vakit kaybetmeksizin buyurun ba\u015flayal\u0131m.<\/p>\n<p><strong>Temel Kurulum ve Yap\u0131land\u0131rma<\/strong><br \/>\n\u0130lk olarak bir Console Application projesi olu\u015fturulmal\u0131 ve bu projeye<br \/>\n<code><a href=\"https:\/\/www.nuget.org\/packages\/AutoGen\" target=\"_blank\">dotnet add package AutoGen<\/a><\/code> talimat\u0131yla gerekli AutoGen k\u00fct\u00fcphanesi y\u00fcklenmelidir.<\/p>\n<p>Ard\u0131ndan OpenRouter \u00fczerinden bir api key edinilerek, <a href=\"https:\/\/openrouter.ai\/mistral\/ministral-8b\" target=\"_blank\">Mistral: Ministral 8B<\/a> AI modeli e\u015fli\u011finde a\u015fa\u011f\u0131daki de\u011fi\u015fkenler tan\u0131mlan\u0131p, \u00e7al\u0131\u015fmaya hali haz\u0131r bir altyap\u0131 olu\u015fturulmal\u0131d\u0131r.<\/p>\n<div style=\"font-size:12px;\">\n<pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\r\nstring apiKey = &quot;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&quot;;\r\nstring model = &quot;mistral\/ministral-8b&quot;;\r\nstring endpoint = &quot;https:\/\/openrouter.ai\/api\/v1&quot;;\r\n<\/pre>\n<\/div>\n<p>Evet, art\u0131k haz\u0131r oldu\u011fumuza g\u00f6re ba\u015flayabiliriz.<\/p>\n<h4>Temel Seviyede Agent \u0130n\u015fas\u0131<\/h4>\n<p>AutoGen&#8217;de temel seviyede bir agent olu\u015fturmak i\u00e7in manuel yap\u0131land\u0131rma maliyetini g\u00f6ze al\u0131p <code>ConversableAgent<\/code> tercih edilebilir, amma velakin h\u0131zl\u0131 bir yap\u0131land\u0131rmayla en temelde bir agent aya\u011fa kald\u0131rmak i\u00e7in <code>OpenAIChatAgent<\/code> daha idealdir.<\/p>\n<div style=\"font-size:12px;\">\n<pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\r\nvar assistantAgent = new OpenAIChatAgent(\r\n      chatClient: new ChatClient(\r\n          model: model,\r\n          credential: new ApiKeyCredential(apiKey),\r\n          options: new OpenAIClientOptions()\r\n          {\r\n              Endpoint = new Uri(endpoint)\r\n          }),\r\n      name: &quot;assistant&quot;,\r\n      systemMessage: &quot;Sen kullan\u0131c\u0131n\u0131n baz\u0131 g\u00f6revleri yapmas\u0131na yard\u0131mc\u0131 olan bir asistans\u0131n.&quot;)\r\n      .RegisterMessageConnector()\r\n      .RegisterPrintMessage();\r\n<\/pre>\n<\/div>\n<p>Burada g\u00f6r\u00fcld\u00fc\u011f\u00fc \u00fczere AI modelle etkile\u015fime girebilecek kullan\u0131c\u0131dan mesaj alabilen bir agent olu\u015fturulmu\u015ftur. Hat\u0131rlarsan\u0131z e\u011fer AutoGen&#8217;de her agent&#8217;\u0131n g\u00f6rev ve yetenekleri yapaca\u011f\u0131 i\u015fin kapsam\u0131na g\u00f6re \u00f6zelle\u015ftirilebildi\u011fi i\u00e7in <em>name<\/em> ve <em>systemMessage<\/em> k\u0131s\u0131mlar\u0131nda bunlar ayarlanmaktad\u0131r. Ayr\u0131ca tan\u0131mlamada yer alan <code>RegisterMessageConnector<\/code> metodu ile AI modelden gelecek mesajlar AutoGen&#8217;in anlayabilece\u011fi IMessage format\u0131na d\u00f6n\u00fc\u015ft\u00fcr\u00fclmekte ve tam tersi i\u015flem ger\u00e7ekle\u015ftirilmektedir. Bir yandan da <code>RegisterPrintMessage<\/code> metodu ile de, bu agent&#8217;\u0131n ald\u0131\u011f\u0131 ve g\u00f6nderdi\u011fi mesajlar console&#8217;a uygun bir formatta yazd\u0131r\u0131lmaktad\u0131r.<\/p>\n<p>Tabi \u015fimdi bu agent&#8217;la haberle\u015fmeyi sa\u011flayacak ve etkile\u015fime girecek bir ba\u015fka agent daha olu\u015fturmam\u0131z gerekmektedir. Misal olarak a\u015fa\u011f\u0131daki gibi <code>UserProxyAgent<\/code> arac\u0131l\u0131\u011f\u0131yla kullan\u0131c\u0131y\u0131 temsil eden bir agent olu\u015fturulabilir.<\/p>\n<div style=\"font-size:12px;\">\n<pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\r\nvar userProxyAgent = new UserProxyAgent(\r\n    name: &quot;user&quot;,\r\n    humanInputMode: HumanInputMode.ALWAYS)\r\n    .RegisterPrintMessage();\r\n<\/pre>\n<\/div>\n<p>Evet, art\u0131k elimizde biri yard\u0131mc\u0131 olan biri de kullan\u0131c\u0131y\u0131 temsil eden iki adet agent mevcuttur. Art\u0131k bu agent&#8217;lar\u0131n kendi aralar\u0131ndaki haberle\u015fmelerini ba\u015flatabiliriz. Bu haberle\u015fme a\u015fa\u011f\u0131daki gibi iki taraftan da ba\u015flayabilir;<\/p>\n<ul>\n<li><em>Kullan\u0131c\u0131 agent&#8217;tan, assistant agent&#8217;a;<\/em>\n<div style=\"font-size:12px;\">\n<pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\r\nawait userProxyAgent.InitiateChatAsync(\r\n    receiver: assistantAgent,\r\n    message: Console.ReadLine(),\r\n    maxRound: 10);\r\n<\/pre>\n<\/div>\n<\/li>\n<li><em>Assistant agent&#8217;tan, kullan\u0131c\u0131 agent&#8217;a;<\/em>\n<div style=\"font-size:12px;\">\n<pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\r\nawait assistantAgent.InitiateChatAsync(\r\n    receiver: userProxyAgent,\r\n    message: Console.ReadLine(),\r\n    maxRound: 10);\r\n<\/pre>\n<\/div>\n<\/li>\n<\/ul>\n<p>Yukar\u0131daki y\u00f6ntemleri incelersek ileti\u015fimin hangi agent&#8217;tan ba\u015flarsa ba\u015flas\u0131n <code>InitiateChatAsync<\/code> metodu arac\u0131l\u0131\u011f\u0131yla ba\u015flat\u0131lmakta oldu\u011funu g\u00f6r\u00fcyoruz. Bir agent bu metot arac\u0131l\u0131\u011f\u0131yla <code>receiver<\/code> parametresine verilen agent&#8217;a mesaj\u0131n\u0131 g\u00f6nderecek ve s\u00fcreci ba\u015flatacakt\u0131r. Bu haberle\u015fme s\u00fcrecinde agent&#8217;lar aras\u0131 yan\u0131t d\u00f6ng\u00fcs\u00fc <code>maxRound<\/code> parametresiyle belirlenmekte ve b\u00f6ylece gereksiz API \u00e7a\u011fr\u0131lar\u0131 ve sonsuz ileti\u015fimsel d\u00f6ng\u00fcler gibi durumlar engellenmektedir.<\/p>\n<p>Bu yapt\u0131\u011f\u0131m\u0131z geli\u015ftirmeyi derleyip \u00e7al\u0131\u015ft\u0131r\u0131rsak e\u011fer a\u015fa\u011f\u0131daki ekran g\u00f6r\u00fcnt\u00fcs\u00fcnde oldu\u011fu gibi test edebilir ve agent&#8217;la sohbet edebiliriz.<a href=\"https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2025\/05\/AutoGen-Ile-Coklu-Yapay-Zeka-Ajan-Sistemi-Gelistirme.gif\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2025\/05\/AutoGen-Ile-Coklu-Yapay-Zeka-Ajan-Sistemi-Gelistirme.gif\" alt=\"AutoGen \u0130le \u00c7oklu Yapay Zek\u00e2 Ajan Sistemi Geli\u015ftirme\" width=\"800\" height=\"446\" class=\"aligncenter size-full wp-image-27877\" \/><\/a>Bak\u0131n dikkat ederseniz art\u0131k sohbeti ayakta tutabilmek i\u00e7in herhangi bir d\u00f6ng\u00fcyle vs. iterasyonel \u00e7al\u0131\u015fma yapmam\u0131za gerek bulunmamaktad\u0131r. \u00c7\u00fcnk\u00fc olu\u015fturdu\u011fumuz agent&#8217;lar s\u00fcrekli bir \u015fuur misali ileti\u015fim kurulabilir bir \u015fekilde ayaktad\u0131rlar.<\/p>\n<h4>GenerateReplyAsync &#038; SendAsync Metotlar\u0131 \u0130le Haberle\u015fme<\/h4>\n<p>Bir agent ile haberle\u015fme s\u00fcrecinde<span style=\"font-size:12px;\">(ki bu haberle\u015fme kullan\u0131c\u0131\/agent aras\u0131nda ya da agent\/agent aras\u0131nda olabilir)<\/span> <code>GenerateReplyAsync<\/code> ve <code>SendAsync<\/code> metotlar\u0131n\u0131 kullanarak farkl\u0131 davran\u0131\u015flar sergilenebilmektedir. \u015e\u00f6yle ki;<\/p>\n<ul style=\"font-size:12px;\">\n<li><strong><em>GenerateReplyAsync Metodu \u0130le Haberle\u015fme<\/em><\/strong><br \/>\nBu metot, agent taraf\u0131ndan yaln\u0131zca bir yan\u0131t \u00fcretilmesi i\u00e7in kullan\u0131lmaktad\u0131r. Genellikle konu\u015fman\u0131n kontrol\u00fc kullan\u0131c\u0131daysa uygun olmakta ve daha \u00e7ok test, debugging ya da kontrol senaryolar\u0131nda tercih edilmektedir.<\/p>\n<div style=\"font-size:12px;\">\n<pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\r\nvar message = new TextMessage(Role.User, &quot;Merhaba, sen kimsin?&quot;);\r\nIMessage reply = await chatAgent.GenerateReplyAsync(&#x5B;message]);\r\n<\/pre>\n<\/div>\n<p>G\u00f6r\u00fcld\u00fc\u011f\u00fc \u00fczere bu metot girdi olarak bir mesaj dizisi almakta, haliyle bu diziye konu\u015fma ge\u00e7mi\u015fi verilerek ba\u011flamla tutarl\u0131 bir cevap elde edilebilmektedir. B\u00f6ylece \u00e7ok ad\u0131ml\u0131, senkronize bir konu\u015fma ak\u0131\u015f\u0131n\u0131n neticesinde bir yan\u0131t \u00fcretilmesi gerekiyorsa bu metot kullan\u0131labilmektedir. Ancak \u015funu unutmamak gerekmektedir ki, bu metodun d\u00f6nd\u00fcrd\u00fc\u011f\u00fc yan\u0131t ne <code>GroupChat<\/code>&#8216;e iletilebilir, ne ba\u015fka bir agent&#8217;a g\u00f6nderilir ne de bir geri bildirim s\u00fcreci tetikleyebilir. Yani anlayaca\u011f\u0131n\u0131z sohbetin ak\u0131\u015f\u0131 ilerlememektedir.\n<\/li>\n<li><strong><em>SendAsync Metodu \u0130le Haberle\u015fme<\/em><\/strong><br \/>\nBu metot ise mesaj\u0131 agent&#8217;a g\u00f6ndermekte ve al\u0131nan cevab\u0131 varsa ak\u0131\u015f mant\u0131\u011f\u0131na g\u00f6re sonraki ad\u0131mlara(ba\u015fka agent&#8217;lara) yollamaktad\u0131r. E\u011fer ki s\u00f6z konusu bir <code>GroupChat<\/code>&#8216;se, bu metot arac\u0131l\u0131\u011f\u0131yla t\u00fcm s\u00fcre\u00e7 tetiklenir ve zincirleme agent ileti\u015fimi ba\u015flat\u0131labilir.<\/p>\n<div style=\"font-size:12px;\">\n<pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\r\nvar message = new TextMessage(Role.User, &quot;Merhaba, sen kimsin?&quot;);\r\nIMessage reply = await chatAgent.SendAsync(message);\r\n<\/pre>\n<\/div>\n<\/li>\n<\/ul>\n<p>Bu metotlar davran\u0131\u015fsal olarak bahsedilen farklara sahip olsalar da manuel kontrol a\u00e7\u0131s\u0131ndan da ciddi fark ortaya koymaktad\u0131rlar. \u015e\u00f6yle ki; <code>GenerateReplyAsync<\/code> metodunda agent&#8217;a g\u00f6nderilen mesaj neticesinde yaln\u0131z yan\u0131t al\u0131nabilmekte ve sistemin geri kalan\u0131na dair hi\u00e7bir \u015fey ger\u00e7ekle\u015fmemektedir. Yani \u00fcretilecek bu cevap s\u00fcre\u00e7te varsa ba\u015fka agent&#8217;lar taraf\u0131ndan kontrol edilmemekte veyahut sistemle ilgili herhangi bir event tetiklenmemektedir. Bundan kaynakl\u0131 bu metodun kullan\u0131ld\u0131\u011f\u0131 s\u00fcre\u00e7lerde mesaj\u0131n ne zaman, kime, nas\u0131l gidece\u011fine karar bizlerdedir. Haliyle olduk\u00e7a s\u0131k\u0131 bir manuel kontrol s\u00f6z konusudur. <code>SendAsync<\/code> metodu ise sistemin i\u00e7inde ba\u015fka agent&#8217;larla olan bir ak\u0131\u015f s\u00f6z konusuysa otomatik ba\u015flatacakt\u0131r ve gerekti\u011fi taktirde sistem event&#8217;lerinden tetikleme ger\u00e7ekle\u015ftirecektir. Ee haliyle bu metotta s\u00fcre\u00e7 taraf\u0131m\u0131zca kontrol edilemedi\u011fi i\u00e7in manuel kontrol paradigmas\u0131 olduk\u00e7a zay\u0131fl\u0131k arz etmektedir.<\/p>\n<p>Ve nihai olarak iki metot aras\u0131ndaki teknik farkl\u0131l\u0131klar\u0131 a\u015fa\u011f\u0131daki tabloda \u00f6zetleyerek devam edelim;<\/p>\n<table style=\"font-size:12px;\">\n<thead>\n<tr>\n<th style=\"width:20%;text-align:left;\">\u00d6zellik<\/th>\n<th style=\"width:40%\">GenerateReplyAsync<\/th>\n<th style=\"width:40%\">SendAsync<\/th>\n<\/tr>\n<\/thead>\n<tbody>\n<tr>\n<td style=\"text-align:left;\">Yan\u0131t \u00dcretimi<\/td>\n<td>\u2714\ufe0f<\/td>\n<td>\u2714\ufe0f<\/td>\n<\/tr>\n<tr>\n<td style=\"text-align:left;\">Mesaj G\u00f6nderimi<\/td>\n<td>\u274c<\/td>\n<td>\u2714\ufe0f<\/td>\n<\/tr>\n<tr>\n<td style=\"text-align:left;\">Otomatik Ak\u0131\u015f Tetikleme<\/td>\n<td>\u274c<\/td>\n<td>\u2714\ufe0f<\/td>\n<\/tr>\n<tr>\n<td style=\"text-align:left;\">Manuel Kontrol<\/td>\n<td>\u2714\ufe0f<\/td>\n<td>\u274c<br \/>\n<span style=\"font-size:8px;\">(daha az)<\/span><\/td>\n<\/tr>\n<tr>\n<td style=\"text-align:left;\">Ak\u0131\u015f Zinciri Tetikleme<\/td>\n<td>\u274c<\/td>\n<td>\u2714\ufe0f<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<h4>Streaming Chat<\/h4>\n<p>Agent&#8217;larla ileti\u015fim s\u00fcre\u00e7lerinde yan\u0131t\u0131 tamamen olu\u015fana kadar beklemek yerine olu\u015fturulan par\u00e7alar\u0131 anl\u0131k olarak streaming(ak\u0131\u015f tabanl\u0131) bir \u015fekilde alabilmek m\u00fcmk\u00fcnd\u00fcr. B\u00f6ylece uzun cevaplardan anl\u0131k tepki al\u0131nabilir ve bir yandan da typing gibi hisler olu\u015fturularak kullan\u0131c\u0131 deneyimleri iyile\u015ftirilebilir.<\/p>\n<div style=\"font-size:12px;\">\n<pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\r\nvar message = new TextMessage(Role.User, &quot;Tarihteki Meml\u00fckler devletiyle ilgili sence \u00f6nemli olan hangi bilgi konu\u015fmaya de\u011fer?&quot;);\r\nawait foreach (var reply in chatAgent.GenerateStreamingReplyAsync(&#x5B;message]))\r\n{\r\n    if (reply is TextMessageUpdate update)\r\n        Console.WriteLine(update.Content);\r\n}\r\n<\/pre>\n<\/div>\n<h4>Middlewares<\/h4>\n<p>AutoGen middleware yap\u0131s\u0131 sayesinde agent&#8217;lar aras\u0131nda ge\u00e7en mesajlar\u0131 ya da g\u00f6rev ak\u0131\u015flar\u0131n\u0131 kesebilmemizi ve b\u00f6ylece s\u00fcrece dair analizler ger\u00e7ekle\u015ftirebilmemizi, de\u011fi\u015fiklikler yapabilmemizi ya da y\u00f6nlendirme olana\u011f\u0131 sa\u011flamaktad\u0131r. Esas\u0131nda varl\u0131k nedeni Asp.NET Core&#8217;da ki bilinen middleware&#8217;lerle birebir ayn\u0131 amaca hizmet etmektedir.<\/p>\n<p>A\u015fa\u011f\u0131da bir agent \u00fczerinden basit\u00e7e middleware kullan\u0131m\u0131 \u00f6rneklendirilmektedir;<\/p>\n<div style=\"font-size:12px;\">\n<pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\r\nvar assistantAgent = new OpenAIChatAgent(\r\n      chatClient: new ChatClient(\r\n          model: model,\r\n          credential: new ApiKeyCredential(apiKey),\r\n          options: new OpenAIClientOptions()\r\n          {\r\n              Endpoint = new Uri(endpoint)\r\n          }),\r\n      name: &quot;assistant&quot;,\r\n      systemMessage: &quot;Sen kullan\u0131c\u0131n\u0131n baz\u0131 g\u00f6revleri yapmas\u0131na yard\u0131mc\u0131 olan bir asistans\u0131n.&quot;)\r\n      .RegisterMessageConnector()\r\n      \/\/messages : O ana kadar ge\u00e7en mesajlar - sohbet ge\u00e7mi\u015fi\r\n      \/\/options : Yan\u0131t \u00fcretim ayarlar\u0131\r\n      \/\/agent : Middleware'in araya girdi\u011fi agent'\u0131n kendisi\r\n      .RegisterMiddleware(async (messages, options, agent, cancellationToken) =&gt;\r\n      {\r\n          var lastMessage = messages.LastOrDefault();\r\n          if (lastMessage is TextMessage textMessage &amp;&amp; textMessage.Content.Contains(&quot;Merhaba&quot;))\r\n              return new TextMessage(Role.Assistant, &quot;&#x5B;middleware] Merhabe alg\u0131land\u0131.&quot;);\r\n\r\n          \/\/Di\u011fer durumlarda m\u00fcdahale etme, varsay\u0131lan yan\u0131t\u0131 \u00fcret!\r\n          return await agent.GenerateReplyAsync(messages, options, cancellationToken);\r\n      })\r\n      .RegisterPrintMessage();\r\n\r\nvar reply = await assistantAgent.SendAsync(&quot;Merhaba&quot;);\r\n<\/pre>\n<\/div>\n<p>G\u00f6r\u00fcld\u00fc\u011f\u00fc \u00fczere <code>RegisterMiddleware<\/code> metodu arac\u0131l\u0131\u011f\u0131yla agent&#8217;a bir middleware tan\u0131mlanabilmekte ve \u00fcretilecek yan\u0131t s\u00fcrecinde rahatl\u0131kla araya girilebilmektedir. Burada m\u00fchim olan ilgili metodun i\u00e7erisine verilecek metod parametrelerinin ne i\u015fe yarad\u0131klar\u0131n\u0131n bilincinde olmakt\u0131r. \u00d6zellikle <code>agent<\/code> parametresinin o an middleware taraf\u0131ndan araya girilen agent oldu\u011funun bilinmesinde fayda vard\u0131r.<\/p>\n<h4>Function Call<\/h4>\n<p>Kimi AI modellerinde, ak\u0131ll\u0131ca i\u015flemler yapabilmesi i\u00e7in s\u00fcrece harici fonksiyonlar dahil edilebilmekte ve b\u00f6ylece \u00fcretilecek yan\u0131tlar manip\u00fcle edilerek, AI modelinin yetkinli\u011fi artt\u0131r\u0131labilmekte ve yetenekleri geni\u015fletilebilmektedir.<\/p>\n<p><strong>Peki nas\u0131l function olu\u015fturulur?<\/strong> diye sordu\u011funuzu duyar gibiyim&#8230; AutoGen&#8217;de <em>function calling<\/em> deste\u011fini <code>FunctionDefinition<\/code> s\u0131n\u0131f\u0131 \u00fczerinden ger\u00e7ekle\u015ftiriyoruz. Bunu manuel yapmaktansa <a href=\"https:\/\/www.nuget.org\/packages\/AutoGen.SourceGenerator\" target=\"_blank\">AutoGen.SourceGenerator<\/a> k\u00fct\u00fcphanesini kullanarak source generator&#8217;dan istifade edebilir ve otomatik olarak ilgili s\u0131n\u0131f\u0131 olu\u015fturtturabiliriz. Bunun i\u00e7in <code>Function<\/code> attribute&#8217;unu kullanaca\u011f\u0131z. Bu attribute ile i\u015faretlenmi\u015f olan metotlar\u0131n otomatik olarak <em>function_calling<\/em> format\u0131na uygun olan <code>FunctionDefinition<\/code> d\u00f6n\u00fc\u015f\u00fcmleri ger\u00e7ekle\u015ftirilecek ve nesneleri elde edilecektir.<\/p>\n<div style=\"font-size:12px;\">\n<pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\r\n    public partial class Functions\r\n    {\r\n        \/\/\/ &lt;summary&gt;\r\n        \/\/\/ Kullan\u0131c\u0131 listesini getirir.\r\n        \/\/\/ &lt;\/summary&gt;\r\n        \/\/\/ &lt;param name=&quot;userId&quot;&gt;E\u011fer null de\u011filse, yaln\u0131zca de\u011feriyle e\u015fle\u015fen kullan\u0131c\u0131y\u0131 getirir.&lt;\/param&gt;\r\n        &#x5B;Function]\r\n        async Task&lt;string&gt; GetUsersAsync(int? userId)\r\n        {\r\n            using HttpClient httpClient = new();\r\n            var httpResponseMessage = await httpClient.GetAsync($&quot;https:\/\/jsonplaceholder.typicode.com\/users{(userId.HasValue ? $&quot;\/{userId.Value}&quot; : &quot;&quot;)}&quot;);\r\n            var jsonResult = await httpResponseMessage.Content.ReadAsStringAsync();\r\n            return jsonResult;\r\n        }\r\n    }\r\n<\/pre>\n<\/div>\n<p>Yukar\u0131daki tan\u0131mda \u015funu demek istiyoruz : <em>&#8216;Bu metodu LLM&#8217;e callable bir fonksiyon olarak sunmak istiyorum.&#8217;<\/em> Ee haliyle bunu reflection&#8217;la yapmaktansa source generator&#8217;\u0131 devreye sokup gerekli <code>FunctionDefinition<\/code> nesnesini olu\u015fturacak C# kodunu otomatik \u00fcrettiyoruz. Tabi bunun i\u00e7in source generator&#8217;\u0131n fonksiyon tan\u0131m\u0131n\u0131 \u00fcretirken gerekli olan fonksiyon dok\u00fcmantasyonundan yararlanmas\u0131n\u0131 sa\u011flayabilmek i\u00e7in projede a\u015fa\u011f\u0131daki gibi <code>GenerateDocumentationFile<\/code> \u00f6zelli\u011fini true olarak ayarlay\u0131p XML belge deste\u011fini etkinle\u015ftirmekte fayda vard\u0131r.<\/p>\n<div style=\"font-size:12px;\">\n<pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\r\n&lt;Project Sdk=&quot;Microsoft.NET.Sdk&quot;&gt;\r\n\t&lt;PropertyGroup&gt;\r\n\t\t.\r\n\t\t.\r\n\t\t.\r\n\t\t&lt;GenerateDocumentationFile&gt;true&lt;\/GenerateDocumentationFile&gt;\r\n\t&lt;\/PropertyGroup&gt;\r\n\t&lt;ItemGroup&gt;\r\n\t\t.\r\n\t\t.\r\n\t\t.\r\n\t\t&lt;PackageReference Include=&quot;AutoGen.SourceGenerator&quot; Version=&quot;0.2.3&quot; \/&gt;\r\n\t&lt;\/ItemGroup&gt;\r\n&lt;\/Project&gt;\r\n<\/pre>\n<\/div>\n<p>Ayr\u0131ca \u015funu da s\u00f6ylemekte fayda vard\u0131r ki; source generator&#8217;\u0131n kod \u00fcretebilmesi i\u00e7in t\u0131pk\u0131 yukar\u0131daki \u00f6rnekte oldu\u011fu gibi <code style=\"color:purple;\">public<\/code> ve <code style=\"color:purple;\">partial<\/code> olan bir class gerekli ve <code>Function<\/code> attribute&#8217;u ile i\u015faretlenmi\u015f metotda <code style=\"color:purple;\">public<\/code> olmal\u0131 ve d\u00f6n\u00fc\u015f de\u011feri olarak da <code style=\"color:purple;\">Task&lt;T&gt;<\/code> \u015feklinde tan\u0131mlanmal\u0131d\u0131r. Ve unutulmamal\u0131d\u0131r ki metot \u00f6zet k\u0131sm\u0131ndaki(summary) yaz\u0131lanlar kritik arz etmektedir.<\/p>\n<p>Evet, t\u00fcm \u00e7al\u0131\u015fmalar anlat\u0131ld\u0131\u011f\u0131 \u015fekilde yap\u0131ld\u0131\u011f\u0131 taktirde uygulama derlendi\u011fi vakit source generator devreye girecek ve gerekli function tan\u0131m\u0131 \u00fcretilecektir. Bu \u00fcretim neticesinde ilgili metodun LLM&#8217;e sunulmas\u0131 ve tetiklenebilmesi s\u00fcrecinde merkezi rol oynayacak olan iki member olu\u015fturulmu\u015f olacakt\u0131r. Bunlar <em>FunctionContract<\/em> property&#8217;si ile birlikte <em>Wrapper<\/em> metodudur.<\/p>\n<ul style=\"font-size:12px;\">\n<li><strong><em>FunctionContract<\/em><\/strong><br \/>\n\u0130lgili fonksiyona dair ad\u0131, a\u00e7\u0131klamas\u0131, parametreleri vs. gibi bilgileri e\u015fli\u011finde LLM&#8217;e bildirilece\u011fi s\u00f6zle\u015fmeyi yani kontrakt&#8217;\u0131 ifade etmektedir. Yukar\u0131daki metoda kar\u015f\u0131 source generator a\u015fa\u011f\u0131daki kontrakt\u0131 \u00fcretecektir.<\/p>\n<div style=\"font-size:12px;\">\n<pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\r\n        public FunctionContract GetUsersAsyncFunctionContract\r\n        {\r\n            get =&gt; new FunctionContract\r\n            {\r\n                Namespace = @&quot;AutoGen_Example&quot;,\r\n                ClassName = @&quot;Functions&quot;,\r\n                Name = @&quot;GetUsersAsync&quot;,\r\n                Description = @&quot;Kullan\u0131c\u0131 listesini getirir.&quot;,\r\n                ReturnType = typeof(Task&lt;string&gt;),\r\n                Parameters = new global::AutoGen.Core.FunctionParameterContract&#x5B;]\r\n                {\r\n                    new FunctionParameterContract\r\n                    {\r\n                        Name = @&quot;userId&quot;,\r\n                        Description = @&quot;E\u011fer null de\u011filse, yaln\u0131zca de\u011feriyle e\u015fle\u015fen kullan\u0131c\u0131y\u0131 getirir.&quot;,\r\n                        ParameterType = typeof(int?),\r\n                        IsRequired = true,\r\n                    },\r\n                },\r\n            };\r\n        }\r\n<\/pre>\n<\/div>\n<\/li>\n<li><strong><em>Wrapper<\/em><\/strong><br \/>\nLLM&#8217;den gelen JSON format\u0131ndaki parametreleri do\u011fru C# koduna d\u00f6n\u00fc\u015ft\u00fcren metottur. Misal olarak; LLM bizlere<br \/>\n<code>{'userId': 3}<\/code> d\u00f6nd\u00fcrd\u00fcyse, bunu <code>GetUsersAsyncWrapper(3)<\/code> \u015feklinde yorumlayacakt\u0131r. Yine benzer mant\u0131kla yukar\u0131daki metoda kar\u015f\u0131 source generator a\u015fa\u011f\u0131daki Wrapper \u00e7al\u0131\u015fmas\u0131n\u0131 ger\u00e7ekle\u015ftirmi\u015ftir.<\/p>\n<div style=\"font-size:12px;\">\n<pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\r\n        private class GetUsersAsyncSchema\r\n        {\r\n            &#x5B;JsonPropertyName(@&quot;userId&quot;)]\r\n            public int? userId {get; set;}\r\n        }\r\n<\/pre>\n<\/div>\n<p>Bak\u0131n, g\u00f6r\u00fcld\u00fc\u011f\u00fc \u00fczere \u00f6nce ilgili metodun parametlerilerini temsil edecek bir schema s\u0131n\u0131f\u0131 olu\u015fturmu\u015ftur.<\/p>\n<div style=\"font-size:12px;\">\n<pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\r\n        public Task&lt;string&gt; GetUsersAsyncWrapper(string arguments)\r\n        {\r\n            var schema = JsonSerializer.Deserialize&lt;GetUsersAsyncSchema&gt;(\r\n                arguments, \r\n                new JsonSerializerOptions\r\n                {\r\n                    PropertyNamingPolicy = JsonNamingPolicy.CamelCase,\r\n                });\r\n\r\n            return GetUsersAsync(schema.userId);\r\n        }\r\n<\/pre>\n<\/div>\n<p>Ard\u0131ndan LLM&#8217;den gelen JSON format\u0131ndaki parametreleri bu schema s\u0131n\u0131f\u0131 arac\u0131l\u0131\u011f\u0131yla deserialize edip kullanan <em>GetUsersAsyncWrapper<\/em> isimli wrapper metodunu olu\u015fturmu\u015ftur.\n<\/li>\n<\/ul>\n<p>Ne kadar kolay de\u011fil mi? AutoGen&#8217;in, biz geli\u015ftiricilerin deneyimini olduk\u00e7a kolayla\u015ft\u0131rmas\u0131 yetmiyormu\u015f gibi bir de source generator ile bu tarz teferruatl\u0131 i\u015flemlerin de sorumlulu\u011funu bizlerden t\u00f6rp\u00fclemesi taktire \u015fayan\ud83d\udc4f<\/p>\n<p><strong>Peki hoca! \u0130yi g\u00fczel de bu fonksiyonu LLM&#8217;den nas\u0131l \u00e7a\u011f\u0131raca\u011f\u0131z?<\/strong> sorunuzu da duymuyor de\u011filim. Bunun i\u00e7in a\u015fa\u011f\u0131daki gibi ilgili agent&#8217;a <code>RegisterMiddleware<\/code> \u00fczerinden <code>FunctionCallMiddleware<\/code> arac\u0131l\u0131\u011f\u0131yla hedef function(lar) kazand\u0131r\u0131labilir ve \u00f6rnekte oldu\u011fu gibi prompt&#8217;un mahiyetine g\u00f6re AI modeli taraf\u0131ndan ilgili function(lar) tetiklenerek  \u00fcretilecek yan\u0131t \u015fekillendirilip, s\u00fcrece yeni davran\u0131\u015f(lar) kazand\u0131r\u0131labilir.<\/p>\n<div style=\"font-size:12px;\">\n<pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\r\nFunctions functions = new();\r\n\r\nvar assistantAgent = new OpenAIChatAgent(\r\n      chatClient: new ChatClient(\r\n          model: model,\r\n          credential: new ApiKeyCredential(apiKey),\r\n          options: new OpenAIClientOptions()\r\n          {\r\n              Endpoint = new Uri(endpoint)\r\n          }),\r\n      name: &quot;assistant&quot;,\r\n      systemMessage: &quot;Sen kullan\u0131c\u0131n\u0131n baz\u0131 g\u00f6revleri yapmas\u0131na yard\u0131mc\u0131 olan bir asistans\u0131n.&quot;)\r\n      .RegisterMessageConnector()\r\n      .RegisterMiddleware(new FunctionCallMiddleware(\r\n          functions: &#x5B;functions.GetUsersAsyncFunctionContract],\r\n          functionMap: new Dictionary&lt;string, Func&lt;string, Task&lt;string&gt;&gt;&gt;()\r\n            {\r\n                { nameof(Functions.GetUsersAsync), functions.GetUsersAsyncWrapper}\r\n            }   \r\n          ))\r\n      .RegisterPrintMessage();\r\n\r\nvar result = await assistantAgent.GenerateReplyAsync(&#x5B;new TextMessage(Role.User, &quot;bana t\u00fcm kullan\u0131c\u0131lar\u0131n bilgilerini getir&quot;)]);\r\n<\/pre>\n<\/div>\n<p>Tabi <code>GenerateReplyAsync<\/code> metodu ile function calling tetiklenece\u011fi gibi <code>SendAsync<\/code> metoduyla da tetiklenecektir.<\/p>\n<div style=\"font-size:12px;\">\n<pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\r\nvar result = await assistantAgent.SendAsync(&quot;bana t\u00fcm kullan\u0131c\u0131lar\u0131n bilgilerini getir&quot;);\r\n<\/pre>\n<\/div>\n<p>Velhas\u0131l, prompt neticesinde gelen cevap a\u015fa\u011f\u0131daki g\u00f6rseldeki gibi olacakt\u0131r.<a href=\"https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2025\/05\/AutoGen-Ile-Coklu-Yapay-Zeka-Ajan-Sistemi-Gelistirme.png\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2025\/05\/AutoGen-Ile-Coklu-Yapay-Zeka-Ajan-Sistemi-Gelistirme.png\" alt=\"AutoGen \u0130le \u00c7oklu Yapay Zek\u00e2 Ajan Sistemi Geli\u015ftirme\" width=\"569\" height=\"977\" class=\"aligncenter size-full wp-image-27883\" srcset=\"https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2025\/05\/AutoGen-Ile-Coklu-Yapay-Zeka-Ajan-Sistemi-Gelistirme.png 569w, https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2025\/05\/AutoGen-Ile-Coklu-Yapay-Zeka-Ajan-Sistemi-Gelistirme-175x300.png 175w\" sizes=\"auto, (max-width: 569px) 100vw, 569px\" \/><\/a>Ayr\u0131ca function calling \u00f6zelli\u011fini, AI modelin \u00e7\u0131kt\u0131lar\u0131n\u0131 par\u00e7a par\u00e7a elde etti\u011fimiz (streaming) senaryolardaki <code>RegisterStreamingMiddleware<\/code> \u00fczerinden de a\u015fa\u011f\u0131daki gibi devreye sokup benzer neticeyi elde edebiliriz.<\/p>\n<div style=\"font-size:12px;\">\n<pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\r\n      .RegisterStreamingMiddleware(new FunctionCallMiddleware(\r\n          functions: &#x5B;functions.GetUsersAsyncFunctionContract],\r\n          functionMap: new Dictionary&lt;string, Func&lt;string, Task&lt;string&gt;&gt;&gt;()\r\n          {\r\n              { nameof(Functions.GetUsersAsync), functions.GetUsersAsyncWrapper}\r\n          }))\r\n<\/pre>\n<\/div>\n<blockquote><p><em>Function calling \u00f6zelli\u011fini kullanabilmek i\u00e7in tercih edilen AI modelinin bu davran\u0131\u015f\u0131 desteklemesi gerekmektedir. Bunun i\u00e7in i\u00e7erik s\u00fcrecinde bu ba\u015fl\u0131ktaki testleri <code>openai\/gpt-4.1-nano<\/code> AI modeliyle ger\u00e7ekle\u015ftirmi\u015f bulunuyorum.<\/em><\/p><\/blockquote>\n<p><strong>ChatTool S\u0131n\u0131f\u0131 Nedir?<\/strong><br \/>\nBu s\u0131n\u0131f, AutoGen i\u00e7erisindeki function&#8217;lar\u0131 temsil eden bir t\u00fcrd\u00fcr. Bir ba\u015fka deyi\u015fle, AI modelin function calling \u00f6zelli\u011fiyle \u00e7a\u011f\u0131rabilece\u011fi t\u00fcm function&#8217;lar <code>ChatTool<\/code> olarak tan\u0131mlanmaktad\u0131rlar.<\/p>\n<p>Bir kontrakt \u00fczerinden <code>ChatTool<\/code> nesnesine a\u015fa\u011f\u0131daki gibi <code>ToChatTool<\/code> metodu arac\u0131l\u0131\u011f\u0131yla eri\u015filebilmektedir.<\/p>\n<div style=\"font-size:12px;\">\n<pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\r\nvar getUsersAsyncFunctionChatTool = functions.GetUsersAsyncFunctionContract.ToChatTool();\r\n<\/pre>\n<\/div>\n<blockquote style=\"color:purple;\"><p><em><code>FunctionContract<\/code>&#8216;\u0131 fonksiyonun yap\u0131s\u0131n\u0131 JSON \u015femas\u0131 misali ifade eden teknik dok\u00fcmantasyon gibi d\u00fc\u015f\u00fcn\u00fcrsek, <code>ChatTool<\/code> ise bu \u015femay\u0131 LLM ile sohbet s\u0131ras\u0131nda fiziksel olarak kullan\u0131labilir bir nesne haline getiren ara\u00e7 olarak d\u00fc\u015f\u00fcnebiliriz.<\/em><\/p><\/blockquote>\n<p><strong>GetToolCalls Metodu Nedir?<\/strong><br \/>\nFunction calling&#8217;e dair bilinmesi gereken son \u015fey ise <code>GetToolCalls<\/code> metodudur. Bu metot, <code>IMessage<\/code> t\u00fcr\u00fcnden olan mesaj nesnelerinde mevcut olan <code>ToolCallMessage<\/code>&#8216;lar\u0131n listesini verecektir. Yani, AI modelinin yan\u0131t\u0131 s\u00fcrecinde yer alan t\u00fcm tool \u00e7a\u011fr\u0131lar\u0131n\u0131 bizlere sunacakt\u0131r. Bunu daha net anlamak i\u00e7in a\u015fa\u011f\u0131daki \u00f6rnek \u00fczerinden incelemede bulunmakta fayda vard\u0131r;<\/p>\n<div style=\"font-size:12px;\">\n<pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\r\nvar result = await assistantAgent.GenerateReplyAsync(&#x5B;new TextMessage(Role.User, &quot;bana 1,3 ve 5 id'li kullan\u0131c\u0131lar\u0131n bilgilerini getirir misin?&quot;)]);\r\nvar toolCalls = result.GetToolCalls();\r\n<\/pre>\n<\/div>\n<p>Yukar\u0131daki iste\u011fi AI modeli \u015fu \u015fekilde yorumlayacakt\u0131r;<\/p>\n<div style=\"font-size:12px;\">\n<pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\r\n&#x5B;\r\n  { &quot;name&quot;: &quot;GetUsersAsync&quot;, &quot;arguments&quot;: { &quot;userId&quot;: 3 } },\r\n  { &quot;name&quot;: &quot;GetUsersAsync&quot;, &quot;arguments&quot;: { &quot;userId&quot;: 5 } },\r\n  { &quot;name&quot;: &quot;GetUsersAsync&quot;, &quot;arguments&quot;: { &quot;userId&quot;: 7 } }\r\n]\r\n<\/pre>\n<\/div>\n<p>Haliyle t\u00fcm bu tool&#8217;lar\u0131 <code>GetToolCalls<\/code> metodunu \u00e7a\u011f\u0131r\u0131p a\u015fa\u011f\u0131daki g\u00f6rselde oldu\u011fu gibi programatik olarak elde edebiliriz;<a href=\"https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2025\/05\/AutoGen-Ile-Coklu-Yapay-Zeka-Ajan-Sistemi-Gelistirme-1.png\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2025\/05\/AutoGen-Ile-Coklu-Yapay-Zeka-Ajan-Sistemi-Gelistirme-1.png\" alt=\"AutoGen \u0130le \u00c7oklu Yapay Zek\u00e2 Ajan Sistemi Geli\u015ftirme\" width=\"567\" height=\"166\" class=\"aligncenter size-full wp-image-27884\" srcset=\"https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2025\/05\/AutoGen-Ile-Coklu-Yapay-Zeka-Ajan-Sistemi-Gelistirme-1.png 567w, https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2025\/05\/AutoGen-Ile-Coklu-Yapay-Zeka-Ajan-Sistemi-Gelistirme-1-300x88.png 300w\" sizes=\"auto, (max-width: 567px) 100vw, 567px\" \/><\/a><\/p>\n<h4>Birden Fazla Agent&#8217;\u0131 Kendi Aralar\u0131nda Konu\u015fturma<\/h4>\n<p>AutoGen&#8217;de birden fazla agent&#8217;\u0131 kendi aralar\u0131nda s\u0131ral\u0131 bir \u015fekilde yahut belirlenen kurallara g\u00f6re konu\u015fturabilmekteyiz. E\u011fer ki s\u0131ral\u0131 bir \u015fekilde konu\u015fturulacaklarsa <code>RoundRobinGroupChat<\/code>, yok e\u011fer belirlenen kurallara g\u00f6re ya da agent&#8217;lar\u0131n rol ve ge\u00e7mi\u015flerine g\u00f6re konu\u015fturulacaklarsa da <code>GroupChat<\/code> tercih edilmelidir.<\/p>\n<table style=\"font-size:12px;\">\n<thead>\n<tr>\n<th style=\"width:50%;\">GroupChat<\/th>\n<th>RoundRobinGroupChat<\/th>\n<\/tr>\n<\/thead>\n<tbody>\n<tr>\n<td style=\"text-align:left;vertical-align: text-top;\">Kural tabanl\u0131d\u0131r. Ak\u0131ll\u0131 y\u00f6nlendirme yapar. Mesajlar\u0131 sohbete kat\u0131l\u0131mc\u0131 agent&#8217;lara rol, ge\u00e7mi\u015f ve i\u00e7erik bazl\u0131 olarak y\u00f6nlendirir. B\u00f6ylece her agent kendi i\u00e7 kurallar\u0131na g\u00f6re gelen mesaj\u0131 al\u0131p almayaca\u011f\u0131na karar verir ve cevap verecek agent&#8217;lar da i\u00e7 mant\u0131klar\u0131na g\u00f6re belirlenir. Bu y\u00fczden ak\u0131\u015f her daim s\u0131raya g\u00f6re gitmek zorunda de\u011fildir.<\/p>\n<p><u>\u2705Avantajlar\u0131;<\/u><\/p>\n<ul>\n<li>Agent&#8217;lar gelen mesajlar\u0131 gerekmedi\u011fi s\u00fcrece i\u015flemeyebilecek esnekli\u011fe sahiptirler.<\/li>\n<li>Gelen mesaja ilgili ya da direkt uzman\u0131 olan agent&#8217;lar cevap verecektir.<\/li>\n<li>Her agent kendi alan\u0131nda konu\u015faca\u011f\u0131 i\u00e7in t\u0131pk\u0131 ger\u00e7ek bir tak\u0131m gibi daha &#8216;ak\u0131ll\u0131&#8217; hissi vermektedir.<\/li>\n<\/ul>\n<p><u>\ud83d\udeabDezavantajlar\u0131;<\/u><\/p>\n<ul>\n<li>\u0130ster istemez y\u00f6netimi daha karma\u015f\u0131kt\u0131r.<\/li>\n<\/ul>\n<\/td>\n<td style=\"text-align:left;vertical-align: text-top\">D\u00f6n\u00fc\u015f\u00fcml\u00fcd\u00fcr. S\u0131rayla i\u015fleme yapar. Her agent s\u0131rayla konu\u015fur, mesaj\u0131 i\u015fler, sonra s\u0131radakine devreder. Haliyle her agent, alakas\u0131 olsun ya da olmas\u0131n \u00e7al\u0131\u015facak, bir cevap \u00fcretecektir.<\/p>\n<p><u>\u2705Avantajlar\u0131;<\/u><\/p>\n<ul>\n<li>Hangi agent&#8217;\u0131n ne zaman devreye girece\u011fi tahmin edilebilir, hatta bilinir.<\/li>\n<li>Debug ve demo durumlar i\u00e7in ideal bir davran\u0131\u015ft\u0131r.<\/li>\n<li>Agent&#8217;lar\u0131n s\u00fcrece aktif kat\u0131l\u0131m\u0131n\u0131 garanti etmektedir.<\/li>\n<\/ul>\n<p><u>\ud83d\udeabDezavantajlar\u0131;<\/u><\/p>\n<ul>\n<li>Her agent konuyla alakas\u0131 olmasa bile cevap vermeye zorlan\u0131r.<\/li>\n<li>Uzmanl\u0131k filtresi yoktur! Her agent, her konuda konu\u015fur.<\/li>\n<\/ul>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>\u015eimdi gelin <code>GroupChat<\/code>&#8216;i belirli senaryo e\u015fli\u011finde pratikte \u00f6rneklendirelim;<\/p>\n<div style=\"background-color:#e1e7cf;color:purple;text-align:center;\">\nSenaryo<\/p>\n<div style=\"color:black;font-size:12px;\">\nAgent&#8217;lar \u00fczerinden seyreden dinamik bir kodlama s\u00fcreci d\u00fc\u015f\u00fcnelim. Bu s\u00fcre\u00e7te coder, runner, reviewer ve admin olmak \u00fczere d\u00f6rt agent&#8217;tan ibaret bir \u00e7al\u0131\u015fma ger\u00e7ekle\u015ftirecek ve aralar\u0131ndaki haberle\u015fmeyi a\u015fa\u011f\u0131daki gibi modelliyor olaca\u011f\u0131z;<\/p>\n<div style=\"display: flex; flex-direction: column; gap: 10px; width: 100%;\">\n<div style=\"display: flex; border-radius: 8px; overflow: hidden; background-color: #3498db; color: white; height: 100px;\">\n<div style=\"width: 120px; background-color: #2980b9; display: flex; align-items: center; justify-content: center; font-weight: bold;\">\n      Admin\n    <\/div>\n<div style=\"flex: 1; display: flex; align-items: center; padding: 0 16px; line-height: 20px;\">\n      GroupChat i\u00e7erisinde yer alacak olan bu \u00f6zel agent&#8217;\u0131n g\u00f6revi, grup i\u00e7indeki konu\u015fmay\u0131 t\u0131pk\u0131 bir moderat\u00f6r gibi y\u00f6netmek, ak\u0131\u015fa m\u00fcdahale etmek ve gerekiyorsa y\u00f6nlendirme kararlar\u0131 almakt\u0131r. Yani s\u00fcre\u00e7te kimin konu\u015faca\u011f\u0131n\u0131 belirlemekte ve hangi mesaj\u0131n hangi agent&#8217;a y\u00f6nlendirilece\u011fini kontrol etmektedir. Tabi gerekti\u011fi taktirde de konu\u015fmay\u0131 sonland\u0131rmakta ve \u00f6zet \u00e7\u0131kar\u0131p, neticeyi de\u011fi\u015ftirebilmektedir.\n    <\/div>\n<\/p><\/div>\n<div style=\"display: flex; border-radius: 8px; overflow: hidden; background-color: #2ecc71; color: white; height: 100px;\">\n<div style=\"width: 120px; background-color: #27ae60; display: flex; align-items: center; justify-content: center; font-weight: bold;\">\n      Coder\n    <\/div>\n<div style=\"flex: 1; display: flex; align-items: center; padding: 0 16px;\">\n     Verilen g\u00f6revi \u00e7\u00f6zebilmek i\u00e7in kod yazacak olan agent&#8217;t\u0131r.\n    <\/div>\n<\/p><\/div>\n<div style=\"display: flex; border-radius: 8px; overflow: hidden; background-color: #9b59b6; color: white; height: 100px; \">\n<div style=\"width: 120px; background-color: #8e44ad; display: flex; align-items: center; justify-content: center; font-weight: bold;\">\n     Reviewer\n  <\/div>\n<div style=\"flex: 1; display: flex; flex-direction: column; justify-content: center; padding: 0 16px;\">\n<div style=\"text-align:left;\">\n      Coder taraf\u0131ndan yaz\u0131lan kodu a\u015fa\u011f\u0131daki kurallar do\u011frultusunda inceleyecek agent&#8217;t\u0131r.\n    <\/div>\n<div style=\"text-align:left;line-height: 16px;\">\n<ul style=\"margin: 0; padding-left: 20px;\">\n<li>Yaln\u0131zca tek bir csharp kod blo\u011fu kullan\u0131lmal\u0131.<\/li>\n<li>Top-level statements kullan\u0131lmal\u0131.<\/li>\n<li>\u00dcretilen kod dotnet code snippet olmal\u0131.<\/li>\n<li>Kod neticesi console&#8217;a yazd\u0131r\u0131l\u0131yor olmal\u0131.<\/li>\n<\/ul><\/div>\n<\/p><\/div>\n<\/div>\n<div style=\"display: flex; border-radius: 8px; overflow: hidden; background-color: #e74c3c; color: white; height: 100px;\">\n<div style=\"width: 120px; background-color: #c0392b; display: flex; align-items: center; justify-content: center; font-weight: bold;\">\n      Runner\n    <\/div>\n<div style=\"flex: 1; display: flex; align-items: center; padding: 0 16px;\">\n      Coder taraf\u0131ndan yaz\u0131lan kodu \u00e7al\u0131\u015ft\u0131racak agent&#8217;t\u0131r.\n    <\/div>\n<\/p><\/div>\n<\/div>\n<p>Evet, \u015fimdi bu senaryoyu a\u015fa\u011f\u0131daki ad\u0131mlar e\u015fli\u011finde geli\u015ftirme yaparak ger\u00e7ekle\u015ftirebiliriz;<\/p>\n<ul style=\"text-align:left;\">\n<li><strong>Ad\u0131m 1<\/strong> &#8211; <span style=\"color:green;font-size:12px;\"><i>(Admin Agent&#8217;\u0131n Olu\u015fturulmas\u0131)<\/i><\/span><br \/>\n\u0130lk olarak admin agent&#8217;\u0131 olu\u015fturarak ba\u015flayaca\u011f\u0131z. Bunun i\u00e7in a\u015fa\u011f\u0131daki gibi bir \u00e7al\u0131\u015fman\u0131n yap\u0131lmas\u0131 yeterli olacakt\u0131r.<\/p>\n<div style=\"font-size:12px;width:95%;\">\n<pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\r\n        async static Task&lt;IAgent&gt; CreateAdminAgentAsync(string apiKey, string model, string endpoint)\r\n        {\r\n            var admin = new OpenAIChatAgent(\r\n                chatClient: new ChatClient(\r\n                model: model,\r\n                credential: new ApiKeyCredential(apiKey),\r\n                options: new OpenAIClientOptions()\r\n                {\r\n                    Endpoint = new Uri(endpoint)\r\n                }),\r\n                name: &quot;admin&quot;,\r\n                temperature: 0)\r\n                .RegisterMessageConnector()\r\n                .RegisterPrintMessage();\r\n\r\n            return admin;\r\n        }\r\n<\/pre>\n<\/div>\n<p>Burada <code>temperature<\/code> parametresi dikkatinizi \u00e7ekmi\u015f olabilir. Bu parametre ile AI modelinin \u00fcretece\u011fi yan\u0131tlar\u0131n rastgeleli\u011fini(\u00e7e\u015fitlilik) kontrol ediyoruz. <em>Nas\u0131l yani?<\/em> diye sorarsan\u0131z; olas\u0131 kelime veya yan\u0131tlar aras\u0131ndan se\u00e7im yaparken ne kadar &#8216;cesur&#8217; ya da &#8216;temkinli&#8217; olaca\u011f\u0131n\u0131 kastediyoruz. Yani AI modeli daha yarat\u0131c\u0131 m\u0131 olsun yoksa daha deterministik(tahmin edilebilir) mi? Bu mant\u0131k do\u011frultusunda ilgili parametre 0 ile 2 aras\u0131nda bir de\u011fer almakta ve a\u015fa\u011f\u0131daki tan\u0131mland\u0131\u011f\u0131 gibi AI modele davran\u0131\u015f kazand\u0131rmaktad\u0131r. <\/p>\n<table>\n<thead>\n<tr>\n<th style=\"width:10%;line-height: 15px;\">Temperature De\u011feri<\/th>\n<th>Davran\u0131\u015f\u0131<\/th>\n<\/tr>\n<\/thead>\n<tbody>\n<tr>\n<td style=\"text-align:left;\">0<\/td>\n<td style=\"text-align:left;\">Tamamen deterministik davran\u0131\u015f sergiler ve her daim en olas\u0131 yan\u0131tlar verir. En g\u00fcvenilir ve net sonu\u00e7lar bu de\u011ferle \u00fcretilir.<\/td>\n<\/tr>\n<tr>\n<td style=\"text-align:left;\">0.3 &#8211; 0.5<\/td>\n<td style=\"text-align:left;\">D\u00fc\u015f\u00fck rastgelelelik s\u00f6z konusudur. Hala mant\u0131kl\u0131 ama biraz daha \u00e7e\u015fitli cevaplar \u00fcretir.<\/td>\n<\/tr>\n<tr>\n<td style=\"text-align:left;\">0.7 &#8211; 1.0<\/td>\n<td style=\"text-align:left;\">Dengeli bir yarat\u0131c\u0131l\u0131k seviyesi hakimdir. Bazen tutars\u0131z cevaplar olabilir.<\/td>\n<\/tr>\n<tr>\n<td style=\"text-align:left;\">1.0><\/td>\n<td style=\"text-align:left;\">Y\u00fcksek rastgelelik mevzu bahistir. Kimi zaman a\u015f\u0131r\u0131, kimi zaman da sa\u00e7ma sonu\u00e7lar olabilir.<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>Dikkat ederseniz say\u0131sal de\u011fer y\u00fckseldik\u00e7e rastgelelik artmaktad\u0131r.<\/p>\n<p>Admin agent, g\u00f6revleri y\u00f6neten ve di\u011fer ajanlar\u0131 koordine eden ana kontrol agent&#8217;\u0131 oldu\u011fu i\u00e7in g\u00f6revleri a\u00e7\u0131k ve net tan\u0131mlamal\u0131, di\u011fer agent&#8217;lar\u0131 do\u011fru y\u00f6nlendirmeli ve rastgelelikten uzak, tutarl\u0131 ve kararl\u0131 olmal\u0131d\u0131r. \u0130\u015fte bu y\u00fczden temperature de\u011feri 0 ile maksimum 0.3 aras\u0131nda olmal\u0131d\u0131r.\n<\/li>\n<li><strong>Ad\u0131m 2<\/strong> &#8211; <span style=\"color:green;font-size:12px;\"><i>Coder Agent&#8217;\u0131n Olu\u015fturulmas\u0131<\/i><\/span><br \/>\nCoder agent&#8217;\u0131 ise a\u015fa\u011f\u0131daki gibi olu\u015fturabiliriz.<\/p>\n<div style=\"font-size:12px;width:95%;\">\n<pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\r\n        async static Task&lt;IAgent&gt; CreateCoderAgentAsync(string apiKey, string model, string endpoint)\r\n        {\r\n            var coder = new OpenAIChatAgent(\r\n                chatClient: new ChatClient(\r\n                model: model,\r\n                credential: new ApiKeyCredential(apiKey),\r\n                options: new OpenAIClientOptions()\r\n                {\r\n                    Endpoint = new Uri(endpoint)\r\n                }),\r\n                name: &quot;coder&quot;,\r\n                systemMessage: @&quot;\r\n                    Sen bir .net(dotnet) coder's\u0131n ve gelen task'taki problemi \u00e7\u00f6zmek i\u00e7in dotnet'te C# kodu yaz\u0131yorsun.\r\n                    Kod yazmay\u0131 bitirdi\u011finde runner'dan kodu senin i\u00e7in \u00e7al\u0131\u015ft\u0131rmas\u0131n\u0131 isteyeceksin.\r\n\r\n                    Dotnet kodu yazarken uyulmas\u0131 gereken kurallar:\r\n                        - Disposable olan nesneleri olu\u015ftururken 'using' keyword'\u00fcn\u00fc kullanma!\r\n                        - De\u011fi\u015fken t\u00fcrlerinde 'var' kullan.\r\n                        - Local variable'lar\u0131n default de\u011ferini her zaman ata!\r\n                        - Harici k\u00fct\u00fcphane kullanmaktan ka\u00e7\u0131n. M\u00fcmk\u00fcn mertebe .NET Core k\u00fct\u00fcphanesi kullan.\r\n                        - Kod yazmak i\u00e7in 'top level statement' kullan.\r\n                        - Sonucu her zaman console'a yazd\u0131r.\r\n                        - E\u011fer NuGet paketi y\u00fcklenmesi gerekiyorsa, ilgili paketi a\u015fa\u011f\u0131daki bi\u00e7imde yerle\u015ftir.\r\n                            ```nuget\r\n                            nuget_package_name\r\n                            ```\r\n                        - Kod yanl\u0131\u015fsa runner sana hata mesaj\u0131n\u0131 verecektir. Hatay\u0131 d\u00fczelt ve kodu tekrar g\u00f6nder.&quot;)\r\n                .RegisterMessageConnector()\r\n                .RegisterPrintMessage();\r\n\r\n            return coder;\r\n        }\r\n<\/pre>\n<\/div>\n<p>Burada dikkat edilmesi gereken husus bu agent&#8217;t\u0131n davran\u0131\u015fsal kapsam\u0131n\u0131n system message(system prompt) olarak detayl\u0131ca belirleniyor olmas\u0131d\u0131r. Evet, bu agent \u00e7al\u0131\u015fmalar\u0131nda olduk\u00e7a hayati bir \u00f6nem arz etmektedir. Agent&#8217;lar da system prompt&#8217;lar ile g\u00f6revler ve davran\u0131\u015flar iyice detayland\u0131r\u0131lmal\u0131d\u0131r.\n<\/li>\n<li><strong>Ad\u0131m 3<\/strong> &#8211; <span style=\"color:green;font-size:12px;\"><i>Reviewer Agent&#8217;\u0131n Olu\u015fturulmas\u0131<\/i><\/span><br \/>\nReviewer agent ile \u00fcretilen kodun belirtilen ko\u015fullara uyup uymad\u0131\u011f\u0131n\u0131 de\u011ferlendirebilmek i\u00e7in a\u015fa\u011f\u0131daki gibi bir function tasarlayabiliriz.<\/p>\n<p>Tabi function&#8217;dan \u00f6nce ko\u015fullar\u0131 modelledi\u011fimiz bir yap\u0131 ortaya koyal\u0131m;<\/p>\n<div style=\"font-size:12px;width:95%;\">\n<pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\r\npublic struct CodeReviewResult\r\n{\r\n    public bool HasMultipleCodeBlocks { get; set; }\r\n    public bool IsTopLevelStatement { get; set; }\r\n    public bool IsDotnetCodeBlock { get; set; }\r\n    public bool IsPrintResultToConsole { get; set; }\r\n}\r\n<\/pre>\n<\/div>\n<p>Bu struct bizlere, reviewer agent&#8217;\u0131 taraf\u0131ndan incelenen kodun hangi \u015fartlara uyup uymad\u0131\u011f\u0131n\u0131 tip g\u00fcvenli bir \u015fekilde tutmam\u0131z\u0131 ve kontrol etmemizi sa\u011flayacak bir t\u00fcr sa\u011flamaktad\u0131r.<\/p>\n<div style=\"font-size:12px;width:95%;\">\n<pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\r\npublic partial class Functions\r\n{\r\n    \/\/\/ &lt;summary&gt;\r\n    \/\/\/ review code block\r\n    \/\/\/ &lt;\/summary&gt;\r\n    \/\/\/ &lt;param name=&quot;hasMultipleCodeBlocks&quot;&gt;Birden fazla csharp kod blo\u011fu varsa true de\u011ferindedir.&lt;\/param&gt;\r\n    \/\/\/ &lt;param name=&quot;isTopLevelStatement&quot;&gt;E\u011fer kod top level statement ise true de\u011ferindedir.&lt;\/param&gt;\r\n    \/\/\/ &lt;param name=&quot;isDotnetCodeBlock&quot;&gt;E\u011fer kod blo\u011fu csharp koduysa true de\u011ferindedir.&lt;\/param&gt;\r\n    \/\/\/ &lt;param name=&quot;isPrintResultToConsole&quot;&gt;E\u011fer kod neticesinde console'a yaz\u0131l\u0131yorsa true de\u011ferindedir.&lt;\/param&gt;\r\n    &#x5B;Function]\r\n    public async Task&lt;string&gt; ReviewCodeBlockAsync(\r\n        bool hasMultipleCodeBlocks,\r\n        bool isTopLevelStatement,\r\n        bool isDotnetCodeBlock,\r\n        bool isPrintResultToConsole)\r\n    {\r\n        var obj = new CodeReviewResult\r\n        {\r\n            HasMultipleCodeBlocks = hasMultipleCodeBlocks,\r\n            IsTopLevelStatement = isTopLevelStatement,\r\n            IsDotnetCodeBlock = isDotnetCodeBlock,\r\n            IsPrintResultToConsole = isPrintResultToConsole,\r\n        };\r\n\r\n        return JsonSerializer.Serialize(obj);\r\n    }\r\n}\r\n<\/pre>\n<\/div>\n<p>Bu da review edilen kod blo\u011funu <code>CodeReviewResult<\/code> t\u00fcr\u00fcne d\u00f6n\u00fc\u015ft\u00fcrecek fonksiyonun tan\u0131m\u0131d\u0131r. LLM bu fonksiyon arac\u0131l\u0131\u011f\u0131yla kodun de\u011ferlendirmesini bir JSON objesi olarak bizlere sunacak ve bizler de bu de\u011ferlendirmeyi zahiren rahatl\u0131kla g\u00f6rebiliyor olaca\u011f\u0131z.<\/p>\n<p>Ard\u0131ndan reviewer agent a\u015fa\u011f\u0131daki gibi geli\u015ftirilebilir;<\/p>\n<div style=\"font-size:12px;width:95%;\">\n<pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\r\n        async static Task&lt;IAgent&gt; CreateReviewerAgentAsync(string apiKey, string model, string endpoint)\r\n        {\r\n            var functions = new Functions();\r\n\r\n            var reviewer = new OpenAIChatAgent(\r\n                chatClient: new ChatClient(\r\n                model: model,\r\n                credential: new ApiKeyCredential(apiKey),\r\n                options: new OpenAIClientOptions()\r\n                {\r\n                    Endpoint = new Uri(endpoint)\r\n                }),\r\n                name: &quot;reviewer&quot;,\r\n                systemMessage: &quot;Sen coder'\u0131n olu\u015fturdu\u011fu kodlar\u0131 inceliyorsun.&quot;)\r\n                .RegisterMessageConnector()\r\n                .RegisterMiddleware(new FunctionCallMiddleware(\r\n                    functions: &#x5B;functions.ReviewCodeBlockAsyncFunctionContract],\r\n                    functionMap: new Dictionary&lt;string, Func&lt;string, Task&lt;string&gt;&gt;&gt;()\r\n                    {\r\n                        { nameof(Functions.ReviewCodeBlockAsync), functions.ReviewCodeBlockAsyncWrapper}\r\n                    }\r\n                ))\r\n                .RegisterPrintMessage()\r\n                .RegisterMiddleware(async (messages, options, innerAgent, cancellationToken) =&gt;\r\n                {\r\n                    var maxRetry = 3;\r\n                    var reply = await innerAgent.GenerateReplyAsync(messages, options, cancellationToken);\r\n                    while (maxRetry-- &gt; 0)\r\n                    {\r\n                        if (reply.GetToolCalls() is var toolCalls &amp;&amp; toolCalls?.Count == 1 &amp;&amp; toolCalls?&#x5B;0].FunctionName == nameof(Functions.ReviewCodeBlockAsync))\r\n                        {\r\n\r\n                            var replyContent = reply.GetContent();\r\n                            var reviewResultObject = JsonSerializer.Deserialize&lt;CodeReviewResult&gt;(replyContent);\r\n                            var reviews = new List&lt;string&gt;();\r\n\r\n                            if (reviewResultObject.HasMultipleCodeBlocks)\r\n                                reviews.Add(&quot;Kod birden fazla kod blo\u011funa sahip. L\u00fctfen tek bir kod blo\u011fu g\u00f6nder.&quot;);\r\n\r\n                            if (!reviewResultObject.IsTopLevelStatement)\r\n                                reviews.Add(&quot;Kod top level statement de\u011fil. L\u00fctfen top level statement kullan.&quot;);\r\n\r\n                            if (!reviewResultObject.IsDotnetCodeBlock)\r\n                                reviews.Add(&quot;Kod csharp kod blo\u011fu de\u011fil. L\u00fctfen csharp kod blo\u011fu kullan.&quot;);\r\n\r\n                            if (!reviewResultObject.IsPrintResultToConsole)\r\n                                reviews.Add(&quot;Kod sonucu console'a yazd\u0131rm\u0131yor. L\u00fctfen sonucu console'a yazd\u0131r.&quot;);\r\n\r\n                            if (reviews.Count &gt; 0)\r\n                            {\r\n                                StringBuilder stringBuilder = new();\r\n                                stringBuilder.AppendLine(&quot;Kod reviewer a\u00e7\u0131s\u0131ndan baz\u0131 kurallara uyulmam\u0131\u015ft\u0131r. Bunlar d\u00fczeltilmelidir;&quot;);\r\n\r\n                                foreach (var review in reviews)\r\n                                    stringBuilder.AppendLine($&quot;- {review}&quot;);\r\n\r\n                                return new TextMessage(Role.Assistant, stringBuilder.ToString(), from: &quot;reviewer&quot;);\r\n                            }\r\n                            else\r\n                                return new TextMessage(Role.Assistant, &quot;Ge\u00e7erli kod, runner kodu \u00e7al\u0131\u015ft\u0131rabilir.&quot;);\r\n                        }\r\n                        else\r\n                        {\r\n                            var originalContent = reply.GetContent();\r\n                            var prompt = $@&quot;L\u00fctfen i\u00e7eri\u011fi ReviewCodeBlockAsync fonksiyon parametrelerine d\u00f6n\u00fc\u015ft\u00fcr.\r\n                                ## Original Content\r\n                                {originalContent}\r\n                            &quot;;\r\n\r\n                            reply = await innerAgent.SendAsync(prompt, messages, cancellationToken);\r\n                        }\r\n                    }\r\n                    throw new Exception(&quot;Kod blo\u011funu inceleme ba\u015far\u0131s\u0131z oldu!&quot;);\r\n                });\r\n\r\n            return reviewer;\r\n        }\r\n<\/pre>\n<\/div>\n<p>Burada da \u00f6zellikle 28 ile 72. sat\u0131r aral\u0131\u011f\u0131na dikkat ederseniz, yap\u0131lan istekte <em>ReviewCodeBlockAsync<\/em> ad\u0131nda tool \u00e7a\u011fr\u0131s\u0131 varsa e\u011fer bu tool&#8217;un neticesi JSON olarak elde edilmekte ve \u00fcretilen kod taraf\u0131m\u0131zca belirlenen ko\u015fullar do\u011frultusunda de\u011ferlendirilmektedir. Tabi bu de\u011ferlendirme s\u00fcrecinde de tak\u0131n\u0131lan kurallar varsa onlar metinsel olarak bir koleksiyona not al\u0131nmakta ve 49 ile 58. sat\u0131r aral\u0131\u011f\u0131nda bu notlar mesaj olarak g\u00f6nderilip sistem bilgilendirilmektedir. Yok e\u011fer tool hi\u00e7 \u00e7a\u011fr\u0131lmam\u0131\u015fsa o taktirde de 62 ile 71. sat\u0131r aral\u0131\u011f\u0131nda oldu\u011fu gibi ilgili tool&#8217;un \u00e7a\u011fr\u0131mas\u0131 gerekti\u011fine dair at\u0131fta bulunulmaktad\u0131r.<\/p>\n<p><span style=\"color:red;\">Dikkat! Burada <code>FunctionCallMiddleware<\/code>&#8216;in <code>RegisterPrintMessage<\/code>&#8216;dan \u00f6nce tan\u0131mlanmas\u0131na \u00f6zen g\u00f6steriniz. Aksi taktirde agent&#8217;a tan\u0131mlanan hi\u00e7bir tool di\u011fer middleware&#8217;ler taraf\u0131ndan alg\u0131lanmayacakt\u0131r.<\/span>\n<\/li>\n<li><strong>Ad\u0131m 4<\/strong> &#8211; <span style=\"color:green;font-size:12px;\"><i>Runner Agent&#8217;\u0131n Olu\u015fturulmas\u0131<\/i><\/span><br \/>\nRunner, coder&#8217;\u0131n \u00fcretece\u011fi kodlar\u0131 \u00e7al\u0131\u015ft\u0131raca\u011f\u0131 i\u00e7in \u00f6ncelikle \u00fcretilen kodu metinsel konseptinden yakalayabilmesi gerekmektedir. \u015e\u00f6yle ki; coder \u00fcretece\u011fi kodu<\/p>\n<div style=\"font-size:12px;width:100px\">\n<pre class=\"brush: plain; title: ; notranslate\" title=\"\">\r\n        ```csharp\r\n        \r\n        ``` \r\n<\/pre>\n<\/div>\n<p>i\u00e7erisine koyaca\u011f\u0131 i\u00e7in buradan saf bir \u015fekilde bu kodun metinsel de\u011ferlerden temizlenerek elde edilmesi gerekecektir. Haliyle bunun i\u00e7in <a href=\"https:\/\/www.nuget.org\/packages\/AutoGen.DotnetInteractive\" target=\"_blank\">AutoGen.DotnetInteractive<\/a> k\u00fct\u00fcphanesinin extension&#8217;lar\u0131na ihtiya\u00e7 duyaca\u011f\u0131z. Ayr\u0131ca \u00fcretilen C# kodunu \u00e7al\u0131\u015ft\u0131rabilmek i\u00e7in bu k\u00fct\u00fcphanenin bizlere sundu\u011fu C# Kernel&#8217;dan istifade edece\u011fiz.<\/p>\n<p>\u00d6ncelikle C# Kernel&#8217;\u0131 olu\u015fturarak ilerleyelim;<\/p>\n<div style=\"font-size:12px;width:95%;\">\n<pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\r\n            var kernel = new CompositeKernel()\r\n            {\r\n                new CSharpKernel().UseKernelHelpers()\r\n            }.UseDefaultMagicCommands();\r\n            kernel.DefaultKernelName = &quot;csharp&quot;;\r\n<\/pre>\n<\/div>\n<p>Burada kulland\u0131\u011f\u0131m\u0131z <code>new CSharpKernel().UseKernelHelpers()<\/code> metodu varsay\u0131lan olarak C#&#8217;\u0131 destekleyen bir kernel yap\u0131land\u0131rmaktad\u0131r. Bu kernel e\u015fli\u011finde a\u015fa\u011f\u0131daki gibi agent&#8217;\u0131 geli\u015ftirebiliriz;<\/p>\n<div style=\"font-size:12px;width:95%;\">\n<pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\r\n        async static Task&lt;IAgent&gt; CreateRunnerAgentAsync(string apiKey, string model, string endpoint)\r\n        {\r\n            var kernel = new CompositeKernel()\r\n            {\r\n                new CSharpKernel().UseKernelHelpers()\r\n            }.UseDefaultMagicCommands();\r\n            kernel.DefaultKernelName = &quot;csharp&quot;;\r\n\r\n            var runner = new DefaultReplyAgent(\r\n                name: &quot;runner&quot;,\r\n                defaultReply: &quot;Ge\u00e7ersiz kod!&quot;)\r\n                .RegisterMiddleware(async (messages, option, agent, _) =&gt;\r\n                {\r\n                    if (!messages.Any())\r\n                        return new TextMessage(Role.Assistant, &quot;Ge\u00e7ersiz kod! Coder l\u00fctfen kodu yaz.&quot;);\r\n                    else\r\n                    {\r\n                        var coderMessage = messages.Last(message =&gt; message.From == &quot;coder&quot;);\r\n                        if (coderMessage.ExtractCodeBlock(&quot;```csharp&quot;, &quot;```&quot;) is string code)\r\n                        {\r\n                            var codeResult = await kernel.RunSubmitCodeCommandAsync(code, &quot;csharp&quot;);\r\n                            codeResult = $&quot;&quot;&quot;\r\n                                &#x5B;RUNNER_RESULT]\r\n                                {codeResult}\r\n                                &quot;&quot;&quot;;\r\n\r\n                            return new TextMessage(Role.Assistant, codeResult)\r\n                            {\r\n                                From = &quot;runner&quot;\r\n                            };\r\n                        }\r\n                        else\r\n                            return new TextMessage(Role.Assistant, &quot;Ge\u00e7ersiz kod! Coder l\u00fctfen kodu yaz.&quot;);\r\n                    }\r\n                })\r\n                      .RegisterPrintMessage();\r\n\r\n            return runner;\r\n        }\r\n<\/pre>\n<\/div>\n<p>Runner agent&#8217;\u0131n\u0131n kodlar\u0131n\u0131 da incelerseniz, e\u011fer gelen bir mesaj varsa bu demek oluyor ki \u00fcretilen bir kod vard\u0131r. Haliyle bu kod 19. sat\u0131rda <code>ExtractCodeBlock<\/code> metodu ile yukar\u0131daki sat\u0131rlarda bahsedildi\u011fi gibi salt bir \u015fekilde metinsel de\u011ferin i\u00e7erisinden al\u0131nmakta ve 21. sat\u0131rda da <code>RunSubmitCodeCommandAsync<\/code> metodu ile C# kernel&#8217;\u0131nda \u00e7al\u0131\u015ft\u0131r\u0131larak \u00fcretilen sonu\u00e7 elde edilmektedir.\n<\/li>\n<li><strong>Ad\u0131m 5<\/strong> &#8211; <span style=\"color:green;font-size:12px;\"><i>Agent&#8217;lar\u0131n Olu\u015fturulmas\u0131 ve Birbirlerine Rol ve G\u00f6rev Tan\u0131mlar\u0131nda Bulunarak, S\u00fcrecin Ba\u015flat\u0131lmas\u0131<\/i><\/span><br \/>\nOlu\u015fturulan <code>GroupChat<\/code> i\u00e7inde agent&#8217;lar aras\u0131 i\u015fbirli\u011finin sa\u011flanmas\u0131 ve g\u00f6rev payla\u015f\u0131m\u0131n\u0131n netle\u015fmesi i\u00e7in her agent&#8217;\u0131n di\u011fer agent&#8217;lara kim oldu\u011funu ve ne yapaca\u011f\u0131n\u0131 s\u00f6ylemesi gerekmektedir. B\u00f6ylece bir yandan da her agent&#8217;\u0131n kendi g\u00f6revini anlad\u0131\u011f\u0131 da ifade edilmi\u015f olunacakt\u0131r. Bunun i\u00e7in a\u015fa\u011f\u0131daki gibi <code>SendIntroduction<\/code> metodundan istifade edilmektedir.<\/p>\n<div style=\"font-size:12px;width:95%;\">\n<pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\r\n        public static async Task RunAsync(string apiKey, string model, string endpoint)\r\n        {\r\n            var admin = await CreateAdminAgentAsync(apiKey, model, endpoint);\r\n            var coder = await CreateCoderAgentAsync(apiKey, model, endpoint);\r\n            var reviewer = await CreateReviewerAgentAsync(apiKey, model, endpoint);\r\n            var runner = await CreateRunnerAgentAsync(apiKey, model, endpoint);\r\n\r\n            var groupChat = new GroupChat(\r\n                admin: admin,\r\n                members: &#x5B;coder, reviewer, runner]);\r\n\r\n            admin.SendIntroduction(&quot;Gelen g\u00f6revin \u00e7\u00f6z\u00fcm s\u00fcrecini takip edece\u011fim. \u00c7\u00f6z\u00fcld\u00fc\u011f\u00fc zaman da s\u00fcreci sonland\u0131raca\u011f\u0131m.&quot;, groupChat);\r\n            coder.SendIntroduction(&quot;Gelen g\u00f6revi \u00e7\u00f6zmek i\u00e7in dotnet kodu yazaca\u011f\u0131m.&quot;, groupChat);\r\n            reviewer.SendIntroduction(&quot;Coder taraf\u0131ndan \u00fcretilen dotnet kodunu kurallar do\u011frultusunda g\u00f6zden ge\u00e7irece\u011fim. Onaylanmad\u0131\u011f\u0131m zaman coder tekrardan kod yazd\u0131raca\u011f\u0131m ve onaylayana kadar denetleyece\u011fim.&quot;, groupChat);\r\n            runner.SendIntroduction(&quot;Reviewer incelemeye tamamlad\u0131ktan sonra dotnet kodunu \u00e7al\u0131\u015ft\u0131raca\u011f\u0131m.&quot;, groupChat);\r\n\r\n            var result = groupChat.SendAsync(&#x5B;new TextMessage(Role.User, &quot;Bana fibonacci say\u0131 diziminde 35. haneyi verir misin?&quot;)], maxRound: 15);\r\n            await foreach (var message in result)\r\n            {\r\n                if (message.From == &quot;runner&quot;)\r\n                    Console.WriteLine(message.GetContent());\r\n            }\r\n        }\r\n<\/pre>\n<\/div>\n<p>Bir yandan 8 ile 10.  sat\u0131r aral\u0131\u011f\u0131nda \u00fcretilen agent&#8217;lardan bir <code>GroupChat<\/code> olu\u015fturuldu\u011funa dikkatinizi \u00e7ekerim. 17. sat\u0131rda ise bu <code>GroupChat<\/code>&#8216;e verilen mesaj e\u015fli\u011finde ileti\u015fim s\u00fcreci ba\u015flat\u0131lmakta ve runner agent&#8217;tan elde edilen netice console&#8217;a yazd\u0131r\u0131lmaktad\u0131r.\n<\/li>\n<li><strong>Ad\u0131m 6<\/strong> &#8211; <span style=\"color:green;font-size:12px;\"><i>Test<\/i><\/span><br \/>\nUygulamay\u0131 bu vaziyette derleyip \u00e7al\u0131\u015ft\u0131rd\u0131\u011f\u0131m\u0131zda a\u015fa\u011f\u0131daki gibi verilen mesaja kar\u015f\u0131n agent&#8217;lar aras\u0131 isti\u015fare s\u00fcreci cereyan edecek ve netice elde edilecektir.<a href=\"https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2025\/05\/AutoGen-Ile-Coklu-Yapay-Zeka-Ajan-Sistemi-Gelistirme-1.gif\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2025\/05\/AutoGen-Ile-Coklu-Yapay-Zeka-Ajan-Sistemi-Gelistirme-1.gif\" alt=\"AutoGen \u0130le \u00c7oklu Yapay Zek\u00e2 Ajan Sistemi Geli\u015ftirme\" width=\"800\" height=\"447\" class=\"aligncenter size-full wp-image-27889\" \/><\/a>\u0130\u015fte bu kadar \ud83d\ude42 G\u00f6r\u00fcld\u00fc\u011f\u00fc \u00fczere verdi\u011fimiz g\u00f6rev gere\u011fince admin nezaretinde coder bir kod \u00fcretmekte, reviewer bu kodu belirledi\u011fimiz ko\u015fullara g\u00f6re de\u011ferlendirmekte ve runner&#8217;da nihai olarak \u00e7al\u0131\u015ft\u0131r\u0131p netice elde edilmektedir.\n<\/li>\n<\/ul>\n<\/div>\n<\/div>\n<p><strong>GroupChat&#8217;i Kontrol Etmek \u0130\u00e7in Graph Kullan\u0131m\u0131<\/strong><br \/>\nBazen, <code>GroupChat<\/code>&#8216;te \u00e7\u00f6zmek istenen g\u00f6reve ba\u011fl\u0131 olarak s\u0131radaki agent&#8217;\u0131n nas\u0131l se\u00e7ilece\u011fi konusunda daha fazla kontrol eklemek isteyebiliriz. Misal olarak, yukar\u0131daki \u00f6rnekte admin&#8217;in do\u011frudan reviewer ile ve benzer \u015fekilde coder&#8217;\u0131n da runner ile ileti\u015fim kurmas\u0131 gerekmemektedir. Bunu a\u015fa\u011f\u0131daki diyagramda g\u00f6sterilen \u015fekilde daha da idealize edebiliriz.<a href=\"https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2025\/05\/AutoGen-Ile-Coklu-Yapay-Zeka-Ajan-Sistemi-Gelistirme-2.png\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2025\/05\/AutoGen-Ile-Coklu-Yapay-Zeka-Ajan-Sistemi-Gelistirme-2.png\" alt=\"AutoGen \u0130le \u00c7oklu Yapay Zek\u00e2 Ajan Sistemi Geli\u015ftirme\" width=\"717\" height=\"469\" class=\"aligncenter size-full wp-image-27890\" srcset=\"https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2025\/05\/AutoGen-Ile-Coklu-Yapay-Zeka-Ajan-Sistemi-Gelistirme-2.png 717w, https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2025\/05\/AutoGen-Ile-Coklu-Yapay-Zeka-Ajan-Sistemi-Gelistirme-2-300x196.png 300w\" sizes=\"auto, (max-width: 717px) 100vw, 717px\" \/><\/a>Evet, <code>GroupChat<\/code>&#8216;te belirli bir graph ak\u0131\u015f\u0131n\u0131 takip edilebilir k\u0131l\u0131p, agent&#8217;lara bir \u00f6n bilgi kazand\u0131rabilir ve konu\u015fmay\u0131 daha verimli ve sa\u011flam hale getirebiliriz. Bunun i\u00e7in yukar\u0131daki grafi\u011fi temsil edebilecek kodu a\u015fa\u011f\u0131da ele alabiliriz.<\/p>\n<div style=\"font-size:12px;\">\n<pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\r\n        public static async Task UseGraphToControlDynamicGroupChatAsync(string apiKey, string model, string endpoint)\r\n        {\r\n            var admin = await CreateAdminAgentAsync(apiKey, model, endpoint);\r\n            var coder = await CreateCoderAgentAsync(apiKey, model, endpoint);\r\n            var reviewer = await CreateReviewerAgentAsync(apiKey, model, endpoint);\r\n            var runner = await CreateRunnerAgentAsync(apiKey, model, endpoint);\r\n\r\n            var adminToCoderTransition = Transition.Create(admin, coder);\r\n\r\n            var coderToReviewerTransition = Transition.Create(coder, reviewer);\r\n\r\n            var reviewerToRunnerTransition = Transition.Create(\r\n                from: reviewer,\r\n                to: runner,\r\n                canTransitionAsync: async (from, to, messages) =&gt;\r\n                {\r\n                    var lastMessage = messages.LastOrDefault();\r\n                    if (lastMessage is not TextMessage textMessage)\r\n                        return false;\r\n\r\n                    return textMessage.Content.Contains(&quot;Ge\u00e7erli kod, runner kodu \u00e7al\u0131\u015ft\u0131rabilir.&quot;);\r\n                });\r\n\r\n            var reviewerToCoderTransition = Transition.Create(\r\n                from: reviewer,\r\n                to: coder,\r\n                canTransitionAsync: async (from, to, messages) =&gt;\r\n                {\r\n                    var lastMessage = messages.LastOrDefault();\r\n                    if (lastMessage is not TextMessage textMessage)\r\n                        return false;\r\n\r\n                    return textMessage.Content.Contains(&quot;Kod birden fazla kod blo\u011funa sahip. L\u00fctfen tek bir kod blo\u011fu g\u00f6nder.&quot;);\r\n                });\r\n\r\n            var runnerToCoderTransition = Transition.Create(\r\n                from: runner,\r\n                to: coder,\r\n                canTransitionAsync: async (from, to, messages) =&gt;\r\n                {\r\n                    var lastMessage = messages.LastOrDefault();\r\n                    if (lastMessage is not TextMessage textMessage)\r\n                        return false;\r\n\r\n                    return textMessage.Content.Contains(&quot;Ge\u00e7ersiz kod! Coder l\u00fctfen kodu yaz.&quot;);\r\n                });\r\n\r\n            var runnerToAdminTransition = Transition.Create(runner, admin);\r\n\r\n            var groupChat = new GroupChat(\r\n                admin: admin,\r\n                workflow: new Graph(\r\n                &#x5B;\r\n                    adminToCoderTransition,\r\n                    coderToReviewerTransition,\r\n                    reviewerToRunnerTransition,\r\n                    reviewerToCoderTransition,\r\n                    runnerToCoderTransition,\r\n                    runnerToAdminTransition\r\n                ]),\r\n                members:\r\n                &#x5B;\r\n                    admin,\r\n                    coder,\r\n                    runner,\r\n                    reviewer,\r\n                ]);\r\n\r\n            admin.SendIntroduction(&quot;Gelen g\u00f6revin \u00e7\u00f6z\u00fcm s\u00fcrecini takip edece\u011fim. \u0130lk \u00e7\u00f6z\u00fcld\u00fc\u011f\u00fc zaman da s\u00fcreci sonland\u0131raca\u011f\u0131m ve grupchat'i kapataca\u011f\u0131m.&quot;, groupChat);\r\n            coder.SendIntroduction(&quot;Gelen g\u00f6revi \u00e7\u00f6zmek i\u00e7in dotnet kodu yazaca\u011f\u0131m.&quot;, groupChat);\r\n            reviewer.SendIntroduction(&quot;Coder taraf\u0131ndan \u00fcretilen dotnet kodunu kurallar do\u011frultusunda g\u00f6zden ge\u00e7irece\u011fim. Onaylanmad\u0131\u011f\u0131m zaman coder tekrardan kod yazd\u0131raca\u011f\u0131m ve onaylayana kadar denetleyece\u011fim.&quot;, groupChat);\r\n            runner.SendIntroduction(&quot;Reviewer incelemeye tamamlad\u0131ktan sonra dotnet kodunu \u00e7al\u0131\u015ft\u0131raca\u011f\u0131m.&quot;, groupChat);\r\n\r\n\r\n            var result = groupChat.SendAsync(&#x5B;new TextMessage(Role.User, &quot;Bana fibonacci say\u0131 diziminde 35. haneyi verir misin?&quot;, from: admin.Name)], maxRound: 15);\r\n            await foreach (var message in result)\r\n            {\r\n                if (message.From == &quot;runner&quot;)\r\n                    Console.WriteLine(message.GetContent());\r\n                await Task.Delay(1000);\r\n            }\r\n        }\r\n<\/pre>\n<\/div>\n<p>Yukar\u0131daki \u00e7al\u0131\u015fmaya g\u00f6z atarsan\u0131z e\u011fer <code>Transition.Create()<\/code> metodu ile agent&#8217;lar aras\u0131ndaki ge\u00e7i\u015fe dair hiyerar\u015fi belirlenebilmekte ve dikkat ederseniz kimi durumlarda birden fazla k\u0131r\u0131l\u0131m\u0131n ge\u00e7erli olabilece\u011fi \u00e7ok ihtimalli s\u00fcre\u00e7lerde y\u00f6nlendirilebilecek \u015fekilde tan\u0131mlanabilmektedirler.<\/p>\n<p>Yukar\u0131da verilen diyagram\u0131n koda yans\u0131y\u0131\u015f\u0131n\u0131 okursak e\u011fer; 8. sat\u0131rdaki <em>adminToCoderTransition<\/em> transition ile admin&#8217;den coder&#8217;a, 10. sat\u0131rdaki <em>coderToReviewerTransition<\/em> transition ile de coder&#8217;dan reviewer&#8217;a ge\u00e7i\u015fi ifade etmektedir. Bu a\u015famada reviewer iki ihtimale sahiptir; ya kodu onaylayacak ve runner&#8217;a ge\u00e7i\u015f yap\u0131lacak ya da onaylamayacak ve coder&#8217;a tekrardan kod yazd\u0131r\u0131lacakt\u0131r. \u0130\u015fte bu durumda 12. sat\u0131rdaki <em>reviewerToRunnerTransition<\/em> transition&#8217;\u0131 kodun onayland\u0131\u011f\u0131 durumu temsil etmekte ve reviewer&#8217;dan runner&#8217;a ge\u00e7i\u015fi ifade etmektedir. 24. sat\u0131rdaki <em>reviewerToCoderTransition<\/em> transition&#8217;\u0131 ise olas\u0131 ko\u015fulsuzluklardan kaynakl\u0131 kodun tekrardan coder taraf\u0131ndan yaz\u0131lmas\u0131 gerekti\u011fi durumu ifade etmektedir. Benzer mant\u0131kla runner&#8217;da kodu \u00e7al\u0131\u015ft\u0131rd\u0131\u011f\u0131 taktirde ya ba\u015far\u0131l\u0131 olacak ve admin&#8217;e bildirecek ya da hata alacak ve coder&#8217;a geri d\u00f6necektir. Haliyle 36. sat\u0131rdaki <em>runnerToCoderTransition<\/em> transition&#8217;\u0131 ile koddaki olas\u0131 hataya istinaden runner&#8217;dan coder&#8217;a ge\u00e7i\u015f ifade etmekteyken, 48. sat\u0131rda ise <em>runnerToAdminTransition<\/em> transition&#8217;\u0131 ile  de s\u00fcrecin nihai olarak ba\u015far\u0131yla tamamlanaca\u011f\u0131n\u0131 temsil etmektedir.<\/p>\n<blockquote style=\"color:gray;\"><p><em>Graph, ko\u015fullu transition&#8217;lar\u0131\/ge\u00e7i\u015fleri desteklemektedir. Bir transition&#8217;\u0131 ko\u015fullu hale getirmek i\u00e7in yukar\u0131daki \u00f6rnekte oldu\u011fu gibi <em>canTransitionAsync<\/em> parametresine gerekli lambda fonksiyonu ge\u00e7ebilir ve transition&#8217;\u0131n yap\u0131l\u0131p yap\u0131lamayaca\u011f\u0131n\u0131 belirten bir ko\u015ful \u00e7al\u0131\u015fmas\u0131 ger\u00e7ekle\u015ftirebilirsiniz.<\/em><\/p><\/blockquote>\n<p>E\u011fer ki tan\u0131mlanm\u0131\u015f transtion&#8217;lardan birden fazla ge\u00e7erli olan s\u00f6z konusu olursa, bu taktirde <code>GroupChat<\/code>&#8216;in y\u00f6netici agent&#8217;\u0131 olan admin, konu\u015fman\u0131n ba\u011flam\u0131na g\u00f6re hangi duruma ge\u00e7ilece\u011fine karar verecektir.<\/p>\n<p>Ayr\u0131ca burada teknik olarak dikkat edilmesi gereken bir detay daha vard\u0131r ki; o da, graph&#8217;in kullan\u0131ld\u0131\u011f\u0131 \u00e7al\u0131\u015fmalarda admin&#8217;in 63. sat\u0131rda oldu\u011fu gibi members&#8217;lara eklenmesi ve <code>GroupChat<\/code>&#8216;i ba\u015flatacak olan <code>SendAsync<\/code> metoduna verilen <code>TextMessage<\/code> nesnesinde de &#8216;from&#8217; olarak belirtilmesi gerekmektedir.<a href=\"https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2025\/05\/AutoGen-Ile-Coklu-Yapay-Zeka-Ajan-Sistemi-Gelistirme-3.png\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2025\/05\/AutoGen-Ile-Coklu-Yapay-Zeka-Ajan-Sistemi-Gelistirme-3.png\" alt=\"AutoGen \u0130le \u00c7oklu Yapay Zek\u00e2 Ajan Sistemi Geli\u015ftirme\" width=\"1894\" height=\"703\" class=\"aligncenter size-full wp-image-27892\" srcset=\"https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2025\/05\/AutoGen-Ile-Coklu-Yapay-Zeka-Ajan-Sistemi-Gelistirme-3.png 1894w, https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2025\/05\/AutoGen-Ile-Coklu-Yapay-Zeka-Ajan-Sistemi-Gelistirme-3-300x111.png 300w, https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2025\/05\/AutoGen-Ile-Coklu-Yapay-Zeka-Ajan-Sistemi-Gelistirme-3-1024x380.png 1024w, https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2025\/05\/AutoGen-Ile-Coklu-Yapay-Zeka-Ajan-Sistemi-Gelistirme-3-768x285.png 768w, https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2025\/05\/AutoGen-Ile-Coklu-Yapay-Zeka-Ajan-Sistemi-Gelistirme-3-1536x570.png 1536w\" sizes=\"auto, (max-width: 1894px) 100vw, 1894px\" \/><\/a><\/p>\n<p>Nihai olarak;<br \/>\nBu i\u00e7eri\u011fimizde AutoGen&#8217;i pratiksel olarak geni\u015f a\u00e7\u0131dan deneyimlemi\u015f ve temel agent yap\u0131land\u0131rmalar\u0131ndan tutun, agent&#8217;lar\u0131n aralar\u0131ndaki haberle\u015fme s\u00fcre\u00e7lerindeki davran\u0131\u015flar\u0131na kadar detayl\u0131ca incelemi\u015f bulunuyoruz. Bir yandan da agent&#8217;lar aras\u0131ndaki ileti\u015fim an\u0131nda kullan\u0131labilecek streaming, middleware, function calling vs. gibi \u00f6zelliklere temas etmi\u015f ve g\u00fczel bir \u00f6rnek senaryo \u00fczerinden neyin ne oldu\u011funu ve nerelerde ne \u015fekilde kullan\u0131labilece\u011fini tecr\u00fcbe etmi\u015f bulunuyoruz. \u00d6zellikle function contract ve wrapper yap\u0131lanmalar\u0131n\u0131 ve LLM ile herhangi bir function&#8217;\u0131n nas\u0131l call edilebilece\u011fini detaylar\u0131yla izah etmi\u015f ve son olarak da tasarlanm\u0131\u015f bir GroupChat&#8217;te Graph ile ileti\u015fim s\u00fcrecini daha detayl\u0131 bir \u015fekilde nas\u0131l yap\u0131land\u0131rabilece\u011fimizi incelemi\u015f bulunuyoruz.<\/p>\n<p>Evet, bu i\u00e7eri\u011fimizde her ne kadar <a href=\"https:\/\/www.gencayyildiz.com\/blog\/semantic-kernel-nedir-deepseek-r1-esliginde-net-acisindan-derinlemesine-degerlendirelim\/\" target=\"_blank\">Semantic Kernel<\/a> ile AutoGen&#8217;i birlikte kullanmaya de\u011finmemi\u015f olsak da sonraki yaz\u0131lar\u0131mda bu iki teknolojiyi harmanlamay\u0131 ve ayr\u0131ca <a href=\"https:\/\/www.gencayyildiz.com\/blog\/model-context-protocol-mcp-nedir-derinlemesine-degerlendirelim\/\" target=\"_blank\">MCP (Model Context Protocol)<\/a>&#8216;yi de i\u015fin i\u00e7ine katarak s\u00fcreci daha da yetenekli hale getirmeyi tasarlam\u0131yor de\u011filim \ud83d\ude42 O halde takip kal\u0131n \ud83d\ude09<\/p>\n<p>\u0130lgilenenlerin faydalanmas\u0131 dile\u011fiyle&#8230;<br \/>\nSonraki yaz\u0131lar\u0131mda g\u00f6r\u00fc\u015fmek \u00fczere&#8230;<br \/>\n\u0130yi \u00e7al\u0131\u015fmalar dilerim&#8230;<\/p>\n<p>Not : \u00d6rnek \u00e7al\u0131\u015fmaya a\u015fa\u011f\u0131daki GitHub adresinden eri\u015febilirsiniz.<br \/>\n<a href=\"https:\/\/github.com\/gncyyldz\/AutoGen_Example\" target=\"_blank\">https:\/\/github.com\/gncyyldz\/AutoGen_Example<\/a><\/p>\n<!-- AddThis Advanced Settings generic via filter on the_content --><!-- AddThis Share Buttons generic via filter on the_content -->","protected":false},"excerpt":{"rendered":"<p>Merhaba, Bir \u00f6nceki AutoGen Nedir? Derinlemesine Teorik \u0130nceleyelim&#8230; ba\u015fl\u0131kl\u0131 i\u00e7eri\u011fimizde AutoGen&#8217;i teorik boyutta masaya yat\u0131rm\u0131\u015f ve tam teferruatl\u0131 bir incelemede bulunmu\u015ftuk. Bu i\u00e7eri\u011fimizde ise edindi\u011fimiz teorik zemin \u00fczerine art\u0131k pratik bir in\u015fada bulunacak ve&#46;&#46;&#46;<!-- AddThis Advanced Settings generic via filter on get_the_excerpt --><!-- AddThis Share Buttons generic via filter on get_the_excerpt --><\/p>\n","protected":false},"author":1,"featured_media":27863,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[5206,5222,5220],"tags":[5346,5376,5381,5382,5385,5377,5351,5383,5379,5386,5362,5378,5359,5380,5384,5350],"class_list":["post-27866","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-net","category-llm","category-yapay-zeka-ai","tag-autogen","tag-autogen-for-net","tag-autogen-dotnetinteractive","tag-autogen-sourcegenerator","tag-chattool","tag-coklu-yapay-zeka","tag-conversableagent","tag-functiondefinition","tag-generatereplyasync","tag-gettoolcalls","tag-groupchat","tag-multi-agent-system","tag-openaichatagent","tag-roundrobingroupchat","tag-tochattool","tag-userproxyagent"],"amp_enabled":true,"_links":{"self":[{"href":"https:\/\/www.gencayyildiz.com\/blog\/wp-json\/wp\/v2\/posts\/27866","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.gencayyildiz.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.gencayyildiz.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.gencayyildiz.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.gencayyildiz.com\/blog\/wp-json\/wp\/v2\/comments?post=27866"}],"version-history":[{"count":19,"href":"https:\/\/www.gencayyildiz.com\/blog\/wp-json\/wp\/v2\/posts\/27866\/revisions"}],"predecessor-version":[{"id":27893,"href":"https:\/\/www.gencayyildiz.com\/blog\/wp-json\/wp\/v2\/posts\/27866\/revisions\/27893"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.gencayyildiz.com\/blog\/wp-json\/wp\/v2\/media\/27863"}],"wp:attachment":[{"href":"https:\/\/www.gencayyildiz.com\/blog\/wp-json\/wp\/v2\/media?parent=27866"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.gencayyildiz.com\/blog\/wp-json\/wp\/v2\/categories?post=27866"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.gencayyildiz.com\/blog\/wp-json\/wp\/v2\/tags?post=27866"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}