Browse Source

Initial AI documentation

pull/23533/head
enisn 11 months ago
parent
commit
ebea2d67bb
No known key found for this signature in database GPG Key ID: A052619F04155D1C
  1. 311
      docs/en/framework/infrastructure/artificial-intelligence.md
  2. 1
      docs/en/framework/infrastructure/index.md
  3. 159
      framework/src/Volo.Abp.AI/README.md

311
docs/en/framework/infrastructure/artificial-intelligence.md

@ -0,0 +1,311 @@
# Artificial Intelligence
ABP provides a simple way to integrate AI capabilities into your applications by unifying two popular .NET AI stacks under a common concept called a "workspace":
- Microsoft.Extensions.AI `IChatClient`
- Microsoft.SemanticKernel `Kernel`
A workspace is just a named scope. You configure providers per workspace and then resolve either default services (for the "Default" workspace) or workspace-scoped services.
## Installation
> This package is not included by default. Install it to enable AI features.
It is suggested to use the ABP CLI to install the package. Open a command line window in the folder of the project (.csproj file) and type the following command:
```bash
abp add-package Volo.Abp.AI
```
### Manual Installation
Add nuget package to your project:
```bash
dotnet add package Volo.Abp.AI
```
Then add the module dependency to your module class:
```csharp
using Volo.Abp.AI;
using Volo.Abp.Modularity;
[DependsOn(typeof(AbpAIModule))]
public class MyProjectModule : AbpModule
{
}
```
## Usage
### Chat Client
#### Default configuration (quick start)
Configure the special workspace named `"Default"` to inject `IChatClient` by default.
```csharp
using Microsoft.Extensions.AI;
using Microsoft.SemanticKernel;
using Volo.Abp.AI;
using Volo.Abp.Modularity;
public class MyProjectModule : AbpModule
{
public override void ConfigureServices(ServiceConfigurationContext context)
{
context.Services.PreConfigure<AbpAIOptions>(options =>
{
options.Workspaces.Configure(AbpAIModule.DefaultWorkspaceName, configuration =>
{
configuration.ConfigureChatClient(chatClientConfiguration =>
{
chatClientConfiguration.Builder = new ChatClientBuilder(
sp => new OllamaApiClient("http://localhost:11434", "mistral")
);
chatClientConfiguration.BuilderConfigurers.Add(builder =>
{
builder.UseSystemMessage(
"You are a helpful assistant that greets users in a friendly manner with their names."
);
});
});
// Chat client only in this quick start
});
});
}
}
```
Notes:
- Prefer `ConfigureChatClient(...)` / `ConfigureKernel(...)` methods for configuration.
- Set the `Builder` and then use `BuilderConfigurers.Add(...)` to apply incremental changes.
- If a workspace configures only the Kernel, a chat client may still be exposed for that workspace through the Kernel’s service provider (when available).
Once configured, inject the default chat client:
```csharp
using Microsoft.Extensions.AI;
public class MyService
{
private readonly IChatClient _chatClient; // default chat client
public MyService(IChatClient chatClient)
{
_chatClient = chatClient;
}
}
```
#### Workspace configuration
Workspaces allow multiple, isolated AI configurations. Define workspace types (optionally decorated with `WorkspaceNameAttribute`). If omitted, the type’s full name is used.
```csharp
using Volo.Abp.AI;
[WorkspaceName("GreetingAssistant")]
public class GreetingAssistant // ChatClient-only workspace
{
}
[WorkspaceName("ContentPlanner")]
public class ContentPlanner // Kernel-only workspace
{
}
```
Configure a ChatClient workspace:
```csharp
public class MyProjectModule : AbpModule
{
public override void ConfigureServices(ServiceConfigurationContext context)
{
context.Services.PreConfigure<AbpAIOptions>(options =>
{
options.Workspaces.Configure<GreetingAssistant>(configuration =>
{
configuration.ConfigureChatClient(chatClientConfiguration =>
{
chatClientConfiguration.Builder = new ChatClientBuilder(
sp => new OllamaApiClient("http://localhost:11434", "mistral")
);
chatClientConfiguration.BuilderConfigurers.Add(builder =>
{
builder.UseSystemMessage(
"You are a helpful assistant that greets users in a friendly manner with their names."
);
});
});
});
});
}
}
```
### Semantic Kernel
#### Default configuration
```csharp
public class MyProjectModule : AbpModule
{
public override void ConfigureServices(ServiceConfigurationContext context)
{
context.Services.PreConfigure<AbpAIOptions>(options =>
{
options.Workspaces.Configure<ContentPlanner>(configuration =>
{
configuration.ConfigureKernel(kernelConfiguration =>
{
kernelConfiguration.Builder = Kernel.CreateBuilder()
.AddAzureOpenAIChatClient("...", "...");
});
// Note: Chat client is not configured here
});
});
}
}
```
#### Workspace configuration
```csharp
using Microsoft.Extensions.AI;
using Volo.Abp.AI;
public class GreetingService
{
private readonly IChatClient<GreetingAssistant> _chatClient;
public GreetingService(IChatClient<GreetingAssistant> chatClient)
{
_chatClient = chatClient;
}
public async Task<string> GreetAsync(string name)
{
var response = await _chatClient.GetResponseAsync(
[new ChatMessage(ChatRole.User, $"Greet {name}")]
);
return response?.Message?.Text ?? string.Empty;
}
}
```
#### Resolve
```csharp
using Microsoft.Extensions.AI;
using Volo.Abp.AI;
using Microsoft.SemanticKernel;
public class PlanningService
{
private readonly IKernelAccessor<ContentPlanner> _kernelAccessor;
private readonly IChatClient<ContentPlanner> _chatClient; // available even if only Kernel is configured
public PlanningService(
IKernelAccessor<ContentPlanner> kernelAccessor,
IChatClient<ContentPlanner> chatClient)
{
_kernelAccessor = kernelAccessor;
_chatClient = chatClient;
}
public async Task<string> PlanAsync(string topic)
{
var kernel = _kernelAccessor.Kernel; // Microsoft.SemanticKernel.Kernel
// Use Semantic Kernel APIs if needed...
var response = await _chatClient.GetResponseAsync(
[new ChatMessage(ChatRole.User, $"Create a content plan for: {topic}")]
);
return response?.Message?.Text ?? string.Empty;
}
}
```
## Options
- `AbpAIOptions.Workspaces`: A `WorkspaceConfigurationDictionary` used to configure workspaces.
- `Configure<TWorkspace>(Action<WorkspaceConfiguration>)`
- `Configure(string name, Action<WorkspaceConfiguration>)`
- `WorkspaceConfiguration` per workspace:
- `ChatClient`: `ChatClientConfiguration`
- `Builder`: `ChatClientBuilder?`
- `ConfigureBuilder(Action<ChatClientBuilder>)`
- `ConfigureBuilder(string name, Action<ChatClientBuilder>)` (named actions executed in order)
- `Kernel`: `KernelConfiguration`
- `Builder`: `IKernelBuilder?`
- `ConfigureBuilder(Action<IKernelBuilder>)`
- `ConfigureBuilder(string name, Action<IKernelBuilder>)`
- `AbpAIWorkspaceOptions.ConfiguredWorkspaceNames`: Automatically set of workspace names configured during startup. Useful for diagnostics.
## Advanced Usage and Customizations
### Addding Your Own DelegatingChatClient
If you want to build your own decorator, implement a `DelegatingChatClient` derivative and provide an extension method that adds it to the `ChatClientBuilder` using `builder.Use(...)`.
Example sketch:
```csharp
using Microsoft.Extensions.AI;
public class MyPolicyChatClient : DelegatingChatClient
{
public MyPolicyChatClient(IChatClient inner) : base(inner) { }
public override Task<ChatResponse> GetResponseAsync(IEnumerable<ChatMessage> messages, ChatOptions? options = null, CancellationToken cancellationToken = default)
{
// Mutate messages/options as needed, then call base
return base.GetResponseAsync(messages, options, cancellationToken);
}
}
public static class MyPolicyChatClientExtensions
{
public static ChatClientBuilder UseMyPolicy(this ChatClientBuilder builder)
{
return builder.Use(client => new MyPolicyChatClient(client));
}
}
```
It'll have similar usage with `.UseSystemMessage(...)` extension while configuring a chat client (see configuration examples above).
```cs
chatClientConfiguration.BuilderConfigurers.Add(builder =>
{
builder.UseMyPolicy();
});
```
## Technical Anatomy
- `AbpAIModule`: Wires up configured workspaces, registers keyed services and default services for the `"Default"` workspace.
- `AbpAIOptions`: Holds `Workspaces` and provides helper methods for internal keyed service naming.
- `WorkspaceConfigurationDictionary` and `WorkspaceConfiguration`: Configure per-workspace Chat Client and Kernel.
- `ChatClientConfiguration` and `KernelConfiguration`: Hold builders and a list of ordered builder configurers.
- `WorkspaceNameAttribute`: Names a workspace; falls back to the type’s full name if not specified.
- `IChatClient<TWorkspace>`: Typed chat client for a workspace.
- `IKernelAccessor<TWorkspace>`: Provides access to the workspace’s `Kernel` instance if configured.
- `AbpAIWorkspaceOptions`: Exposes `ConfiguredWorkspaceNames` for diagnostics.
There are no database tables for this feature; it is a pure configuration and DI integration layer.
## See Also
- Microsoft.Extensions.AI (Chat Client)
- Microsoft Semantic Kernel

1
docs/en/framework/infrastructure/index.md

@ -3,6 +3,7 @@
ABP provides a complete infrastructure for creating real world software solutions with modern architectures based on the .NET platform. Each of the following documents explains an infrastructure feature:
* [Audit Logging](./audit-logging.md)
* [Artificial Intelligence](./artificial-intelligence.md)
* [Background Jobs](./background-jobs/index.md)
* [Background Workers](./background-workers/index.md)
* [BLOB Storing](./blob-storing/index.md)

159
framework/src/Volo.Abp.AI/README.md

@ -1,159 +0,0 @@
### Volo.Abp.AI for application developers
Use this package to configure and consume two AI stacks in ABP apps with a shared “workspace” scope:
- Microsoft.Extensions.AI Chat Clients
- Microsoft.SemanticKernel Kernels
Key ideas:
- Decorate a class with `WorkspaceNameAttribute` to define a workspace. The same workspace name is used for both Chat Client and Kernel.
- Resolve services either by workspace type (`IChatClient<TWorkSpace>`, `IKernel<TWorkSpace>`) or as defaults (`IChatClient`, `Kernel`).
### 1) Add module dependency
```csharp
using Volo.Abp.AI;
using Volo.Abp.Modularity;
[DependsOn(typeof(AbpAIModule))]
public class YourAppModule : AbpModule
{
}
```
### 2) Define a workspace
```csharp
using Volo.Abp.AI;
[WorkspaceName("CommentSummarizer")]
public class CommentSummarizer { }
```
If you omit the attribute, the type’s full name is used as the workspace name.
### 3) Configure providers per workspace
Configure in your module (in `ConfigureServices` using `PreConfigure<AbpAIOptions>`). You can set defaults and/or configure specific workspaces.
```csharp
using Microsoft.Extensions.AI;
using Microsoft.SemanticKernel;
using Volo.Abp.AI;
using Volo.Abp.Modularity;
public class YourAppModule : AbpModule
{
public override void ConfigureServices(ServiceConfigurationContext context)
{
PreConfigure<AbpAIOptions>(options =>
{
// Default ChatClient (inject IChatClient)
options.ChatClients.ConfigureDefault(cfg =>
{
cfg.Builder = new ChatClientBuilder();
cfg.ConfigureBuilder(b =>
{
// Example: OpenAI provider (Microsoft.Extensions.AI.OpenAI)
b.UseOpenAIChatClient("gpt-4o-mini", apiKey: "<OPENAI_API_KEY>");
});
});
// Default Kernel (inject Kernel)
options.Kernels.ConfigureDefault(cfg =>
{
var kb = Kernel.CreateBuilder();
// Example: OpenAI connector (Microsoft.SemanticKernel.Connectors.OpenAI)
kb.AddOpenAIChatCompletion("gpt-4o-mini", "<OPENAI_API_KEY>");
cfg.Builder = kb;
});
// Workspace-scoped ChatClient (inject IChatClient<CommentSummarizer>)
options.ChatClients.Configure<CommentSummarizer>(cfg =>
{
cfg.Builder = new ChatClientBuilder();
cfg.ConfigureBuilder(b => b.UseOpenAIChatClient("gpt-4o-mini", "<OPENAI_API_KEY>"));
});
// Workspace-scoped Kernel (inject IKernel<CommentSummarizer>)
options.Kernels.Configure<CommentSummarizer>(cfg =>
{
var kb = Kernel.CreateBuilder();
kb.AddOpenAIChatCompletion("gpt-4o-mini", "<OPENAI_API_KEY>");
cfg.Builder = kb;
});
});
}
}
```
Notes:
- `cfg.Builder` is required for both Chat Client and Kernel.
- You can call `cfg.ConfigureBuilder(...)` multiple times; actions run in order.
### 4) Resolve and use services
Defaults (from `ConfigureDefault`):
```csharp
public class MyService
{
private readonly IChatClient _chatClient; // Microsoft.Extensions.AI
private readonly Kernel _kernel; // Microsoft.SemanticKernel
public MyService(IChatClient chatClient, Kernel kernel)
{
_chatClient = chatClient;
_kernel = kernel;
}
}
```
Workspace-scoped (typed):
```csharp
public class CommentSummarizerService
{
private readonly IChatClient<CommentSummarizer> _chatClient;
private readonly IKernel<CommentSummarizer> _kernel;
public CommentSummarizerService(
IChatClient<CommentSummarizer> chatClient,
IKernel<CommentSummarizer> kernel)
{
_chatClient = chatClient;
_kernel = kernel;
}
}
```
Access the original Semantic Kernel instance via `IKernel<TWorkSpace>.Kernel`:
```csharp
public class KernelUsage
{
private readonly IKernel<CommentSummarizer> _workspaceKernel;
public KernelUsage(IKernel<CommentSummarizer> workspaceKernel)
{
_workspaceKernel = workspaceKernel;
}
public async Task RunAsync()
{
var sk = _workspaceKernel.Kernel; // Microsoft.SemanticKernel.Kernel
// Use SK APIs directly
}
}
```
### Frequently used variations
- Only Chat Client per workspace: configure `options.ChatClients.Configure<YourWorkspace>(...)`.
- Only Kernel per workspace: configure `options.Kernels.Configure<YourWorkspace>(...)`.
- Single global setup: just use `ConfigureDefault` for either or both; inject the default services.
### Terminology
- `WorkspaceNameAttribute`: names a workspace; used for both stacks.
- `IChatClient<TWorkSpace>` and `IKernel<TWorkSpace>`: typed services bound to a workspace.
- `IChatClient` and `Kernel`: defaults if configured via `ConfigureDefault`.
Loading…
Cancel
Save