Какво са Tools?
- Разбери какво са Agents
- Научи какво са LLMs и системата от Messages
- Изучи Tools и Actions
- Научи Agent workflow
- Напиши първия си Agent
- Unit Quiz
Един ключов аспект на AI Agents е способността им да предприемат действия (actions). Както видяхме, това става чрез Tools.
В тази секция ще научиш какво е Tool, как моделът го използва и как му го описваме чрез system message. Накрая ще напишеш един tool на C# и ще го изпълниш на своя компютър, без да ти трябва модел.
Какво са AI Tools?
Секция „Какво са AI Tools?“Tool е функция, предоставена на LLM. Тя трябва да има ясна цел. За един C# програмист това е обикновен метод.
Ето някои често използвани tools:
| Tool | Описание |
|---|---|
| Web Search | Извлича актуална информация от интернет. |
| Image Generation | Създава изображения по текстово описание. |
| Retrieval | Извлича информация от външен източник. |
| API Interface | Работи с външен API (GitHub, YouTube, Spotify и т.н.). |
Това са само примери. Можеш да създадеш tool за всякаква задача.
Добрият tool допълва силата на LLM, тоест прави нещо, което моделът сам не може или не прави добре:
- Точни изчисления. Моделът предсказва текст, а не смята. Един calculator tool дава верен резултат всеки път.
- Актуални данни. Моделът знае само това, което е било в данните му за обучение. Ако го попиташ за времето днес и той няма tool за това, вероятно ще си измисли прогноза. Това се нарича халюцинация.

Как работят tools?
Секция „Как работят tools?“LLM може само да чете и да пише текст. Той няма как сам да извика метод. Затова работата се разделя между двама: моделът казва какво иска, а Agent-ът го изпълнява. Тук Agent-ът е програмата около модела.
Да кажем, че сме дали на модела tool за проверка на времето и потребителят пита какво е времето в Париж:
- Моделът разпознава, че му трябва този tool. Вместо отговор написва текст, който описва извикването, например
GetWeather("Paris"). - Agent-ът прочита този текст, разбира, че е извикване на tool, и изпълнява истинския метод
GetWeather. - Agent-ът добавя резултата към разговора като нов message и подава разговора отново на модела.
- Моделът прочита резултата и написва отговора за потребителя.
Потребителят вижда само последната стъпка. За него изглежда, че моделът сам е проверил времето, но цялата работа е свършил Agent-ът.
Как даваме tools на LLM?
Секция „Как даваме tools на LLM?“Моделът чете само текст. Затова „да му дадем tool“ означава нещо просто: описваме tool-а с текст и слагаме описанието в system prompt-а.
You are an AI assistant designed to help users efficiently and accurately.Your primary goal is to provide helpful, precise, and clear responses.
You have access to the following tools:{tools_description}На мястото на {tools_description} застават описанията на нашите tools.
Какво трябва да знае моделът за един tool?
Секция „Какво трябва да знае моделът за един tool?“Когато задържиш мишката върху метод във Visual Studio, IntelliSense ти показва името му, параметрите с техните типове, типа на резултата и кратко описание. Тялото на метода не се вижда, но и не ти трябва, за да го извикаш правилно.
Моделът има нужда от същите четири неща:
- Име на tool-а.
- Описание на това, което прави.
- Входове: имената и типовете на аргументите.
- Изход: типът на резултата.
Да вземем за пример прост calculator tool, който умножава две цели числа:
int Calculator(int a, int b) => a * b;Записани като текст, четирите неща изглеждат така:
Tool Name: Calculator, Description: Multiply two integers., Arguments: a: int, b: int, Outputs: intВажно: Този текст е всичко, което моделът знае за tool-а. Самия C# код той не вижда.
Точно този формат не е задължителен, може да бъде и JSON. Важното е описанието да е точно и да е в един и същ формат за всички tools.
Описанието може да се напише на ръка, но това е крехко. Достатъчно е да преименуваш параметър и да забравиш да поправиш текста, и моделът започва да извиква tool-а грешно, без компилаторът да те предупреди. Затова е по-добре програмата сама да състави описанието от кода. Това ще направим сега.
Tools в C#
Секция „Tools в C#“Ще напишем tool-а Calculator, ще накараме програмата сама да състави описанието му и ще го вмъкнем в system prompt-а. Програмата няма да извиква модел.
Трябва ти единствено .NET SDK от Unit 0. Не ти трябват Ollama, модел или NuGet пакети.
1. Създай проекта
Секция „1. Създай проекта“Отвори терминал и изпълни:
dotnet new console -n FirstToolcd FirstToolПървата команда създава папка FirstTool с ново конзолно приложение, а втората влиза в нея. Отвори папката в редактора си. В следващите стъпки ще работим с три малки файла.
2. Напиши tool-а
Секция „2. Напиши tool-а“Създай нов файл MyTools.cs:
using System.ComponentModel;
public static class MyTools{ [Description("Multiply two integers.")] public static int Calculator(int a, int b) => a * b;}Това е методът от по-горе с една добавка: атрибутът [Description]. Името, параметрите и типът на резултата вече са записани в самия метод. Липсваше само описанието с думи и атрибутът го добавя.
Защо атрибут, а не /// коментар? Коментарите изчезват при компилация. Атрибутите остават в програмата и тя може да ги прочете, докато работи.
3. Напиши класа Tool
Секция „3. Напиши класа Tool“Създай втори файл, Tool.cs. Той събира на едно място всичко за един tool:
using System.ComponentModel;using System.Reflection;
public record Tool( string Name, string Description, Delegate Function, string Arguments, string Outputs){ public static Tool FromMethod(Delegate function) { MethodInfo method = function.Method;
string name = method.Name; string description = method.GetCustomAttribute<DescriptionAttribute>()?.Description ?? ""; string arguments = string.Join(", ", method.GetParameters() .Select(p => $"{p.Name}: {TypeName(p.ParameterType)}")); string outputs = TypeName(method.ReturnType);
return new Tool(name, description, function, arguments, outputs); }
public override string ToString() => $"Tool Name: {Name}, Description: {Description}, " + $"Arguments: {Arguments}, Outputs: {Outputs}";
public object? Invoke(params object?[] args) => Function.DynamicInvoke(args);
private static string TypeName(Type type) => type.Name switch { "Int32" => "int", "String" => "string", "Boolean" => "bool", "Double" => "double", var other => other, };}Първите редове изброяват от какво се състои един tool: четирите неща от описанието и самият метод (Function). Под тях има три метода:
FromMethodсъздаваToolот подаден метод. Всичко нужно той чете от самия метод, през обектаMethodInfo, който го описва.ToStringподрежда описанието в един ред. Това е текстът за модела.Invokeизпълнява самия метод. Това ще прави Agent-ът, когато моделът поиска tool-а.
Ето откъде FromMethod взима четирите неща:
| Какво ни трябва | Откъде го взима | Резултат за Calculator |
|---|---|---|
| Име | method.Name |
Calculator |
| Описание | атрибутът [Description] |
Multiply two integers. |
| Входове | method.GetParameters() |
a: int, b: int |
| Изход | method.ReturnType |
int |
Когато една програма чете информация за собствения си код, докато работи, това се нарича reflection. Помощният метод TypeName само заменя .NET имената Int32 и String с познатите int и string.
4. Използвай tool-а
Секция „4. Използвай tool-а“Отвори Program.cs, изтрий съдържанието му и сложи следното:
Tool calculator = Tool.FromMethod(MyTools.Calculator);
Console.WriteLine(calculator);Console.WriteLine(calculator.Invoke(6, 7));
string systemPrompt = $""" You are an AI assistant designed to help users efficiently and accurately. Your primary goal is to provide helpful, precise, and clear responses.
You have access to the following tools: {calculator} """;
Console.WriteLine();Console.WriteLine(systemPrompt);
// The example ends here.// The next step would be to send this system prompt to a model.Програмата прави три неща: създава Tool от метода Calculator, отпечатва описанието му и резултата от едно извикване, а накрая вмъква описанието в system prompt-а.
Коментарът в края отбелязва къде спираме. Следващата стъпка би била да изпратим system prompt-а на модел, а модел все още нямаме.
5. Стартирай програмата
Секция „5. Стартирай програмата“В терминала, в папката FirstTool, изпълни:
dotnet runизход:
Tool Name: Calculator, Description: Multiply two integers., Arguments: a: int, b: int, Outputs: int42
You are an AI assistant designed to help users efficiently and accurately.Your primary goal is to provide helpful, precise, and clear responses.
You have access to the following tools:Tool Name: Calculator, Description: Multiply two integers., Arguments: a: int, b: int, Outputs: intЕто как програмата стигна до този изход:
Tool.FromMethod(MyTools.Calculator)получи самия метод, без да го изпълнява, и прочете от него името, описанието, параметрите и типа на резултата.Console.WriteLine(calculator)извикаToStringи отпечата първия ред. Това е същото описание, което по-горе написахме на ръка, но този път идва от кода.calculator.Invoke(6, 7)изпълни истинския методCalculatorи върна42. В един Agent това става, когато моделът поиска tool-а. Тук го извикахме сами, за да видиш, че работи.{calculator}вsystemPromptотново извикаToStringи постави описанието там, където в шаблона по-горе стоеше{tools_description}.
6. Експериментирай
Секция „6. Експериментирай“Опитай тези две промени и след всяка изпълни dotnet run.
Преименувай параметрите. В MyTools.cs смени a и b с x и y:
public static int Calculator(int x, int y) => x * y;В изхода вече пише Arguments: x: int, y: int, и то на двете места. Не си пипал нито един текст: описанието идва от кода и няма как да се размине с него.
Добави втори tool. Добави още един метод в класа MyTools:
[Description("Get the current weather in a given location.")]public static string GetWeather(string location) => $"the weather in {location} is sunny with low temperatures.";В Program.cs създай Tool и за него, под първия ред:
Tool weather = Tool.FromMethod(MyTools.GetWeather);и го добави в system prompt-а на нов ред под {calculator}:
You have access to the following tools: {calculator} {weather} """;В края на изхода ще се появи втори tool, описан в същия формат:
Tool Name: GetWeather, Description: Get the current weather in a given location., Arguments: location: string, Outputs: stringТова описание ще срещнеш отново в Dummy Agent Library, където ще го изпратим на истински модел.
Как е в истинско приложение
Секция „Как е в истинско приложение“Класът Tool е учебен пример, но реалните библиотеки работят по същия начин. В .NET това прави AIFunctionFactory от библиотеката Microsoft.Extensions.AI. С AIFunctionFactory.Create(MyTools.Calculator) и той чете името на метода, атрибута [Description] и параметрите. Разликата е, че описва входовете във формат JSON Schema, който съвременните модели разбират.
Ще го използваме, когато изграждаме първия си Agent. Как един Agent извиква tool-а, ще научим в секцията Actions.
Model Context Protocol (MCP)
Секция „Model Context Protocol (MCP)“Нашият клас Tool работи само в нашата програма. Всяка библиотека за Agents има свой подобен клас, така че един и същ tool трябва да се описва наново за всяка от тях.
Model Context Protocol (MCP) е отворен протокол, който стандартизира начина, по който приложенията предоставят tools на LLMs. Tool-ът се реализира веднъж, в отделна програма, наречена MCP server, и всеки framework, който поддържа MCP, може да го използва. Вече има и много готови MCP сървъри, към които твоят Agent може директно да се включи.
В .NET има официален MCP C# SDK (NuGet пакетът ModelContextProtocol), който работи директно с Microsoft.Extensions.AI. Ако искаш да навлезеш по-дълбоко в MCP, разгледай безплатния MCP Course на Hugging Face.
Обобщение
Секция „Обобщение“- Tool е функция, която дава на LLM възможности отвъд генерирането на текст: точни изчисления, актуални данни, действия във външни системи.
- Моделът не изпълнява tools. Той само написва кой tool иска и с какви аргументи, а Agent-ът го изпълнява и му връща резултата.
- За да използва един tool, моделът трябва да знае името, описанието, входовете и изхода му. Това описание стои в system prompt-а.
- В C# описанието се взима от самия метод с reflection и атрибута
[Description], за да не се разминава с кода. - MCP позволява един tool да се реализира веднъж и да се използва от различни frameworks.
Сега можем да преминем към работния процес на Agent, където ще видиш как един Agent наблюдава, мисли и действа. Той събира всичко, което разгледахме досега, и подготвя сцената за създаването на твой собствен AI Agent.
Но първо е време за още един кратък quiz!