multiAI Summary Pending
genkit
Build production-ready AI workflows using Firebase Genkit. Use when creating flows, tool-calling agents, RAG pipelines, multi-agent systems, or deploying AI to Firebase/Cloud Run. Supports TypeScript, Go, and Python with Gemini, OpenAI, Anthropic, Ollama, and Vertex AI plugins.
231 stars
Installation
Claude Code / Cursor / Codex
$curl -o ~/.claude/skills/genkit/SKILL.md --create-dirs "https://raw.githubusercontent.com/aiskillstore/marketplace/main/skills/supercent-io/genkit/SKILL.md"
Manual Installation
- Download SKILL.md from GitHub
- Place it in
.claude/skills/genkit/SKILL.mdinside your project - Restart your AI agent — it will auto-discover the skill
How genkit Compares
| Feature / Agent | genkit | Standard Approach |
|---|---|---|
| Platform Support | multi | Limited / Varies |
| Context Awareness | High | Baseline |
| Installation Complexity | Unknown | N/A |
Frequently Asked Questions
What does this skill do?
Build production-ready AI workflows using Firebase Genkit. Use when creating flows, tool-calling agents, RAG pipelines, multi-agent systems, or deploying AI to Firebase/Cloud Run. Supports TypeScript, Go, and Python with Gemini, OpenAI, Anthropic, Ollama, and Vertex AI plugins.
Which AI agents support this skill?
This skill is compatible with multi.
Where can I find the source code?
You can find the source code on GitHub using the link provided at the top of the page.
SKILL.md Source
# Firebase Genkit
## When to use this skill
- **AI workflow orchestration**: Building multi-step AI pipelines with type-safe inputs/outputs
- **Flow-based APIs**: Wrapping LLM calls into deployable HTTP endpoints
- **Tool calling / agents**: Equipping models with custom tools and implementing agentic loops
- **RAG pipelines**: Retrieval-augmented generation with vector databases (Pinecone, pgvector, Firestore, Chroma, etc.)
- **Multi-agent systems**: Coordinating multiple specialized AI agents
- **Streaming responses**: Real-time token-by-token output for chat or long-form content
- **Firebase/Cloud Run deployment**: Deploying AI functions to Google Cloud
- **Prompt management**: Managing prompts as versioned `.prompt` files with Dotprompt
---
## Installation & Setup
### Step 1: Install the Genkit CLI
```bash
# npm (recommended for JavaScript/TypeScript)
npm install -g genkit-cli
# macOS/Linux binary
curl -sL cli.genkit.dev | bash
```
### Step 2: Create a TypeScript project
```bash
mkdir my-genkit-app && cd my-genkit-app
npm init -y
npm pkg set type=module
npm install -D typescript tsx
npx tsc --init
mkdir src && touch src/index.ts
```
### Step 3: Install Genkit core and a model plugin
```bash
# Core + Google AI (Gemini) — free tier, no credit card required
npm install genkit @genkit-ai/google-genai
# Or: Vertex AI (requires GCP project)
npm install genkit @genkit-ai/vertexai
# Or: OpenAI
npm install genkit genkitx-openai
# Or: Anthropic (Claude)
npm install genkit genkitx-anthropic
# Or: Ollama (local models)
npm install genkit genkitx-ollama
```
### Step 4: Configure API Key
```bash
# Google AI (Gemini)
export GEMINI_API_KEY=your_key_here
# OpenAI
export OPENAI_API_KEY=your_key_here
# Anthropic
export ANTHROPIC_API_KEY=your_key_here
```
---
## Core Concepts
### Initializing Genkit
```typescript
import { googleAI } from '@genkit-ai/google-genai';
import { genkit } from 'genkit';
const ai = genkit({
plugins: [googleAI()],
model: googleAI.model('gemini-2.5-flash'), // default model
});
```
### Defining Flows
Flows are the core primitive: type-safe, observable, deployable AI functions.
```typescript
import { genkit, z } from 'genkit';
import { googleAI } from '@genkit-ai/google-genai';
const ai = genkit({ plugins: [googleAI()] });
// Input/output schemas with Zod
const SummaryInputSchema = z.object({
text: z.string().describe('Text to summarize'),
maxWords: z.number().optional().default(100),
});
const SummaryOutputSchema = z.object({
summary: z.string(),
keyPoints: z.array(z.string()),
});
export const summarizeFlow = ai.defineFlow(
{
name: 'summarizeFlow',
inputSchema: SummaryInputSchema,
outputSchema: SummaryOutputSchema,
},
async ({ text, maxWords }) => {
const { output } = await ai.generate({
model: googleAI.model('gemini-2.5-flash'),
prompt: `Summarize the following text in at most ${maxWords} words and extract key points:\n\n${text}`,
output: { schema: SummaryOutputSchema },
});
if (!output) throw new Error('No output generated');
return output;
}
);
// Call the flow
const result = await summarizeFlow({
text: 'Long article content here...',
maxWords: 50,
});
console.log(result.summary);
```
### Generating Content
```typescript
// Simple text generation
const { text } = await ai.generate({
model: googleAI.model('gemini-2.5-flash'),
prompt: 'Explain quantum computing in one sentence.',
});
// Structured output
const { output } = await ai.generate({
prompt: 'List 3 programming languages with their use cases',
output: {
schema: z.object({
languages: z.array(z.object({
name: z.string(),
useCase: z.string(),
})),
}),
},
});
// With system prompt
const { text: response } = await ai.generate({
system: 'You are a senior TypeScript engineer. Be concise.',
prompt: 'What is the difference between interface and type in TypeScript?',
});
// Multimodal (image + text)
const { text: description } = await ai.generate({
prompt: [
{ text: 'What is in this image?' },
{ media: { url: 'https://example.com/image.jpg', contentType: 'image/jpeg' } },
],
});
```
### Streaming Flows
```typescript
export const streamingFlow = ai.defineFlow(
{
name: 'streamingFlow',
inputSchema: z.object({ topic: z.string() }),
streamSchema: z.string(), // type of each chunk
outputSchema: z.object({ full: z.string() }),
},
async ({ topic }, { sendChunk }) => {
const { stream, response } = ai.generateStream({
prompt: `Write a detailed essay about ${topic}.`,
});
for await (const chunk of stream) {
sendChunk(chunk.text); // stream each token to client
}
const { text } = await response;
return { full: text };
}
);
// Client-side consumption
const stream = streamingFlow.stream({ topic: 'AI ethics' });
for await (const chunk of stream.stream) {
process.stdout.write(chunk);
}
const finalOutput = await stream.output;
```
### Tool Calling (Agents)
```typescript
import { z } from 'genkit';
// Define tools
const getWeatherTool = ai.defineTool(
{
name: 'getWeather',
description: 'Get current weather for a city',
inputSchema: z.object({ city: z.string() }),
outputSchema: z.object({ temp: z.number(), condition: z.string() }),
},
async ({ city }) => {
// Call real weather API
return { temp: 22, condition: 'sunny' };
}
);
const searchWebTool = ai.defineTool(
{
name: 'searchWeb',
description: 'Search the web for information',
inputSchema: z.object({ query: z.string() }),
outputSchema: z.string(),
},
async ({ query }) => {
// Call search API
return `Search results for: ${query}`;
}
);
// Agent flow with tools
export const agentFlow = ai.defineFlow(
{
name: 'agentFlow',
inputSchema: z.object({ question: z.string() }),
outputSchema: z.string(),
},
async ({ question }) => {
const { text } = await ai.generate({
prompt: question,
tools: [getWeatherTool, searchWebTool],
returnToolRequests: false, // auto-execute tools
});
return text;
}
);
```
### Prompts with Dotprompt
Manage prompts as versioned `.prompt` files:
```
# src/prompts/summarize.prompt
---
model: googleai/gemini-2.5-flash
input:
schema:
text: string
style?: string
output:
schema:
summary: string
sentiment: string
---
Summarize the following text in a {{style, default: "professional"}} tone:
{{text}}
Return JSON with summary and sentiment (positive/negative/neutral).
```
```typescript
// Load and use dotprompt
const summarizePrompt = ai.prompt('summarize');
const { output } = await summarizePrompt({
text: 'Article content here...',
style: 'casual',
});
```
### RAG — Retrieval-Augmented Generation
```typescript
import { devLocalVectorstore } from '@genkit-ai/dev-local-vectorstore';
import { textEmbedding004 } from '@genkit-ai/google-genai';
const ai = genkit({
plugins: [
googleAI(),
devLocalVectorstore([{
indexName: 'documents',
embedder: textEmbedding004,
}]),
],
});
// Index documents
await ai.index({
indexer: devLocalVectorstoreIndexer('documents'),
docs: [
{ content: [{ text: 'Document 1 content...' }], metadata: { source: 'doc1' } },
{ content: [{ text: 'Document 2 content...' }], metadata: { source: 'doc2' } },
],
});
// RAG flow
export const ragFlow = ai.defineFlow(
{
name: 'ragFlow',
inputSchema: z.object({ question: z.string() }),
outputSchema: z.string(),
},
async ({ question }) => {
// Retrieve relevant documents
const docs = await ai.retrieve({
retriever: devLocalVectorstoreRetriever('documents'),
query: question,
options: { k: 3 },
});
// Generate answer grounded in retrieved docs
const { text } = await ai.generate({
system: 'Answer questions using only the provided context.',
prompt: question,
docs,
});
return text;
}
);
```
### Chat Sessions
```typescript
export const chatFlow = ai.defineFlow(
{
name: 'chatFlow',
inputSchema: z.object({ message: z.string(), sessionId: z.string() }),
outputSchema: z.string(),
},
async ({ message, sessionId }) => {
const session = ai.loadSession(sessionId) ?? ai.createSession({ sessionId });
const chat = session.chat({
system: 'You are a helpful assistant.',
});
const { text } = await chat.send(message);
return text;
}
);
```
### Multi-Agent Systems
```typescript
// Specialist agents
const researchAgent = ai.defineFlow(
{ name: 'researchAgent', inputSchema: z.string(), outputSchema: z.string() },
async (query) => {
const { text } = await ai.generate({
system: 'You are a research expert. Gather facts and cite sources.',
prompt: query,
tools: [searchWebTool],
});
return text;
}
);
const writerAgent = ai.defineFlow(
{ name: 'writerAgent', inputSchema: z.string(), outputSchema: z.string() },
async (brief) => {
const { text } = await ai.generate({
system: 'You are a professional writer. Write clear, engaging content.',
prompt: brief,
});
return text;
}
);
// Orchestrator delegates to specialists
export const contentPipelineFlow = ai.defineFlow(
{
name: 'contentPipelineFlow',
inputSchema: z.object({ topic: z.string() }),
outputSchema: z.string(),
},
async ({ topic }) => {
const research = await researchAgent(`Research: ${topic}`);
const article = await writerAgent(`Write an article based on: ${research}`);
return article;
}
);
```
---
## Developer Tools
### CLI Commands
```bash
# Start Developer UI + connect to your app
genkit start -- npx tsx --watch src/index.ts
genkit start -o -- npx tsx src/index.ts # auto-open browser
# Run a specific flow from CLI
genkit flow:run summarizeFlow '{"text": "Hello world", "maxWords": 10}'
# Run with streaming output
genkit flow:run streamingFlow '{"topic": "AI"}' -s
# Evaluate a flow
genkit eval:flow ragFlow --input eval-inputs.json
# View all commands
genkit --help
# Disable analytics telemetry
genkit config set analyticsOptOut true
```
### Developer UI
The Developer UI runs at **http://localhost:4000** and provides:
- **Flow runner**: Execute flows with custom JSON inputs
- **Trace inspector**: Visualize each step (generate, embed, retrieve, tool calls)
- **Prompt playground**: Test prompts interactively
- **Model tester**: Compare outputs across different models
- **Evaluator**: Run evaluation datasets against flows
```bash
# Add npm script for convenience
# package.json
"scripts": {
"genkit:dev": "genkit start -- npx tsx --watch src/index.ts"
}
npm run genkit:dev
```
---
## Deployment
### Firebase Cloud Functions
```typescript
import { onCallGenkit } from 'firebase-functions/https';
import { defineSecret } from 'firebase-functions/params';
const apiKey = defineSecret('GOOGLE_AI_API_KEY');
export const summarize = onCallGenkit(
{ secrets: [apiKey] },
summarizeFlow
);
```
```bash
firebase deploy --only functions
```
### Express.js Server
```typescript
import express from 'express';
import { expressHandler } from 'genkit/express';
const app = express();
app.use(express.json());
app.post('/summarize', expressHandler(summarizeFlow));
app.post('/chat', expressHandler(chatFlow));
app.listen(3000, () => console.log('Server running on port 3000'));
```
### Cloud Run
```bash
# Build and deploy
gcloud run deploy genkit-app \
--source . \
--region us-central1 \
--set-env-vars GEMINI_API_KEY=$GEMINI_API_KEY
```
---
## Supported Plugins
### Model Providers
| Plugin | Package | Models |
|--------|---------|--------|
| Google AI | `@genkit-ai/google-genai` | Gemini 2.5 Flash/Pro |
| Vertex AI | `@genkit-ai/vertexai` | Gemini, Imagen, Claude |
| OpenAI | `genkitx-openai` | GPT-4o, o1, etc. |
| Anthropic | `genkitx-anthropic` | Claude 3.5/3 |
| AWS Bedrock | `genkitx-aws-bedrock` | Claude, Titan, etc. |
| Ollama | `genkitx-ollama` | Local models |
| DeepSeek | `genkitx-deepseek` | DeepSeek-R1 |
| xAI (Grok) | `genkitx-xai` | Grok models |
### Vector Databases
| Plugin | Package |
|--------|---------|
| Dev Local (testing) | `@genkit-ai/dev-local-vectorstore` |
| Pinecone | `genkitx-pinecone` |
| pgvector | `genkitx-pgvector` |
| Chroma | `genkitx-chroma` |
| Cloud Firestore | `@genkit-ai/firebase` |
| LanceDB | `genkitx-lancedb` |
---
## Best Practices
1. **Always define input/output schemas** — Use Zod objects for Dev UI labeled fields and API safety
2. **Use flows for all AI logic** — Even simple calls; flows give you tracing and deployment for free
3. **Store API keys in environment variables** — Never hardcode; use Firebase Secrets for production
4. **Use `ai.run()` to trace custom steps** — Wrap non-Genkit code in `ai.run()` for trace visibility
5. **Stream long-form content** — Use `defineFlow` with `streamSchema` + `sendChunk` for better UX
6. **Separate concerns with agents** — Specialized subflows > one monolithic flow
7. **Use Dotprompt for team prompts** — `.prompt` files enable versioning, review, and reuse
## Constraints
### Must Do
- Define schemas for all flow inputs and outputs
- Handle `null` output from `generate()` — throw meaningful errors
- Set `GENKIT_ENV=dev` when running flows separately from the dev server
- Use `onCallGenkit` (not raw Cloud Functions) when deploying to Firebase
### Must Not Do
- Never hardcode API keys in source code
- Do not use `generate()` outside a flow if you need tracing/observability
- Do not call `genkit start` without a command — always pass `-- <your-run-command>`
- Avoid blocking the event loop in tool handlers — use `async/await`
---
## References
- [Official Docs](https://genkit.dev/docs/overview/)
- [Get Started Guide](https://genkit.dev/docs/get-started/)
- [Developer Tools](https://genkit.dev/docs/devtools/)
- [Flows Reference](https://genkit.dev/docs/flows/)
- [Tool Calling](https://genkit.dev/docs/tool-calling/)
- [RAG Guide](https://genkit.dev/docs/rag/)
- [Multi-Agent Systems](https://genkit.dev/docs/multi-agent/)
- [Dotprompt](https://genkit.dev/docs/dotprompt/)
- [GitHub Repository](https://github.com/firebase/genkit)
- [API References](https://genkit.dev/docs/api-references/)
## Examples
### Example 1: Minimal Flow
```typescript
import { googleAI } from '@genkit-ai/google-genai';
import { genkit, z } from 'genkit';
const ai = genkit({ plugins: [googleAI()] });
export const helloFlow = ai.defineFlow(
{
name: 'helloFlow',
inputSchema: z.object({ name: z.string() }),
outputSchema: z.string(),
},
async ({ name }) => {
const { text } = await ai.generate(`Say hello to ${name} in a creative way.`);
return text;
}
);
// Run it
const greeting = await helloFlow({ name: 'World' });
console.log(greeting);
```
### Example 2: Full RAG + Agent Pipeline
```typescript
import { googleAI, textEmbedding004 } from '@genkit-ai/google-genai';
import { devLocalVectorstore } from '@genkit-ai/dev-local-vectorstore';
import { genkit, z } from 'genkit';
const ai = genkit({
plugins: [
googleAI(),
devLocalVectorstore([{ indexName: 'kb', embedder: textEmbedding004 }]),
],
});
// Index knowledge base documents
const indexKnowledgeBase = ai.defineFlow(
{ name: 'indexKB', inputSchema: z.array(z.string()) },
async (texts) => {
await ai.index({
indexer: devLocalVectorstoreIndexer('kb'),
docs: texts.map(text => ({ content: [{ text }] })),
});
}
);
// Answer questions using RAG
export const answerFlow = ai.defineFlow(
{
name: 'answerFlow',
inputSchema: z.object({ question: z.string() }),
outputSchema: z.object({ answer: z.string(), sources: z.number() }),
},
async ({ question }) => {
const docs = await ai.retrieve({
retriever: devLocalVectorstoreRetriever('kb'),
query: question,
options: { k: 5 },
});
const { text } = await ai.generate({
system: 'Answer only from the provided context. If unsure, say so.',
prompt: question,
docs,
});
return { answer: text, sources: docs.length };
}
);
```
### Example 3: Multi-Model Comparison
```typescript
import { googleAI } from '@genkit-ai/google-genai';
import { openAI } from 'genkitx-openai';
import { genkit, z } from 'genkit';
const ai = genkit({ plugins: [googleAI(), openAI()] });
export const compareModelsFlow = ai.defineFlow(
{
name: 'compareModelsFlow',
inputSchema: z.object({ prompt: z.string() }),
outputSchema: z.object({ gemini: z.string(), gpt4o: z.string() }),
},
async ({ prompt }) => {
const [geminiResult, gptResult] = await Promise.all([
ai.generate({ model: googleAI.model('gemini-2.5-flash'), prompt }),
ai.generate({ model: 'openai/gpt-4o', prompt }),
]);
return {
gemini: geminiResult.text,
gpt4o: gptResult.text,
};
}
);
```