Create GenAI Task: API
-
A GenAI task leverages an AI model to enable intelligent processing of documents in runtime.
- The task is associated with a document collection and with an AI model.
- It is an ongoing task that:
- Continuously monitors the collection;
- Whenever needed, like when a document is added to the collection, generates user-defined context objects based on the source document data;
- Passes each context object to the AI model for further processing;
- Receives the AI model's JSON-based results;
- And finally, runs a user-defined script that potentially acts upon the results.
-
The main steps in defining a GenAI task are:
- Defining a Connection string to the AI model
- Defining a Context generation script
- Defining a Prompt
- Defining a JSON schema
- Defining an Update script
-
In this article:
Defining a Connection string
- Choose the model to connect with, by what you need from your GenAI task.
E.g., If you require security and speed above all for the duration of a rapid development phase, you may prefer a local AI service like Ollama. - Make sure you define the correct service: both Ollama and OpenAI are supported
but you need to pick an Ollama/OpenAI service that supports generative AI,
like Ollama
llama3.2or OpenAIgpt-4o-mini. - Learn more about connection strings here.
Example:
- set-open-ai
- set-ollama
using (var store = new DocumentStore())
{
// Define the connection string to OpenAI
var connectionString = new AiConnectionString
{
// Connection string name & identifier
Name = "open-ai-cs",
// Connection type
ModelType = AiModelType.Chat,
// OpenAI connection settings
OpenAiSettings = new OpenAiSettings(
apiKey: "your-api-key",
endpoint: "https://api.openai.com/v1",
// text generation model
model: "gpt-4o-mini")
};
// Deploy the connection string to the server
var operation = new PutConnectionStringOperation<AiConnectionString>(connectionString);
var putConnectionStringResult = store.Maintenance.Send(operation);
}
using (var store = new DocumentStore())
{
// Define the connection string to Ollama
var connectionString = new AiConnectionString
{
// Connection string name & identifier
Name = "ollama-cs",
// Connection type
ModelType = AiModelType.Chat,
// Ollama connection settings
OllamaSettings = new OllamaSettings(
// LLM model for text generation
model: "llama3.2",
// local URL
uri: "http://localhost:11434/")
};
// Deploy the connection string to the server
var operation = new PutConnectionStringOperation<AiConnectionString>(connectionString);
var putConnectionStringResult = store.Maintenance.Send(operation);
}
Syntax:
- open-ai-syntax
- ollama-syntax
public class AiConnectionString
{
public string Name { get; set; }
public AiModelType ModelType { get; set; }
public string Identifier { get; set; }
public OpenAiSettings OpenAiSettings { get; set; }
...
}
public class OpenAiSettings : AbstractAiSettings
{
public string ApiKey { get; set; }
public string Endpoint { get; set; }
public string Model { get; set; }
public int? Dimensions { get; set; }
public string OrganizationId { get; set; }
public string ProjectId { get; set; }
}
public class AiConnectionString
{
public string Name { get; set; }
public AiModelType ModelType { get; set; }
public string Identifier { get; set; }
public OllamaSettings OllamaSettings { get; set; }
...
}
public class OllamaSettings : AbstractAiSettings
{
public string Model { get; set; }
public string Uri { get; set; }
}
Defining the GenAI task
- Define a GenAI task using a
GenAiConfigurationobject. - Run the task using
AddGenAiOperation.
- use-sample-object
- use-json-schema
// Define a GenAI task configuration
GenAiConfiguration config = new GenAiConfiguration
{
// Task name
Name = "spam-filter",
// Unique user-defined task identifier
Identifier = "spam-filter",
// Connection string to AI model
ConnectionStringName = "open-ai-cs",
// Task is enabled
Disabled = false,
// Collection associated with the task
Collection = "Posts",
// Context generation script - format for objects to be sent to the AI model
GenAiTransformation = new GenAiTransformation
{
Script = @"
for(const comment of this.Comments)
{
ai.genContext({Text: comment.Text, Author: comment.Author, Id: comment.Id});}"
},
// AI model Prompt - the instructions sent to the AI model
Prompt = "Check if the following blog post comment is spam or not",
// Sample object - the layout for the AI model's response
SampleObject = @"
{
""Blocked"": true,
""Reason"": ""Concise reason for why this comment was marked as spam or ham""
}",
// Update script - specifies what to do with AI model replies.
// Use $input to access the context object that was sent to the AI model.
// Use $output` to access the results object returned from the AI model.
// Use `this` to access and modify the currently processed document.
UpdateScript = @"
// Find the comment
const idx = this.Comments.findIndex(c => c.Id == $input.Id);
// Was detected as spam
if($output.Blocked)
{
// Remove this comment
this.Comments.splice(idx, 1);
}",
// Max concurrent connections to AI model
MaxConcurrency = 4
};
// Run the task
var GenAiOperation = new AddGenAiOperation(config);
var addAiIntegrationTaskResult = store.Maintenance.Send(GenAiOperation);
// Define a GenAI task configuration
GenAiConfiguration config = new GenAiConfiguration
{
// Task name
Name = "spam-filter",
// Unique user-defined task identifier
Identifier = "spam-filter",
// Connection string to AI model
ConnectionStringName = "open-ai-cs",
// Task is enabled
Disabled = false,
// Collection associated with the task
Collection = "Posts",
// Context generation script - format for objects to be sent to the AI model
GenAiTransformation = new GenAiTransformation
{
Script = @"
for(const comment of this.Comments)
{
ai.genContext({Text: comment.Text, Author: comment.Author, Id: comment.Id});}"
},
// AI model Prompt - the instructions sent to the AI model
Prompt = "Check if the following blog post comment is spam or not",
// JSON schema - a schema to format the AI model's replies by
JsonSchema = @"{
""name"": """ + "some-name" + @""",
""strict"": true,
""schema"": {
""type"": ""object"",
""properties"": {
""Blocked"": {
""type"": ""boolean""
},
""Reason"": {
""type"": ""string"",
""description"": ""Concise reason for why this comment was marked as spam or ham""
}
},
""required"": [
""Blocked"",
""Reason""
],
""additionalProperties"": false
}
}",
// Update script - specifies what to do with AI model replies.
// Use $input to access the context object that was sent to the AI model.
// Use $output` to access the results object returned from the AI model.
// Use `this` to access and modify the currently processed document.
UpdateScript = @"
// Find the comment
const idx = this.Comments.findIndex(c => c.Id == $input.Id);
// Was detected as spam
if($output.Blocked)
{
// Remove this comment
this.Comments.splice(idx, 1);
}",
// Max concurrent connections to AI model
MaxConcurrency = 4
};
// Run the task
var GenAiOperation = new AddGenAiOperation(config);
var addAiIntegrationTaskResult = store.Maintenance.Send(GenAiOperation);
GenAiConfiguration
| Parameters | Type | Description |
|---|---|---|
| Name | string | Task name |
| Identifier | string | Unique user-defined task identifier Use only lowercase letters, numbers, and hyphens |
| ConnectionStringName | string | Connection string name |
| Disabled | bool | Determines whether the task is enabled or disabled |
| Collection | string | Name of the document collection associated with the task |
| GenAiTransformation | GenAiTransformation | Context generation script - format for objects to be sent to the AI model |
| Prompt | string | AI model Prompt - the instructions sent to the AI model |
| SampleObject | string | A sample response object to format the AI model's replies by If both a SampleObject and a JsonSchema are provided the schema takes precedence |
| JsonSchema | string | A JSON schema to format the AI model's replies by If both a SampleObject and a JsonSchema are provided the schema takes precedence |
| UpdateScript | string | Update script - specifies what to do with AI model replies |
| MaxConcurrency | int | Max concurrent connections to the AI model (each connection serving a single context object) |
Full example
The following example demonstrates how to define a GenAI task that removes spam comments from blog posts.
After creating a connection string to the AI model, the task defines a GenAI task that:
- Monitors the
Postscollection. - For each document, generates a context object per each comment in the
Commentsarray. - Sends each context object to the AI model with a prompt to check if the comment is spam.
- Receives an AI model response per context object that classifies the comment as spam or not and specifies the reasoning for the decision.
- If the comment is marked as spam, the task's update script removes the comment from the
Commentsarray in the document.
After running the task, its functionality is demonstrated by adding to the Posts collection a blog post that includes a spammy comment. Adding the post triggers the task, which will scan the post's comments and remove the one that contains spam.
// Define a connection string to OpenAI
var connectionString = new AiConnectionString
{
// Connection string name & identifier
Name = "open-ai-cs",
ModelType = AiModelType.Chat,
// OpenAI connection settings
OpenAiSettings = new OpenAiSettings(
apiKey: "your-api-key",
endpoint: "https://api.openai.com/v1",
// LLM model for text generation
model: "gpt-4.1")
};
// Deploy the connection string to the server
var operation = new PutConnectionStringOperation<AiConnectionString>(connectionString);
var putConnectionStringResult = store.Maintenance.Send(operation);
// Define a GenAI task configuration
GenAiConfiguration config = new GenAiConfiguration
{
// Task name
Name = "spam-filter",
// Unique user-defined task identifier
Identifier = "spam-filter",
// Connection string to AI model
ConnectionStringName = "open-ai-cs",
// Task is enabled
Disabled = false,
// Collection associated with the task
Collection = "Posts",
// Context generation script - format for objects to be sent to the AI model
GenAiTransformation = new GenAiTransformation
{
Script = @"
for(const comment of this.Comments)
{
ai.genContext({Text: comment.Text, Author: comment.Author, Id: comment.Id});}"
},
// AI model Prompt - the instructions sent to the AI model
Prompt = "Check if the following blog post comment is spam or not",
// Sample object - the layout for the AI model's response
SampleObject = JsonConvert.SerializeObject(
new
{
Blocked = true,
Reason = "Concise reason for why this comment was marked as spam or ham"
}),
// Update script - specifies what to do with AI model replies.
// Use $input to access the context object that was sent to the AI model.
// Use $output` to access the results object returned from the AI model.
// Use `this` to access and modify the currently processed document.
UpdateScript = @"
// Find the comment
const idx = this.Comments.findIndex(c => c.Id == $input.Id);
// Was detected as spam
if($output.Blocked)
{
// Remove this comment
this.Comments.splice(idx, 1);
}",
// Max concurrent connections to AI model
MaxConcurrency = 4
};
// Run the task
var GenAiOperation = new AddGenAiOperation(config);
var addAiIntegrationTaskResult = store.Maintenance.Send(GenAiOperation);
// Add a blog post document that includes a spam comment to the Posts collection.
// Adding the post will trigger the GenAI task to process it.
using (var session = store.OpenSession())
{
var post = new
{
Name = "first post",
Body = "This is my first post",
Comments = new[]
{
new
{
Id = "comment/1",
Text = "This article really helped me understand how indexes work in RavenDB. Great write-up!",
Author = "John"
},
new
{
Id = "comment/2",
Text = "Learn how to make $5000/month from home! Visit click4cash.biz.example now!!!",
Author = "shady_marketer"
},
new
{
Id = "comment/3",
Text = "I tried this approach with IO_Uring in the past, but I run into problems with security around the IO systems and the CISO didn't let us deploy that to production. It is more mature at this point?",
Author = "dave"
}
}
};
session.Store(post, "posts/1");
session.Advanced.GetMetadataFor(post)["@collection"] = "Posts";
session.SaveChanges();
}