|
| 1 | +# Firebase Genkit + Anthropic AI |
| 2 | + |
| 3 | +<h1 align="center">Firebase Genkit <> Anthropic AI Plugin</h1> |
| 4 | + |
| 5 | +<h4 align="center">Anthropic AI plugin for Google Firebase Genkit</h4> |
| 6 | + |
| 7 | +`@genkit-ai/anthropic` is the official Anthropic plugin for [Firebase Genkit](https://github.com/firebase/genkit). It supersedes the earlier community package `genkitx-anthropic` and is now maintained by Google. |
| 8 | + |
| 9 | +## Supported models |
| 10 | + |
| 11 | +The plugin supports the most recent Anthropic models: **Claude Sonnet 4.5**, **Claude Opus 4.1**, **Claude Haiku 4.5**, **Claude Sonnet 4**, **Claude Opus 4**, **Claude 3.5 Haiku**, and **Claude 3 Haiku**. |
| 12 | + |
| 13 | +## Installation |
| 14 | + |
| 15 | +Install the plugin in your project with your favorite package manager: |
| 16 | + |
| 17 | +- `npm install @genkit-ai/anthropic` |
| 18 | +- `yarn add @genkit-ai/anthropic` |
| 19 | +- `pnpm add @genkit-ai/anthropic` |
| 20 | + |
| 21 | +## Usage |
| 22 | + |
| 23 | +### Initialize |
| 24 | + |
| 25 | +```typescript |
| 26 | +import { genkit } from 'genkit'; |
| 27 | +import { anthropic } from '@genkit-ai/anthropic'; |
| 28 | + |
| 29 | +const ai = genkit({ |
| 30 | + plugins: [anthropic({ apiKey: process.env.ANTHROPIC_API_KEY })], |
| 31 | + // specify a default model for generate here if you wish: |
| 32 | + model: anthropic.model('claude-sonnet-4-5'), |
| 33 | +}); |
| 34 | +``` |
| 35 | + |
| 36 | +### Basic examples |
| 37 | + |
| 38 | +The simplest way to generate text is by using the `generate` method: |
| 39 | + |
| 40 | +```typescript |
| 41 | +const response = await ai.generate({ |
| 42 | + model: anthropic.model('claude-3-haiku'), |
| 43 | + prompt: 'Tell me a joke.', |
| 44 | +}); |
| 45 | + |
| 46 | +console.log(response.text); |
| 47 | +``` |
| 48 | + |
| 49 | +### Multi-modal prompt |
| 50 | + |
| 51 | +```typescript |
| 52 | +// ...initialize Genkit instance (as shown above)... |
| 53 | + |
| 54 | +const response = await ai.generate({ |
| 55 | + prompt: [ |
| 56 | + { text: 'What animal is in the photo?' }, |
| 57 | + { media: { url: imageUrl } }, |
| 58 | + ], |
| 59 | + config: { |
| 60 | + // control of the level of visual detail when processing image embeddings |
| 61 | + // Low detail level also decreases the token usage |
| 62 | + visualDetailLevel: 'low', |
| 63 | + }, |
| 64 | +}); |
| 65 | +console.log(response.text); |
| 66 | +``` |
| 67 | + |
| 68 | +### Extended thinking |
| 69 | + |
| 70 | +Claude 4 models can expose their internal reasoning. Enable it per-request with the Anthropic thinking config and read the reasoning from the response: |
| 71 | + |
| 72 | +```typescript |
| 73 | +const response = await ai.generate({ |
| 74 | + prompt: 'Walk me through your reasoning for Fermat’s little theorem.', |
| 75 | + config: { |
| 76 | + thinking: { |
| 77 | + enabled: true, |
| 78 | + budgetTokens: 4096, // Must be >= 1024 and less than max_tokens |
| 79 | + }, |
| 80 | + }, |
| 81 | +}); |
| 82 | + |
| 83 | +console.log(response.text); // Final assistant answer |
| 84 | +console.log(response.reasoning); // Summarized thinking steps |
| 85 | +``` |
| 86 | + |
| 87 | +When thinking is enabled, request bodies sent through the plugin include the `thinking` payload (`{ type: 'enabled', budget_tokens: … }`) that Anthropic's API expects, and streamed responses deliver `reasoning` parts as they arrive so you can render the chain-of-thought incrementally. |
| 88 | + |
| 89 | +### Beta API Limitations |
| 90 | + |
| 91 | +The beta API surface provides access to experimental features, but some server-managed tool blocks are not yet supported by this plugin. The following beta API features will cause an error if encountered: |
| 92 | + |
| 93 | +- `web_fetch_tool_result` |
| 94 | +- `code_execution_tool_result` |
| 95 | +- `bash_code_execution_tool_result` |
| 96 | +- `text_editor_code_execution_tool_result` |
| 97 | +- `mcp_tool_result` |
| 98 | +- `mcp_tool_use` |
| 99 | +- `container_upload` |
| 100 | + |
| 101 | +Note that `server_tool_use` and `web_search_tool_result` ARE supported and work with both stable and beta APIs. |
| 102 | + |
| 103 | +### Within a flow |
| 104 | + |
| 105 | +```typescript |
| 106 | +import { z } from 'genkit'; |
| 107 | + |
| 108 | +// ...initialize Genkit instance (as shown above)... |
| 109 | + |
| 110 | +export const jokeFlow = ai.defineFlow( |
| 111 | + { |
| 112 | + name: 'jokeFlow', |
| 113 | + inputSchema: z.string(), |
| 114 | + outputSchema: z.string(), |
| 115 | + }, |
| 116 | + async (subject) => { |
| 117 | + const llmResponse = await ai.generate({ |
| 118 | + prompt: `tell me a joke about ${subject}`, |
| 119 | + }); |
| 120 | + return llmResponse.text; |
| 121 | + } |
| 122 | +); |
| 123 | +``` |
| 124 | + |
| 125 | +### Direct model usage (without Genkit instance) |
| 126 | + |
| 127 | +The plugin supports Genkit Plugin API v2, which allows you to use models directly without initializing the full Genkit framework: |
| 128 | + |
| 129 | +```typescript |
| 130 | +import { anthropic } from '@genkit-ai/anthropic'; |
| 131 | + |
| 132 | +// Create a model reference directly |
| 133 | +const claude = anthropic.model('claude-sonnet-4-5'); |
| 134 | + |
| 135 | +// Use the model directly |
| 136 | +const response = await claude({ |
| 137 | + messages: [ |
| 138 | + { |
| 139 | + role: 'user', |
| 140 | + content: [{ text: 'Tell me a joke.' }], |
| 141 | + }, |
| 142 | + ], |
| 143 | +}); |
| 144 | + |
| 145 | +console.log(response); |
| 146 | +``` |
| 147 | + |
| 148 | +You can also create model references using the plugin's `model()` method: |
| 149 | + |
| 150 | +```typescript |
| 151 | +import { anthropic } from '@genkit-ai/anthropic'; |
| 152 | + |
| 153 | +// Create model references |
| 154 | +const claudeSonnet45 = anthropic.model('claude-sonnet-4-5'); |
| 155 | +const claudeOpus41 = anthropic.model('claude-opus-4-1'); |
| 156 | +const claude35Haiku = anthropic.model('claude-3-5-haiku'); |
| 157 | + |
| 158 | +// Use the model reference directly |
| 159 | +const response = await claudeSonnet45({ |
| 160 | + messages: [ |
| 161 | + { |
| 162 | + role: 'user', |
| 163 | + content: [{ text: 'Hello!' }], |
| 164 | + }, |
| 165 | + ], |
| 166 | +}); |
| 167 | +``` |
| 168 | + |
| 169 | +This approach is useful for: |
| 170 | + |
| 171 | +- Framework developers who need raw model access |
| 172 | +- Testing models in isolation |
| 173 | +- Using Genkit models in non-Genkit applications |
| 174 | + |
| 175 | +## Acknowledgements |
| 176 | + |
| 177 | +This plugin builds on the community work published as [`genkitx-anthropic`](https://github.com/BloomLabsInc/genkit-plugins/blob/main/plugins/anthropic/README.md) by Bloom Labs Inc. Their Apache 2.0–licensed implementation provided the foundation for this maintained package. |
| 178 | + |
| 179 | +## Contributing |
| 180 | + |
| 181 | +Want to contribute to the project? That's awesome! Head over to our [Contribution Guidelines](CONTRIBUTING.md). |
| 182 | + |
| 183 | +## Need support? |
| 184 | + |
| 185 | +> [!NOTE] |
| 186 | +> This repository depends on Google's Firebase Genkit. For issues and questions related to Genkit, please refer to instructions available in [Genkit's repository](https://github.com/firebase/genkit). |
| 187 | +
|
| 188 | + |
| 189 | +## Credits |
| 190 | + |
| 191 | +This plugin is maintained by Google with acknowledgement to the community contributions from [Bloom Labs Inc](https://github.com/BloomLabsInc). |
| 192 | + |
| 193 | +## License |
| 194 | + |
| 195 | +This project is licensed under the [Apache 2.0 License](https://github.com/BloomLabsInc/genkit-plugins/blob/main/LICENSE). |
0 commit comments