Prompt management

Prompts

Deployments

You can create prompts with versions and create their deployments that can be used via the SDK.

Integrating SDK into your code

getPrompt function will respond with deployed version of the given prompt. You can deploy prompts directly from the Maxim dashboard.

const prompt = await maxim.getPrompt("prompt-id");

For a prompt with specific deployment variables

For building query to get prompt with specific deployment variables, you can use QueryBuilder.

const prompt = await maxim.getPrompt("prompt-id",
					new QueryBuilder()
						.and()
						.deploymentVar("Environment", "prod")
						.build()});

Adding multiple queries

const prompt = await maxim.getPrompt(
	"prompt-id",
	new QueryBuilder()
	    .and()
		.deploymentVar("Environment", "prod")
		.deploymentVar("CustomerId", "123")
		.build(),
);

Adding filters based on Tags

const prompt = await maxim.getPrompt(
	"prompt-id",
	new QueryBuilder()
	    .and()
		.deploymentVar("Environment", "prod")
		.tag("TenantId", "3000")
		.build(),
);

Querying Prompts

Sometimes you have usescases where you need to fetch multiple deployed prompts at once using a single query. For example, you might want to fetch all prompts for a specific customer or specific workflow. You can use getPrompts function for this purpose.

You will need to query using at-least one deploymentVar as a filter. Hence you will need to deploy prompt versions before querying them.

Query deployed prompts using tags

const prompts = await maxim.getPrompts(
    new QueryBuilder()
        .and()
        .deploymentVar("Environment", "prod")
        .tag("CustomerId", "123")
        .build()
);

Query deployed prompts using folder

To get all prompts from a folder, you can use getPrompts function with folderId as a query parameter.

First capture folder id

There are multiple ways to capture folder id. You can use Maxim dashboard to get folder id.

  1. Right click/click on three dots on the folder you want to get id for.
  2. Select Edit Folder option.
  3. You will see folder id in the form.

Settings Page

const folder = await maxim.getFolderById("folder-id");

To get folders using tags attached to the folder.

const folders = await maxim.getFolders(new QueryBuilder().and().tag("CustomerId", "123").build());
All the rules of prompt matching algorithm apply here. You can use same overriding techniques as explained above.

Get all deployed prompts from a folder

const folder = ...
const prompts = await maxim.getPrompts(
	new QueryBuilder()
	.and()
	.folder(folder.id)
	.deploymentVar("Environment", "prod")
	.build(),
);

You can filter prompts based on deploymentVars or tags attached to the prompt.

const folder = ...
const prompts = await maxim.getPrompts(
		new QueryBuilder()
		.and()
		.folder(folder.id)
		.deploymentVar("Environment", "prod")
		.tag("CustomerId","123")
		.build());
You have to pass at-least one filter along with folder(). Either a deploymentVar or a tag.

Prompt Structure

export type Prompt = {
	promptId: string;
	version: number;
	versionId: string;
	messages: { role: string; content: string }[];
	modelParameters: { [key: string]: string };
	provider: string;
	model: string;
	tags: { [key: string]: string };
};

Folder Structure

export type Folder = {
	id: string;
	name: string;
	parentFolderId?: string;
	tags: { [key: string]: string };
};

Using your own cache for prompts

Maxim SDK uses in-memory caching by default. You can use your own caching implementation by passing a custom cache object to the SDK. This allows you to remove complete dependency on our backend.

Interface for custom cache

export interface MaximCache {
	getAllKeys(): Promise<string[]>;
	get(key: string): Promise<string | null>;
	set(key: string, value: string): Promise<void>;
	delete(key: string): Promise<void>;
}

You will have to pass this custom cache object to the SDK while initializing it.

const maxim = new Maxim({ apiKey: "api-key", cache: new CustomCache() });

Example

Here is the default in-memory cache implementation used by the SDK.

export class MaximInMemoryCache implements MaximCache {
	private cache: Map<string, string> = new Map();
 
	getAllKeys(): Promise<string[]> {
		return Promise.resolve(Array.from(this.cache.keys()));
	}
 
	get(key: string): Promise<string | null> {
		return Promise.resolve(this.cache.get(key) || null);
	}
	set(key: string, value: string): Promise<void> {
		this.cache.set(key, value);
		return Promise.resolve();
	}
}

Matching algorithm

Before going into the details of how to use the SDK, let's understand how the matching algorithm works. Maxim SDK uses best matching entity algorithm.

  1. Let's assume that, you have asked for a prompt with deployment var env as prod, customerId as "123" and a tag, tenantId as 456 for promptId - "abc".
  2. SDK will first try to find a prompt matching all conditions.
  3. If we don't find any matching entity, we enforce only deploymentVar conditions (you can override this behaviour, as explained in the next section) and match as many tags as possible.
  4. If we still don't find any prompt, we check for a prompt version marked as fallback.
  5. If we still don't find any prompt, we return null.

Overriding fallback algorithm

  1. You can override fallback algorithm by calling .exactMatch() on QueryBuilder object. That will enforce all conditions to be matched.
const prompt = await maxim.getPrompt(
	"prompt-id",
	new QueryBuilder()
        .and()
        .deploymentVar("Environment", "prod")
        .tag("CustomerId", "123")
        .exactMatch()
        .build(),
);
  1. You can override fallback algorithm at each variable level. The third optional parameter in deploymentVar & tag function is enforce. If you pass true to this parameter, it will enforce exact match for that variable.
const prompt = await maxim.getPrompt(
	"prompt-id",
	new QueryBuilder()
	    .and()
		.deploymentVar("Environment", "prod")
		.tag("CustomerId", "123", true)
		.build(),
);

On this page