Sempai is a modular SDK for building intelligent, multi-vendor AI agents in C#.
It provides tools and abstractions to create, configure, and run agents that can integrate with a variety of AI service
providers.
Sempai supports integration with the following AI service providers via the AgentProviderType enumeration:
- Anthropic
- AzureAIFoundry
- AzureOpenAI
- AwsBedrock
- GithubModels
- GoogleGemini
- Groq
- Huggingface
- Mistral
- Ollama
- OpenAI
- OpenRouter
- XAI
To use Sempai in your project, you can reference the NuGet packages directly from GitHub.
dotnet nuget add source https://nuget.pkg.github.com/sofdigital/index.json -n githubAdd the following PackageReference to your .csproj file:
<ItemGroup>
<PackageReferenceInclude="Sempai"Version="0.1.0" />
<PackageReferenceInclude="Sempai.Extensions"Version="0.1.0" />
</ItemGroup>importSofDigital.Sempai.Core;importSofDigital.Sempai.Agents;importSofDigital.Sempai.Extensions;services.AddSempai();varagentFactory=ServiceProvider.GetService<IAgentFactory>();varagentMessageFactory=ServiceProvider.GetService<IAgentMessageFactory();varconnector=newAgentConnector(AgentProviderType.OpenAI,"<api-key>","gpt-5.2");varconfiguration=newAgentConfiguration{AgentName="TimeAgent",Instructions="You are a helpful assistant.",MaxOutputTokens=100,Temperature=0.7f,Threaded=false,Tools=[],};varagent=awaitagentFactory.CreateAgent<Agent>(connector,configuration);varmessage=agentMessageFactory.CreateTextMessage("What time is the current time in UTC?");varresponse=awaitagent!.RunAsync(message);- Concurrent: Agents each work on a task in parallel
- Sequential: Agents each work on a task in an ordered pipeline
- Handoff: Agents are orchestrated depending on a task
- Group Chat: Agents collaborate amongst themselves on a task
importSofDigital.Sempai.Core;importSofDigital.Sempai.Agents;importSofDigital.Sempai.Extensions;services.AddSempai();varagentFactory=ServiceProvider.GetService<IAgentFactory>();varagentMessageFactory=ServiceProvider.GetService<IAgentMessageFactory();varagentWorkflowFactory=ServiceProvider.GetService<IAgentWorkflowFactory>();vardefaultConnector=newAgentConnector(AgentProviderType.OpenAI,"<api-key>","gpt-5.2");varwriterAgentConfiguration=newAgentConfiguration{AgentName="WriterAgent",Instructions="You are a creative writer. Generate a catchy slogan and marketing copy. Be concise and impactful."};varreviewerAgentConfiguration=newAgentConfiguration{AgentName="ReviewerAgent",Instructions="You are a copy reviewer. Evaluate slogans for clarity, impact, and brand alignment."};conststringprompt="Create a slogan for an eco-friendly new LLM model.";varwriterAgent=awaitagentFactory.CreateAgent<Agent>(defaultConnector,writerAgentConfiguration);varreviewerAgent=awaitagentFactory.CreateAgent<Agent>(defaultConnector,reviewerAgentConfiguration);varmessage=agentMessageFactory.CreateTextMessage(prompt);varmessages=newList<ChatMessage>{message};varagentSequentialWorkflow=agentWorkflowFactory.CreateGroupChat(3,writerAgent!,reviewerAgent!);varresult=awaitagentSequentialWorkflow.CreateStreamAsync(messages,true);awaitagentSequentialWorkflow.ConsumeStreamAsync(msg =>{Console.WriteLine("Yielded \nauthor:{AuthorName} \nrole: {Role}\nmessage: {Message}",msg.AuthorName,msg.Role,msg.Contents);});The Agent class is the core component of Sempai, providing a unified interface for interacting with various AI
vendors.
importSofDigital.Sempai.Core;importSofDigital.Sempai.Agents;importSofDigital.Sempai.Extensions;services.AddSempai();varagentFactory=ServiceProvider.GetService<IAgentFactory>();varconnector=newAgentConnector(AgentProviderType.OpenAI,"<api-key>","gpt-5.2");varcustomAgentConfiguration=newAgentConfiguration{AgentName="CustomAgent",Instructions="You are a creative writer. Generate a catchy slogan and marketing copy. Be concise and impactful."};varcustomAgent=awaitagentFactory.CreateAgent<Agent>(connector,customAgentConfiguration);Sempai automatically tracks token usage for each agent instance. You can access the cumulative token counts via the following properties:
TokenCountInput: Total input tokens used.TokenCountOutput: Total output tokens generated.TokenCountReasoning: Total reasoning tokens used (for supported models).
varresponse=awaitagent.RunAsync("Hello, world!");Console.WriteLine($"Input Tokens: {agent.TokenCountInput}");Console.WriteLine($"Output Tokens: {agent.TokenCountOutput}");You can subscribe to the OnTokenUsageUpdated event to receive updates as tokens are consumed during an agent run.
agent.OnTokenUsageUpdated+=(usage)=>{Console.WriteLine($"Incremental Input: {usage.Input}");Console.WriteLine($"Cumulative Input: {usage.TotalInput}");};Agents can be converted into tools, allowing them to be called by other agents.
agent.AgentAsToolName="SpecializedAgent";agent.AgentAsToolDescription="An agent that handles specialized tasks.";varagentTool=agent.GetAsAgentTool();// Use agentTool in another agent's configurationYou can stream responses from the agent for a more interactive experience.
varstream=agent.RunStreamingAsync("Tell me a long story...");awaitforeach(varupdateinstream){Console.Write(update.Text);}Sempai supports strongly-typed responses, allowing you to easily parse AI output into C# objects.
publicrecordWeatherInfo(stringCity,intTemperature);varresponse=awaitagent.RunAsync<WeatherInfo>("What's the weather in Seattle?");WeatherInfoinfo=response.Result;Console.WriteLine($"It's {info.Temperature}°C in {info.City}.");The AgentConfiguration object allows for fine-grained control over agent behavior:
Autonomous: Enables an autonomous plan-act-reflect loop when set totrue.WebSearchEnabled: Enables the agent to perform web searches to retrieve real-time information.Instructions: The system prompt or instructions for the agent.MaxOutputTokens: The maximum number of tokens in the response.Temperature: Randomness of the output (defaults to 0.7).Threaded: Automatically manages conversation threads when set totrue.
The default Agent implementation includes built-in tools that are automatically available:
- Current Date and Time: Provides the agent with the ability to retrieve the current date and time in either Local or UTC format.
You can extend an agent's capabilities by adding custom tools. Tools are methods within your agent class that are exposed to the AI.
- Define the Tool Method: Create a method and use the
[Description]attribute to describe its purpose and parameters. - Register the Tool: Override
GetTools()and useagentFactory.CreateFuctionto include your method.
[Description("Description of what the tool does")]publicstringMyCustomTool([Description("Description of the parameter")]stringinput){// Tool logic herereturn$"Result for {input}";}
# Onderived Agent class
public override IEnumerable<AITool> GetTools(){return[AIFunctionFactory.Create(MyCustomTool,"my_custom_tool")];}
# Asan Agent configuration
varmyCustomTool=awaitagentFactory.CreateFuction(MyCustomTool,"my_custom_tool","My custon tool");varcustomAgentConfiguration=newAgentConfiguration{AgentName="MyCustomToolAgent",Tools=[myCustomTool],};The ConfigurableAgent is a specialized agent that can be initialized with custom parameters using a strongly-typed
configuration or built-in tools.
You can create your own specialized agents by inheriting from ConfigurableAgent and ConfigurableAgentParameters.
This pattern allows you to define custom parameters and specialized logic for your agents.
- Define Custom Parameters: Inherit from
ConfigurableAgentParametersto add your own settings. - Define the Custom Agent: Inherit from
ConfigurableAgentand implementIAgentParameterConsumer<TParameters>for your custom parameter type.
publicclassWebSearchAgentParameters:ConfigurableAgentParameters{publicstringSearchEngine{get;set;}="Bing";}publicclassWebSearchAgent:ConfigurableAgent,IAgentParameterConsumer<WebSearchAgentParameters>{privateWebSearchAgentParameters?_webParameters;publicvoidApplyParameters(WebSearchAgentParametersparameters){_webParameters=parameters;// Optionally apply base parametersbase.ApplyParameters(parameters);}publicoverrideIEnumerable<AITool>GetTools(){// Use _webParameters?.SearchEngine in your tool logicreturn[];}}To use your custom agent, pass your parameter type to AgentConfiguration<TParameters>:
varconfiguration=newAgentConfiguration<WebSearchAgentParameters>{AgentName="MyWebSearchAgent",Parameters=newWebSearchAgentParameters{IndexName="web-index",SearchEngine="Google"}};services.AddTransient<WebSearchAgent>();varagent=awaitagentFactory.CreateAgent<WebSearchAgent>(connector,configuration);The application uses appsettings.json and environment variables for configuration. Ensure the following files are
present in the root directory:
appsettings.jsonappsettings.Development.json
You can customize these files to set up your environment. For example:
appsettings.json
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft": "Warning",
"Microsoft.Hosting.Lifetime": "Information"
}
},
"AgentDefaultConnectors": {
"Basic": {
"Provider": "YourProvider",
"ApiKey": "YourApiKey",
"Model": "YourModel",
"ResourceUri": "YourResourceUri"
}
}
}This project depends on the following NuGet packages:
SempaiSempai.CoreSempai.Extensions