Quick Start¶
You need two things to run an agent, and one optional thing:
- An
ILlmClient— the connection to your AI provider. - DI registration — connect everything to the runtime.
- (Optional) At least one
ITool— something the agent can do. Tools are only needed for runs where the model may call tools. For an explicit tool-free run, passAllowedToolNames: []— the model then answers directly with text.
1. Implement ILlmClient — talk to your AI provider¶
This class sends messages to your AI and returns the answer. Write it once; the runtime never talks to the provider itself.
using AiCleverness.Abstractions;
using AiCleverness.Models;
public sealed class MyLlmClient : ILlmClient
{
public async Task<LlmResponse> CompleteAsync(
IReadOnlyList<LlmMessage> messages,
IReadOnlyList<ToolDefinition>? tools,
LlmCompletionOptions? options,
CancellationToken ct)
{
// Call OpenAI, Anthropic, Ollama, or your local model
var content = await CallMyAiAsync(messages, ct);
return new LlmResponse(content);
}
}
2. Implement ITool — something the agent can do (optional)¶
Skip this step if your run needs no tools. A tool has a name, a description, and a parameter schema. The model reads these three things and decides when to call the tool.
public sealed class WeatherTool : ITool
{
public string Name => "get_weather";
public string Description => "Get current weather for a city";
public ToolDefinition Definition => new(Name, Description, """{
"type": "object",
"properties": {
"city": { "type": "string" }
},
"required": ["city"]
}""");
public async Task<ToolResult> InvokeAsync(
ToolInvocation invocation, CancellationToken ct)
{
var city = invocation.Arguments["city"]?.ToString();
var temp = await FetchTemperatureAsync(city, ct);
return new ToolResult(true, $"Temperature in {city}: {temp}°C", null);
}
}
3. Connect everything and run¶
Register the runtime, your client, and your tool in DI. Then take the runtime and give it a goal:
var services = new ServiceCollection();
services.AddAiClevernessRuntime();
services.AddAiClevernessLlmClient<MyLlmClient>();
services.AddAgentTool<WeatherTool>();
var provider = services.BuildServiceProvider();
var runtime = provider.GetRequiredService<IAgentRuntime>();
var request = new AgentRequest(
Goal: "What is the weather in Tokyo?",
AllowedToolNames: ["get_weather"]);
var result = await runtime.RunAsync(request);
Console.WriteLine(result.Output); // "Temperature in Tokyo: 22°C"
Console.WriteLine(string.Join("\n", result.Steps)); // execution log
What happens inside RunAsync: the runtime sends the goal and the tool
definitions to your LLM client, runs the tool calls the model asks for, and
repeats this until the goal is answered. See
Runtime Pipeline for every step of this
loop, and Defining Tools for more ways to
describe a tool.