بنقرة واحدة
koan-ai-integration
Chat endpoints, embeddings, RAG workflows, vector search
التثبيت باستخدام Codex أو Claude انسخ هذا Prompt والصقه في Codex أو Claude أو مساعد آخر ليراجع صفحة Skill ويثبّتها لك.
القائمة
Chat endpoints, embeddings, RAG workflows, vector search
التثبيت باستخدام Codex أو Claude انسخ هذا Prompt والصقه في Codex أو Claude أو مساعد آخر ليراجع صفحة Skill ويثبّتها لك.
استنادا إلى تصنيف SOC المهني
Auto-registration via KoanAutoRegistrar, minimal Program.cs, "Reference = Intent" pattern
Aggregate boundaries, relationships, lifecycle hooks, value objects
Entity<T> patterns, GUID v7 auto-generation, static methods vs manual repositories
Transparent L1/L2 caching for Entity<T>, [Cacheable] attribute, cross-node coherence, per-request opt-out
Run a mandatory pre-implementation exploration workflow before writing production code in Koan (.NET/C#). Use when a task requires code changes and Codex must first map concerns/layers, read relevant files and docs, check existing constants and types, identify the closest existing pattern, plan exact code placement, and confirm architectural guardrails.
EntityController<T>, custom routes, payload transformers, auth policies
| name | koan-ai-integration |
| description | Chat endpoints, embeddings, RAG workflows, vector search |
AI capabilities integrate seamlessly with entity patterns. Store embeddings on entities, use vector repositories for search, and leverage standard Entity patterns for AI-enriched data.
The AI facade is the static Client class — no DI injection needed. It resolves the configured
pipeline automatically. For controller use, call Client.ChatAsync() directly.
public class ChatController : ControllerBase
{
[HttpPost]
public async Task<IActionResult> Chat(
[FromBody] ChatRequest request,
CancellationToken ct)
{
var response = await Client.ChatAsync(request.Message, ct);
return Ok(new { message = response.Content, usage = response.Usage });
}
// Streaming — use Server-Sent Events or chunked response
[HttpPost("stream")]
public async IAsyncEnumerable<string> Stream(
[FromBody] ChatRequest request,
[EnumeratorCancellation] CancellationToken ct)
{
await foreach (var chunk in Client.StreamAsync(request.Message, ct))
yield return chunk.Content;
}
}
When you need to inject the pipeline (e.g., for testability), inject IAiPipeline and call
PromptAsync / StreamAsync directly:
public class SummaryService(IAiPipeline ai)
{
public Task<AiChatResponse> Summarise(string text, CancellationToken ct) =>
ai.PromptAsync(new AiChatRequest
{
SystemPrompt = "Summarise the following text concisely.",
Messages = [new AiMessage { Role = "user", Content = text }]
}, ct);
}
There is no
IAiinterface and noChatAsyncmethod on any injectable type. Use the staticClientclass for the default pipeline, or injectIAiPipelinewhen you need a testable seam.
[DataAdapter("weaviate")] // Force vector database
public class ProductSearch : Entity<ProductSearch>
{
public string ProductId { get; set; } = "";
public string Description { get; set; } = "";
[VectorField]
public float[] DescriptionEmbedding { get; set; } = Array.Empty<float>();
// Semantic search
public static async Task<List<ProductSearch>> SimilarTo(
string query,
CancellationToken ct = default)
{
return await Vector<ProductSearch>.SearchAsync(query, limit: 10, ct);
}
}
public class KnowledgeBaseService
{
public async Task<string> AnswerQuestion(string question, CancellationToken ct)
{
// 1. Find relevant documents via vector search
var relevantDocs = await KnowledgeDocument.SimilarTo(question, ct);
// 2. Build context from documents
var context = string.Join("\n\n", relevantDocs.Select(d => d.Content));
// 3. Query AI with context — use the fluent conversation builder
var response = await Client.Converse()
.WithSystem($"Answer based on this context:\n\n{context}")
.WithUser(question)
.PromptAsync(ct);
return response.Content;
}
}
{
"Koan": {
"AI": {
"Providers": {
"Primary": {
"Type": "OpenAI",
"ApiKey": "{OPENAI_API_KEY}",
"Model": "gpt-4"
},
"Fallback": {
"Type": "Ollama",
"BaseUrl": "http://localhost:11434",
"Model": "llama2"
}
}
},
"Data": {
"Sources": {
"Vectors": {
"Adapter": "weaviate",
"ConnectionString": "http://localhost:8080"
}
}
}
}
}
The AI subsystem routes operations by category (Chat, Embed, Ocr) with independent source/model configuration:
{
"Koan": {
"Ai": {
"Chat": { "Source": "ollama-gpu", "Model": "llama3" },
"Embed": { "Source": "openai-prod", "Model": "text-embedding-3-small" },
"Ocr": { "Via": "Chat", "Model": "glm-ocr" }
}
}
}
Override routing per-operation:
using (Client.Scope(chat: "fast-local", embed: "cloud-prod"))
{
var answer = await Client.Chat("Summarize this", ct);
var vector = await Client.Embed("search text", ct);
}
EntityAi in Koan.Data.AI bridges entities with AI operations using convention inference:
// Embed entity content (convention: all string properties)
float[] vector = await EntityAi.Embed(myNote, ct);
// Chat with entity as context (injected as system prompt)
string answer = await EntityAi.Chat("What are the key points?", myNote, ct);
// OCR from entity's byte[] property
string text = await EntityAi.Ocr(myDocument, ct);
// Extract text without AI call
string content = EntityAi.ExtractText(myNote);
Convention chain: [Embedding] attribute → AllStrings policy → JSON fallback.
Named recipes bind capabilities to models. ML engineers author recipes, developers select them:
{
"Koan": {
"Ai": {
"ActiveRecipe": "fast-local",
"Recipes": {
"fast-local": { "Chat": "phi3:mini", "Embed": "nomic-embed-text" },
"cloud-prod": { "Chat": "gpt-4o", "Embed": "text-embedding-3-large" }
}
}
}
}
Recipes are sparse — missing keys mean "no opinion" (falls through to advisor/config).
Automatic AI processing for media entities on upload/save:
[MediaAnalysis(Analysis = MediaAnalysis.Describe | MediaAnalysis.Ocr, Async = true)]
[Embedding]
public class PhotoAsset : MediaEntity<PhotoAsset>
{
public string? AiDescription { get; set; } // Auto-populated by Describe
public string? OcrText { get; set; } // Auto-populated by Ocr
public float[]? Embedding { get; set; } // Auto-populated by [Embedding]
}
Pipeline: Upload → Store → [MediaAnalysis] → [Embedding] → Save atomically.
Analysis modes (combinable via flags):
Convention-detected property mapping: AiDescription, OcrText, Transcript, Category. Override with explicit property names in the attribute.
Cross-modal search: analysis results automatically feed into [Embedding] text via MediaAnalysisEmbeddingBridge.
docs/guides/ai-integration.mddocs/guides/ai-vector-howto.mddocs/decisions/AI-0021-category-driven-ai-with-convention-defaults.md (Category-driven AI)docs/decisions/AI-0032-intent-capability-resolution-with-recipes.md (Recipes)samples/S5.Recs/ (AI recommendation engine)docs/decisions/AI-0027-media-analysis-attribute.md (Media Analysis Attribute)samples/S16.PantryPal/ (Vision AI integration)