forge-ml
v0.2.6
Published
The Fastest Way to Build Bulletproof AI Products
Downloads
7,744
Maintainers
Readme
🚅 Forge: The Fastest Way to Build Bulletproof AI Products 🏃💨
A developer toolkit for making AI product development easy and reliable, starting with structured data.
Installation • Quickstart • Forge Online
🚀 Installation
Install Forge globally:
npm install -g forge-ml
And you're live!
forge --help
🛠️ What is Forge?
Features
- Fully typesafe Typescript SDK, auto-generated from your zod schemas
- AI-powered schema creation and editing (save time and get better results with mini-prompts optimized for each key)
- Guaranteed response structure (no more parsing JSON)
- Auto-generated documentation for endpoints (get reliable structured responses in any language)
- Caching and cache-management for queries (don't burn tokens on repeat extractions)
- Multiple LLM Providers: Anthropic and OpenAI - Groq coming soon (avoid vendor lock-in)
Forge uses a combination of tools like Zod and Instructor to create and deploy endpoints that can be used to extract structured data from LLMs. It's the easiest way to build AI products.
You define a Zod schema, test it locally, and run forge deploy
. From there you can access it from any application with a fetch request or the auto-generated SDK, and it's guaranteed to have the expected response structure.
// Define your schema
const whois = z.object({
name: z.string(),
occupation: z.string(),
hobbies: z.array(z.string()),
});
# deploy
forge deploy
// endpoint: https://api.forge-ml.com/q/jakezegil/whois
// prompt: Jake Zegil is a Software Engineer who likes ripping code and driving boats
// Your endpoint response -
{
name: "Jake Zegil",
occupation: "Software Engineer",
hobbies: ["ripping code", "driving boats"],
}
📈 Quickstart
Run the following shell commands in the root directory of your project.
# Sign up for a forge account
forge signup
## Install zod
npm install zod
## Initialize your forge project
forge init
## Create a forge schema
forge create
# Test your endpoint
forge test ./forge/schema/<your_schema>.ts
# Deploy your schema as an endpoint
forge deploy
❗️ Note ❗️ In order to deploy, your schema file must have a zod object as the default export and a named config
export containing the path
.
export default z
.object({
// your schema here
})
.describe("my schema");
export const config: EndpointConfig = {
// "path" determines the url path for the endpoint you'll deploy
path: "my-schema", // one word, no special characters
public: true || false, // determines if the endpoint is available for public access
name: "My Schema", // name of the endpoint
description: "My schema description",
cache: "Individual" | "Common" | "None", // cache determines how the schema is cached.
contentType: "text" | "image", // contentType determines the type of content the endpoint will receive
model:
"gpt-4o-mini" | "gpt-4o" | "gpt-4" | "gpt-3.5-turbo" | "<custom-model-id>", // model determines the model used to generate and query the endpoint
};
Once you're authenticated and have deployed an endpoint, you can view and test out all of your live endpoints on your swagger docs page:
forge docs # https://api.forge-ml.com/docs/jakezegil
You can see my openAPI spec here.
🔐 Authentication
Auth lives at forge auth
. When you log in or sign up, you'll get a fresh api key (this will not invalidate your old key). Your credentials are stored at ~/.forge/key.json
.
forge auth signup # Sign up for a forge account
forge auth login # Log in to your account
forge auth logout # Log out of your account
For simplicity you can also just use forge login
and forge signup
to login and signup.
If you don't like your username, you can always update it, but beware! It will also update your deployed endpoints. Your swagger docs are dynamic, and will reflect your latest username and endpoints.
forge auth update # update your forge username
🔑 Managing API Keys
Your api keys live in ~/.forge/key.json
. You can manage them using some of the utility functions forge provides out of the box:
# List API key status (are keys set?)
forge key list
# Copy a key from the local forge credential cache to your clipboard
# You'll need this once you're ready to hit a deployed endpoint
forge key copy <provider>
# Set a key (defaults to setting your openAI key, in case it isn't valid anymore or you want to change it)
forge key set <API_KEY> --provider <provider>
🔨 Building your Schemas
Forge can create new schemas for you using forge create
. After using the command, you'll be met with a series of prompts to set up your endpoint configuration. Finally you'll be asked for a prompt to generate a schema:
forge> Enter a prompt for your schema? (ex. Generate a Person schema with attributes like a job, name, age, etc.)
user> Make me a superhero schema with attributes like name, sidekick, and abilities, etc. Add a lot of attributes and be very detailed.
forge> Creating schema...
Once the schema is generated, a new forge schema file <endpoint-path>.ts
will be created in ./forge/schema
for you to test and deploy.
🛜 Forge Online
Forge partners with lsd.so for live data from the web.
The LSD bicycle allows you to easily and precisely access structured data from the internet, fast. You can then pipe that data into your prompt context, which gives forge realtime access to any website when building structured AI workflows.
As an example, we built an app that allows you to filter and sort live hacker news articles by vibes:
- Demo: https://main--forge-lsd.netlify.app/
- Code: https://github.com/forge-ml/example.forge-on-lsd
🤖 Using the Forge SDK
forge init
and forge deploy
will generate a client for you, allowing you to interact with your endpoints programatically.
Lets walk through an example of how to use the Forge SDK
After forge init
you'll have a client.ts
file in your forge
folder that looks like this:
import Forge from "@forge-ml/client";
const keyGuard = () => {
throw new Error("set FORGE_KEY in your .env");
};
const forgeKey = process.env.FORGE_KEY || keyGuard();
const forge = Forge({
forgeKey: forgeKey,
});
export default forge;
Feel free to edit this, it's only regenerated when you run forge init
.
In the root of your project add a .env
file with your forge key. You can get your forge key after logging in by running forge key copy forge
.
FORGE_KEY=your-forge-key
Then, import your forge client and make a request:
import forge from "./forge/client";
const response = await forge.person.get({
q: "Who is Mark Twain?",
});
// a typesafe response!
const firstName = response.name.firstName; // "Mark"
console.log(firstName);
And you'll get a typesafe response from your endpoint:
{
"name": {
"full": "Mark Twain",
"firstName": "Mark",
"lastName": "Twain"
},
...
"_meta": {
"usage": {
"prompt_tokens": 211,
"completion_tokens": 220,
"total_tokens": 431
},
"cacheHit": false
}
}
⚡️ Creating your first endpoint
Create a typescript file with a zod schema as the default export
// ./forge/schema/endpointSchema.ts import z from "zod"; const PersonCategory = z.enum([ "historical", "celebrity", "politician", "scientist", "artist", "other", ]); // Define the main person schema const PersonSchema = z.object({ name: z.object({ full: z.string(), firstName: z.string(), lastName: z.string(), }), birthDate: z.date(), deathDate: z.date().optional(), nationality: z.string().optional(), occupation: z.array(z.string()).min(1), category: PersonCategory, knownFor: z.array(z.string()), briefBio: z.string().max(500), imageUrl: z.string().url(), sources: z.array(z.string().url()), lastUpdated: z.date().default(() => new Date()), }); export default PersonSchema;
Add a config export to the schema typescript file. The path for the endpoint should be one word with no special characters
/* * forge/schema/endpointSchema.ts */ export const config: EndpointConfig = { /** path to the endpoint. one word, no special characters */ path: "the_path", /** * determines if the endpoint is available for public access. * users will always use their own OpenAI API key (you won't be dinged for others using your endpoint) */ public: true, /** name of the endpoint */ name: "Person", /** description of the endpoint */ description: "A person in history or the present day", /** cache setting **/ cache: "Individual", // this means it's set to be unique to each user contentType: "text", // this means the endpoint will process text model: "gpt-4o-mini", // this means the endpoint will use the gpt-4o-mini model };
Test the endpoint
forge test ./forge/schema/endpointSchema.ts ## Enter your prompt: Who is Mark Twain?
// Your response should look something like this: { "name": "Mark Twain", "fullName": { "firstName": "Mark", "lastName": "Twain" }, "birthDate": "1920-03-01", "deathDate": "1961-04-21", "nationality": "American", "occupation": ["writer", "illustrator"], "knownFor": [ "The Adventures of Tom Sawyer", "Adventures of Huckleberry Finn" ], "briefBio": "Mark Twain, whose real name was Samuel Langhorne Clemens, was an American writer and humorist. He is best known for his novels 'The Adventures of Tom Sawyer' and 'Adventures of Huckleberry Finn,' which are considered classics of American literature.", "sources": ["https://en.wikipedia.org/wiki/Mark_Twain"], "_meta": { "usage": { "prompt_tokens": 75, "completion_tokens": 79, "total_tokens": 154 } } }
Deploy the endpoint, and check it out in your swagger docs
forge deploy ## Deploy your endpoints forge docs ## Check out your swagger docs
Grab your forge key
forge key copy forge ## Copy your forge key to your clipboard
Make your first request!
# Make a request to your endpoint # If this seems like a lot, just use your forge client! # The only required header is `Authorization` curl -X POST https://api.forge-ml.com/q/your_username/the_path -H "Authorization: Bearer <your-forge-key>" -d '{"q": "Who is Mark Twain?"}' # You can also pass -H "cache-behavior: <bust | evade | none>" and -H "model: <model-id>" to override the default behaviors
⚙️ Endpoint Config
The exported config is used for deployment. It must be a const config
exported from the schema file.
export type EndpointConfig = {
/** path to the endpoint. one word, no special characters */
path: string;
/** name of the endpoint */
name?: string;
/** description of the endpoint */
description?: string;
/** cache setting
* Individual - cache is unique to each user
* Common - cache is shared amongst all users
* None - no caching
* **/
cache: "Individual" | "Common" | "None";
/** contentType setting
* text - the endpoint will process text
* image - the endpoint will process images
* **/
contentType: "text" | "image";
/** model setting
* gpt-4o-mini - the endpoint will use the gpt-4o-mini model
* gpt-4o - the endpoint will use the gpt-4o model
* gpt-4 - the endpoint will use the gpt-4 model
* gpt-3.5-turbo - the endpoint will use the gpt-3.5-turbo model
* <custom-model-id> - the endpoint will use a OpenAI custom model id - as of right now we only support OPENAI as a model provider
* if no model is included we use gpt-4o-mini by default
* **/
model: "gpt-4o-mini" | "gpt-4o" | "gpt-4" | "gpt-3.5-turbo" | "<custom-model-id>";
};
export const config: EndpointConfig = {
...
}
📝 Editing a schema
You can edit a schema by running forge edit
in root directory of your project. You will then be prompted for a schema to edit and the changes you would like to make.
forge> Let's edit your schema! Which file would you like to edit?
user> superhero.ts student.ts recipe.ts * book.ts example.ts test.ts vegetables.ts
forge> What edits would you like to make?
user> Make genre an array and add a new attribute "pageCount"
forge> Editing schema...
🧪 Testing an endpoint
Endpoint schemas can be tested locally using:
forge test <path-to-schema>
👆 Deploying a schema
Example schemas can be found in the ./forge/schema
folder of this project.
forge deploy
deploys all schemas in the ./forge/schema
folder by default. Files with a .ignore.ts extension are ignored.
forge deploy ## Deploy all schemas in the ./forge folder