Skip to main content

Object Generator Tool

The object generator is a built-in tool that generates an object from a JSON schema using the generateObject model function.

It is useful to create synthetic data with a specific schema and a separate prompt, e.g. for testing, mocking, and fictional writing (RPGs, stories, etc.).

Usage

When setting up a object generator too, you need to configure the following:

  • name: The name of the tool. Optional, helps the calling model.
  • description: The description of the tool. Optional, helps the calling model.
  • parameters: A schema that describes the parameters of the tool. Required.
  • objectSchema: A schema that describes the object that will be generated. Required.
  • model: A object generation model that generates the object. Required.
  • prompt: A prompt function that generates the prompt for the model. The resulting prompt needs to match what is expected by the model. Required.

Example

This example generates a list of enemies for a fantasy role-playing game. It uses a llama.cpp model to generate the enemies. You can switch the model to any other object generation model, e.g. a model from OpenAI.

Enemy Generator Tool

import {
ObjectGeneratorTool,
createInstructionPrompt,
jsonObjectPrompt,
llamacpp,
zodSchema,
} from "modelfusion";
import { z } from "zod";

const enemyGenerator = new ObjectGeneratorTool({
name: "enemies",
description: "Generates a list of enemies.",

parameters: zodSchema(
z.object({
enemyDescription: z
.string()
.describe(
"Examples: 'group of bandits', 'pack of wolves', 'a tall bear', 'a powerful lich', ..."
),
numberOfOpponents: z.number(),
location: z.string().describe("The location of the encounter."),
})
),

objectSchema: zodSchema(
z.array(
z.object({
name: z.string(),
species: z
.string()
.describe(
"The species of the enemy, e.g. human, orc, elf, wolf, bear, skeleton..."
),
class: z
.string()
.describe("Character class, e.g. warrior, mage, thief...")
.optional(),
description: z.string().describe("How the character looks like."),
weapon: z
.string()
.optional()
.describe("The weapon the character uses. Optional."),
})
)
),

model: llamacpp
.CompletionTextGenerator({
// run https://huggingface.co/TheBloke/Mixtral-8x7B-Instruct-v0.1-GGUF with llama.cpp
promptTemplate: llamacpp.prompt.Mistral,
temperature: 1.2,
})
.asObjectGenerationModel(jsonObjectPrompt.instruction()),

prompt: createInstructionPrompt(
async ({ enemyDescription, numberOfOpponents, location }) => ({
system:
"You generate enemies for heroes in a fantasy role-playing game set in a medieval fantasy world. " +
"The list of enemies should be limited to a single encounter. " +
"The enemy group must be consistent, i.e. it must make sense for the enemies to appear together. " +
"There must be at least one enemy.",

instruction: `Generate exactly ${numberOfOpponents} enemies from ${enemyDescription} that the heroes encounter in ${location}.`,
})
),
});

Using the Enemy Generator Tool

You can use the tool with runTool or executeTool:

import { jsonToolCallPrompt, runTool, llamacpp } from "modelfusion";
import { z } from "zod";

const { tool, toolCall, args, ok, result } = await runTool({
model: llamacpp
.CompletionTextGenerator({
// run https://huggingface.co/TheBloke/Mixtral-8x7B-Instruct-v0.1-GGUF with llama.cpp
promptTemplate: llamacpp.prompt.Mistral,
temperature: 2,
topP: 0.8,
})
.withInstructionPrompt()
.asToolCallGenerationModel(jsonToolCallPrompt.text()),

tool: enemyGenerator,

prompt:
"The heros enter a dark cave. They hear a noise. They see something moving in the shadows.",
// "The heros enter the backroom of the tavern. They see a group of people sitting at a table.",
// "The heros are resting in the forest. They hear a noise. They see something moving between the trees.",
// "The heros enter the abandoned graveyard. The moon is full. They see something moving slowly between the graves.",
});

console.log(`Tool call:`, toolCall);
console.log(`Tool:`, tool);
console.log(`Arguments:`, args);
console.log(`Ok:`, ok);
console.log(`Result or Error:`, result);