Création d’un agent

Important

Depuis janvier 2026, le projet AI Shell n’est plus activement maintenu. Ce projet doit être considéré comme archivé d’un point de vue ingénieur.

Un agent est une bibliothèque de code qui interface avec AI Shell pour communiquer avec un modèle de langage volumineux spécifique ou un autre fournisseur d’assistance. Les utilisateurs discutent avec les agents à l’aide du langage naturel pour obtenir la sortie ou l’assistance souhaitées. Les agents sont implémentés en tant que classes C# qui implémentent l’interface ILLMAgent à partir du package AIShell.Abstraction.

Pour plus d’informations sur la couche AIShell.Abstraction et AIShell.Kernel, consultez la documentation 'architecture AI Shell.

Cet article est un guide étape par étape pour la création d’un agent pour le modèle de langage Ollama . Le but de cet article est de fournir un exemple simple de la création d’un agent. Il y a une implémentation plus robuste de l’agent Ollama dans le AIShell.Ollama.Agent dossier du dépôt.

Conditions préalables

  • KIT SDK .NET 8 ou version ultérieure
  • PowerShell 7.4.6 ou version ultérieure

Étapes de création d’un agent

Pour cet exemple, nous créons un agent pour communiquer avec le modèle phi3 de langage à l’aide d’Ollama. Ollama est un outil CLI pour la gestion et l’utilisation de LLM/SLM construits localement.

Étape 1 : Créer un projet

La première étape consiste à créer un nouveau projet classlib .

  1. Créer un dossier nommé OllamaAgent

  2. Exécutez la commande suivante pour créer un projet :

    dotnet new classlib
    

Étape 2 : Ajouter les packages nécessaires

Dans le projet nouvellement créé, vous devez installer le package AIShell.Abstraction à partir de la galerie NuGet. Installez le package NuGet à l’aide de la commande suivante :

dotnet add package AIShell.Abstraction --version 1.0.0-preview.2

Cette commande ajoute le package à votre fichier .csproj. Votre fichier .csproj doit contenir le code XML suivant :

<Project Sdk="Microsoft.NET.Sdk">

  <PropertyGroup>
    <TargetFramework>net8.0</TargetFramework>
    <ImplicitUsings>enable</ImplicitUsings>
    <SuppressNETCoreSdkPreviewMessage>true</SuppressNETCoreSdkPreviewMessage>
  </PropertyGroup>

  <ItemGroup>
    <PackageReference Include="AIShell.Abstraction" Version="1.0.0-preview.2" />
  </ItemGroup>
</Project>

Important

Veillez à vérifier que vous êtes sur la dernière version de la galerie NuGet.

Étape 3 : Implémenter la classe d’agent

Pour implémenter l’interface ILLMAgent, modifiez le fichier Class1.cs.

  1. Renommez le fichier en OllamaAgent.cs
  2. Renommer la classe en OllamaAgent
  3. Ajoutez les espaces de noms .NET utilisés par le code dans l’implémentation
using System.Diagnostics;
using System.Text;
using System.Text.Json;
using AIShell.Abstraction;

namespace AIShell.Ollama.Agent;

public sealed class OllamaAgent : ILLMAgent
{

}

Étape 4 : Ajouter les membres et méthodes de classe nécessaires

Ensuite, implémentez les variables et méthodes nécessaires de la classe d’agent. Les commentaires fournissent des descriptions des membres de la classe OllamaAgent. Le _chatService membre est une instance de la classe OllamaChatService , que vous implémentez dans une étape ultérieure.

public sealed class OllamaAgent : ILLMAgent
{
    /// <summary>
    /// The name of the agent
    /// </summary>
    public string Name => "ollama";

    /// <summary>
    /// The description of the agent to be shown at start up
    /// </summary>
    public string Description => "This is an AI assistant that uses the Ollama CLI tool. Be sure to follow all prerequisites in https://aka.ms/ollama/readme";

    /// <summary>
    /// This is the company added to `/like` and `/dislike` verbiage for who the telemetry helps.
    /// </summary>
    public string Company => "Microsoft";

    /// <summary>
    /// These are samples that are shown at start up for good questions to ask the agent
    /// </summary>
    public List<string> SampleQueries => [
        "How do I list files in a given directory?"
    ];

    /// <summary>
    /// These are any optional legal/additional information links you want to provide at start up
    /// </summary>
    public Dictionary<string, string> LegalLinks { private set; get; }

    /// <summary>
    /// This is the chat service to call the API from
    /// </summary>
    private OllamaChatService _chatService;

    /// <summary>
    /// A string builder to render the text at the end
    /// </summary>
    private StringBuilder _text;

    /// <summary>
    /// Dispose method to clean up the unmanaged resource of the chatService
    /// </summary>
    public void Dispose()
    {
        _chatService?.Dispose();
    }

    /// <summary>
    /// Initializing function for the class when the shell registers an agent
    /// </summary>
    /// <param name="config">Agent configuration for any configuration file and other settings</param>
    public void Initialize(AgentConfig config)
    {
        _text = new StringBuilder();
        _chatService = new OllamaChatService();

        LegalLinks = new(StringComparer.OrdinalIgnoreCase)
        {
            ["Ollama Docs"] = "https://github.com/ollama/ollama",
            ["Prerequisites"] = "https://aka.ms/ollama/readme"
        };

    }

    /// <summary>
    /// Get commands that an agent can register to the shell when being loaded
    /// </summary>
    public IEnumerable<CommandBase> GetCommands() => null;

    /// <summary>
    /// Gets the path to the setting file of the agent.
    /// </summary>
    public string SettingFile { private set; get; } = null;

    /// <summary>
    /// Refresh the current chat by starting a new chat session.
    /// An agent can reset chat states in this method.
    /// </summary>
    public void RefreshChat() {}

    /// <summary>
    /// Gets a value indicating whether the agent accepts a specific user action feedback.
    /// </summary>
    /// <param name="action">The user action.</param>
    public bool CanAcceptFeedback(UserAction action) => false;

    /// <summary>
    /// A user action was taken against the last response from this agent.
    /// </summary>
    /// <param name="action">Type of the action.</param>
    /// <param name="actionPayload"></param>
    public void OnUserAction(UserActionPayload actionPayload) {}

    /// <summary>
    /// Main chat function that takes
    /// </summary>
    /// <param name="input">The user input from the chat experience</param>
    /// <param name="shell">The shell that provides host functionality</param>
    /// <returns>Task Boolean that indicates whether the query was served by the agent.</returns>
    public async Task<bool> Chat(string input, IShell shell)
    {

    }
}

Pour l’implémentation initiale, l’agent renvoie « Hello World ! », prouvant que vous avez créé les interfaces correctes. Vous devez également ajouter un try-catch bloc pour intercepter et gérer les exceptions lorsque l’utilisateur tente d’annuler l’opération.

Ajoutez le code suivant à votre méthode Chat.

public async Task<bool> Chat(string input, IShell shell)
{
    // Get the shell host
    IHost host = shell.Host;

    // get the cancellation token
    CancellationToken token = shell.CancellationToken;

    try
    {
       host.RenderFullResponse("Hello World!");
    }
    catch (OperationCanceledException e)
    {
        _text.AppendLine(e.ToString());

        host.RenderFullResponse(_text.ToString());

        return false;
    }

    return true;
}

Étape 5 : Ajouter une vérification Ollama

Ensuite, vous devez vous assurer que Ollama est en cours d’exécution.

public async Task<bool> Chat(string input, IShell shell)
{
    // Get the shell host
    IHost host = shell.Host;

    // get the cancellation token
    CancellationToken token = shell.CancellationToken;

    if (Process.GetProcessesByName("ollama").Length is 0)
    {
        host.RenderFullResponse("Please be sure that Ollama is installed and the server is running. Ensure that you have met all the prerequisites in the README for this agent.");
        return false;
    }

    // Calls to the API will go here

    return true;
}

Étape 6 : Créer des structures de données pour échanger des données avec le service chat

Avant de pouvoir utiliser l’API Ollama, vous devez créer des classes qui envoient des entrées et reçoivent des réponses de l’API Ollama. L’exemple Ollama suivant montre le format de l’entrée et la réponse de l’agent.

Cet exemple appelle l’API Ollama avec la diffusion en continu désactivée. Ollama génère une réponse unique et fixe. À l’avenir, vous pouvez ajouter des fonctionnalités de diffusion en continu afin que les réponses puissent être rendues en temps réel, car l’agent les reçoit.

Pour définir les structures de données, créez un fichier dans le même dossier nommé OllamaSchema.cs. Copiez le code suivant dans le fichier.

namespace AIShell.Ollama.Agent;

// Query class for the data to send to the endpoint
internal class Query
{
    public string prompt { get; set; }
    public string model { get; set; }

    public bool stream { get; set; }
}

// Response data schema
internal class ResponseData
{
    public string model { get; set; }
    public string created_at { get; set; }
    public string response { get; set; }
    public bool done { get; set; }
    public string done_reason { get; set; }
    public int[] context { get; set; }
    public double total_duration { get; set; }
    public long load_duration { get; set; }
    public int prompt_eval_count { get; set; }
    public int prompt_eval_duration { get; set; }
    public int eval_count { get; set; }
    public long eval_duration { get; set; }
}

internal class OllamaResponse
{
    public int Status { get; set; }
    public string Error { get; set; }
    public string Api_version { get; set; }
    public ResponseData Data { get; set; }
}

Vous disposez maintenant des éléments nécessaires pour construire un service de conversation qui utilise l’API Ollama. Une classe de service de conversation distincte n’est pas nécessaire, mais il est utile d’extraire les appels à l’API.

Créez un fichier appelé OllamaChatService.cs dans le même dossier que l’agent. Copiez l’exemple de code dans le fichier.

Conseil

Cet exemple utilise un point de terminaison codé en dur et un modèle de langage pour l’API Ollama. À l’avenir, vous pouvez définir des paramètres configurables dans un fichier de configuration d’agent.

using System.Net.Http.Headers;
using System.Text;
using System.Text.Json;

using AIShell.Abstraction;

namespace AIShell.Ollama.Agent;

internal class OllamaChatService : IDisposable
{
    /// <summary>
    /// Ollama endpoint to call to generate a response
    /// </summary>
    internal const string Endpoint = "http://localhost:11434/api/generate";

    /// <summary>
    /// Http client
    /// </summary>
    private readonly HttpClient _client;

    /// <summary>
    /// Initialization method to initialize the http client
    /// </summary>

    internal OllamaChatService()
    {
        _client = new HttpClient();
    }

    /// <summary>
    /// Dispose of the http client
    /// </summary>
    public void Dispose()
    {
        _client.Dispose();
    }

    /// <summary>
    /// Preparing chat with data to be sent
    /// </summary>
    /// <param name="input">The user input from the chat experience</param>
    /// <returns>The HTTP request message</returns>
    private HttpRequestMessage PrepareForChat(string input)
    {
        // Main data to send to the endpoint
        var requestData = new Query
        {
            model = "phi3",
            prompt = input,
            stream = false
        };

        var json = JsonSerializer.Serialize(requestData);

        var data = new StringContent(json, Encoding.UTF8, "application/json");
        var request = new HttpRequestMessage(HttpMethod.Post, Endpoint) { Content = data };

        return request;
    }

    /// <summary>
    /// Getting the chat response async
    /// </summary>
    /// <param name="context">Interface for the status context used when displaying a spinner.</param>
    /// <param name="input">The user input from the chat experience</param>
    /// <param name="cancellationToken">The cancellation token to exit out of request</param>
    /// <returns>Response data from the API call</returns>
    internal async Task<ResponseData> GetChatResponseAsync(IStatusContext context, string input, CancellationToken cancellationToken)
    {
        try
        {
            HttpRequestMessage request = PrepareForChat(input);
            HttpResponseMessage response = await _client.SendAsync(request, cancellationToken);
            response.EnsureSuccessStatusCode();

            context?.Status("Receiving Payload ...");
            Console.Write(response.Content);
            var content = await response.Content.ReadAsStreamAsync(cancellationToken);
            return JsonSerializer.Deserialize<ResponseData>(content);
        }
        catch (OperationCanceledException)
        {
            // Operation was cancelled by user.
        }

        return null;
    }
}

Étape 7 : Appeler le service de conversation

Ensuite, vous devez appeler le service de conversation dans la classe d’agent principale. Modifiez la méthode Chat() pour appeler le service de conversation et afficher la réponse à l’utilisateur. L’exemple suivant montre la méthode Chat() terminée.

public async Task<bool> Chat(string input, IShell shell)
{
    // Get the shell host
    IHost host = shell.Host;

    // get the cancellation token
    CancellationToken token = shell.CancellationToken;

    if (Process.GetProcessesByName("ollama").Length is 0)
    {
        host.RenderFullResponse("Please be sure that Ollama is installed and the server is running. Ensure that you have met all the prerequisites in the README for this agent.");
        return false;
    }

    ResponseData ollamaResponse = await host.RunWithSpinnerAsync(
        status: "Thinking ...",
        func: async context => await _chatService.GetChatResponseAsync(context, input, token)
    ).ConfigureAwait(false);

    if (ollamaResponse is not null)
    {
        // render the content
        host.RenderFullResponse(ollamaResponse.response);
    }

    return true;
}

Le code de l’agent est terminé.

Étape 8 : Générer et tester l’agent

Ensuite, vous devez générer et tester que le code fonctionne comme prévu. Exécutez la commande suivante :

dotnet build

Cette commande génère tous les packages nécessaires dans le dossier \bin\Debug\net8.0 du projet.

Pour que aish charger l’agent, vous devez copier les fichiers .dll dans un dossier du dossier Agents. Le nom du dossier doit être identique au nom de l’agent.

Vous pouvez installer des agents à l’un des deux emplacements suivants :

  • Dans le dossier Agents sous l’emplacement où vous avez installé aish.exe. Le [script d’installation][08] pour AI Shell s’installe dans %LOCALAPPDATA%\Programs\AIShell. Créez le dossier %LOCALAPPDATA%\Programs\AIShell\Agents\OllamaAgent.
  • En guise d’alternative, vous installez des agents dans %USERPROFILE%\.aish\Agents. Créez le dossier %USERPROFILE%\.aish\Agents\OllamaAgent.

Copiez les fichiers .dll dans le dossier de l’agent que vous avez créé. Vous devez voir l’agent lorsque vous démarrez aish.

AI Shell
v1.0.0-preview.2

Please select an agent to use:

    azure
   >ollama
    openai-gpt

Comment puis-je partager mon propre agent ?

Il n’existe aucun moyen de partager vos agents dans un référentiel centralisé. Nous vous suggérons de faire passer ce référentiel pour le développement de votre propre agent. Vous pouvez partager un lien de votre fourche dans la section Agent Sharing de l’onglet Discussions de ce référentiel. Pour utiliser un agent, placez les fichiers de l’agent dll dans le agents dossier du répertoire de base de aish.exe. AI Shell charge automatiquement les agents à partir de ce dossier.