mirror of
https://github.com/run-llama/LlamaIndexTS.git
synced 2026-07-03 19:19:08 -04:00
Compare commits
38 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 63c8bc2b8d | |||
| 3e66ddc10d | |||
| c719b968f3 | |||
| c73c659c6d | |||
| 361a685012 | |||
| 680b529e94 | |||
| 389acbd307 | |||
| 2e181be160 | |||
| 7a7ca604c5 | |||
| c2fd4f9fc1 | |||
| 40f5f410c0 | |||
| d671ed6d25 | |||
| 76c9a80057 | |||
| 46a416517c | |||
| 168d11fe51 | |||
| 3dfa5eb9ff | |||
| 9b20859dc5 | |||
| 93691793c5 | |||
| 3b231cf11c | |||
| 7073fca171 | |||
| 9145577bf5 | |||
| 4a18a2eb3d | |||
| 206b491724 | |||
| 9b2e25a184 | |||
| b29521bf6c | |||
| 73e25787e7 | |||
| 3ce80540fe | |||
| dbc1ee3089 | |||
| 3b45191228 | |||
| aaf2f8b2db | |||
| 6ddf1c1b1f | |||
| a8717d5ece | |||
| 7e8e4549f2 | |||
| cc3fe92a22 | |||
| 63ab0dba4e | |||
| 2225ffd1d4 | |||
| bc5334249b | |||
| 41953a3ef9 |
@@ -0,0 +1,6 @@
|
||||
---
|
||||
"@llamaindex/workflow": patch
|
||||
"@llamaindex/core": patch
|
||||
---
|
||||
|
||||
Remove requireContext from tools - better use binding to pass context
|
||||
@@ -0,0 +1,5 @@
|
||||
---
|
||||
"@llamaindex/qdrant": patch
|
||||
---
|
||||
|
||||
Update implementation to use query instead of search which is being deprecated
|
||||
@@ -0,0 +1,6 @@
|
||||
---
|
||||
"llamaindex": minor
|
||||
"@llamaindex/core": patch
|
||||
---
|
||||
|
||||
Remove old workflows - use @llamaindex/workflow package
|
||||
@@ -0,0 +1,6 @@
|
||||
---
|
||||
"@llamaindex/azure": patch
|
||||
"@llamaindex/openai": minor
|
||||
---
|
||||
|
||||
Move Azure models to azure package
|
||||
@@ -23,7 +23,7 @@ jobs:
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
node-version: [18.x, 20.x, 22.x, 23.x]
|
||||
node-version: [20.x, 22.x, 23.x]
|
||||
name: E2E on Node.js ${{ matrix.node-version }}
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
@@ -53,7 +53,7 @@ jobs:
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
node-version: [18.x, 20.x, 22.x, 23.x]
|
||||
node-version: [20.x, 22.x, 23.x]
|
||||
name: Test on Node.js ${{ matrix.node-version }}
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
@@ -87,6 +87,30 @@ jobs:
|
||||
run: pnpm run type-check
|
||||
- name: Run Circular Dependency Check
|
||||
run: pnpm run circular-check
|
||||
e2e-npm:
|
||||
runs-on: ubuntu-latest
|
||||
name: Test using packages with npm
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: pnpm/action-setup@v4
|
||||
- name: Setup Node.js
|
||||
uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version-file: ".nvmrc"
|
||||
- name: Install dependencies
|
||||
run: pnpm install
|
||||
- name: Build packages
|
||||
run: pnpm run build
|
||||
- name: Pack packages
|
||||
run: |
|
||||
pnpm pack --pack-destination ${{ runner.temp }} -C packages/llamaindex
|
||||
pnpm pack --pack-destination ${{ runner.temp }} -C packages/workflow
|
||||
- name: Install packed packages
|
||||
run: npm add ${{ runner.temp }}/*.tgz
|
||||
working-directory: e2e/npm
|
||||
- name: Run tests
|
||||
run: npm test
|
||||
working-directory: e2e/npm
|
||||
e2e-llamaindex-examples:
|
||||
strategy:
|
||||
fail-fast: false
|
||||
|
||||
@@ -7,9 +7,10 @@
|
||||
</h3>
|
||||
|
||||
[](https://www.npmjs.com/package/llamaindex)
|
||||
[](https://www.npmjs.com/package/llamaindex)
|
||||
[](https://github.com/run-llama/LlamaIndexTS/blob/main/LICENSE)
|
||||
[](https://www.npmjs.com/package/llamaindex)
|
||||
[](https://discord.com/invite/eN6D2HQ4aX)
|
||||
[](https://x.com/llama_index)
|
||||
|
||||
Use your own data with large language models (LLMs, OpenAI ChatGPT and others) in JS runtime environments with TypeScript support.
|
||||
|
||||
@@ -63,7 +64,7 @@ yarn add llamaindex
|
||||
|
||||
### Setup in Node.js, Deno, Bun, TypeScript...?
|
||||
|
||||
See our official document: <https://ts.llamaindex.ai/docs/llamaindex/getting_started/>
|
||||
See our official document: https://ts.llamaindex.ai/docs/llamaindex/getting_started
|
||||
|
||||
### Adding provider packages
|
||||
|
||||
@@ -83,19 +84,7 @@ Check out our NextJS playground at https://llama-playground.vercel.app/. The sou
|
||||
|
||||
## Core concepts for getting started:
|
||||
|
||||
- [Document](/packages/llamaindex/src/Node.ts): A document represents a text file, PDF file or other contiguous piece of data.
|
||||
|
||||
- [Node](/packages/llamaindex/src/Node.ts): The basic data building block. Most commonly, these are parts of the document split into manageable pieces that are small enough to be fed into an embedding model and LLM.
|
||||
|
||||
- [Embedding](/packages/llamaindex/src/embeddings/OpenAIEmbedding.ts): Embeddings are sets of floating point numbers which represent the data in a Node. By comparing the similarity of embeddings, we can derive an understanding of the similarity of two pieces of data. One use case is to compare the embedding of a question with the embeddings of our Nodes to see which Nodes may contain the data needed to answer that question. Because the default service context is OpenAI, the default embedding is `OpenAIEmbedding`. If using different models, say through Ollama, use this [Embedding](/packages/llamaindex/src/embeddings/OllamaEmbedding.ts) (see all [here](/packages/llamaindex/src/embeddings)).
|
||||
|
||||
- [Indices](/packages/llamaindex/src/indices/): Indices store the Nodes and the embeddings of those nodes. QueryEngines retrieve Nodes from these Indices using embedding similarity.
|
||||
|
||||
- [QueryEngine](/packages/llamaindex/src/engines/query/RetrieverQueryEngine.ts): Query engines are what generate the query you put in and give you back the result. Query engines generally combine a pre-built prompt with selected Nodes from your Index to give the LLM the context it needs to answer your query. To build a query engine from your Index (recommended), use the [`asQueryEngine`](/packages/llamaindex/src/indices/BaseIndex.ts) method on your Index. See all query engines [here](/packages/llamaindex/src/engines/query).
|
||||
|
||||
- [ChatEngine](/packages/llamaindex/src/engines/chat/SimpleChatEngine.ts): A ChatEngine helps you build a chatbot that will interact with your Indices. See all chat engines [here](/packages/llamaindex/src/engines/chat).
|
||||
|
||||
- [SimplePrompt](/packages/llamaindex/src/Prompt.ts): A simple standardized function call definition that takes in inputs and formats them in a template literal. SimplePrompts can be specialized using currying and combined using other SimplePrompt functions.
|
||||
See our documentation: https://ts.llamaindex.ai/docs/llamaindex/getting_started/concepts
|
||||
|
||||
## Contributing:
|
||||
|
||||
|
||||
@@ -1,5 +1,48 @@
|
||||
# @llamaindex/doc
|
||||
|
||||
## 0.2.18
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- d671ed6: Add functionality for search params when querying Qdrant vector store.
|
||||
- Updated dependencies [76c9a80]
|
||||
- Updated dependencies [168d11f]
|
||||
- Updated dependencies [d671ed6]
|
||||
- Updated dependencies [40f5f41]
|
||||
- @llamaindex/openai@0.3.7
|
||||
- @llamaindex/workflow@1.1.2
|
||||
- @llamaindex/core@0.6.5
|
||||
- @llamaindex/cloud@4.0.7
|
||||
- llamaindex@0.10.6
|
||||
- @llamaindex/node-parser@2.0.5
|
||||
- @llamaindex/readers@3.1.3
|
||||
|
||||
## 0.2.17
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [9b2e25a]
|
||||
- @llamaindex/openai@0.3.6
|
||||
- @llamaindex/core@0.6.4
|
||||
- llamaindex@0.10.5
|
||||
- @llamaindex/cloud@4.0.6
|
||||
- @llamaindex/node-parser@2.0.4
|
||||
- @llamaindex/readers@3.1.2
|
||||
- @llamaindex/workflow@1.1.1
|
||||
|
||||
## 0.2.16
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [7e8e454]
|
||||
- Updated dependencies [2225ffd]
|
||||
- Updated dependencies [6ddf1c1]
|
||||
- Updated dependencies [bc53342]
|
||||
- Updated dependencies [41953a3]
|
||||
- @llamaindex/workflow@1.1.0
|
||||
- @llamaindex/cloud@4.0.5
|
||||
- llamaindex@0.10.4
|
||||
|
||||
## 0.2.15
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@llamaindex/doc",
|
||||
"version": "0.2.15",
|
||||
"version": "0.2.18",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"postinstall": "fumadocs-mdx",
|
||||
@@ -15,7 +15,7 @@
|
||||
"dependencies": {
|
||||
"@huggingface/transformers": "^3.5.0",
|
||||
"@icons-pack/react-simple-icons": "^10.1.0",
|
||||
"@llama-flow/docs": "0.0.5",
|
||||
"@llama-flow/docs": "0.0.8",
|
||||
"@llamaindex/chat-ui": "0.2.0",
|
||||
"@llamaindex/cloud": "workspace:*",
|
||||
"@llamaindex/core": "workspace:*",
|
||||
|
||||
@@ -4,7 +4,6 @@ import matter from "gray-matter";
|
||||
import path from "path";
|
||||
|
||||
const CONTENT_DIR = path.join(process.cwd(), "src/content/docs");
|
||||
const BUILD_DIR = path.join(process.cwd(), ".next");
|
||||
|
||||
// Regular expression to find internal links
|
||||
// This captures Markdown links [text](/docs/path) and href attributes href="/docs/path"
|
||||
@@ -14,6 +13,8 @@ const INTERNAL_LINK_REGEX = /(?:(?:\]\(|\bhref=["'])\/docs\/([^")]+))/g;
|
||||
// This captures relative links like [text](./path) or 
|
||||
const RELATIVE_LINK_REGEX = /(?:\]\()(?:\s*)(?:\.\.?)\//g;
|
||||
|
||||
const ALLOWED_LINKS = ["/docs/llamaflow"];
|
||||
|
||||
interface LinkValidationResult {
|
||||
file: string;
|
||||
invalidLinks: Array<{ link: string; line: number }>;
|
||||
@@ -28,7 +29,7 @@ interface RelativeLinkResult {
|
||||
* Get all valid documentation routes from the content directory
|
||||
*/
|
||||
async function getValidRoutes(): Promise<Set<string>> {
|
||||
const mdxFiles = await glob("**/*.mdx?", { cwd: CONTENT_DIR });
|
||||
const mdxFiles = await glob("**/*.{md,mdx}", { cwd: CONTENT_DIR });
|
||||
|
||||
const routes = new Set<string>();
|
||||
|
||||
@@ -124,14 +125,11 @@ function findRelativeLinksInFile(
|
||||
return relativeLinks;
|
||||
}
|
||||
|
||||
/**
|
||||
* Validate internal links in all MDX files
|
||||
*/
|
||||
/**
|
||||
* Find relative links in all MDX files
|
||||
*/
|
||||
async function findRelativeLinks(): Promise<RelativeLinkResult[]> {
|
||||
const mdxFiles = await glob("**/*.mdx?", { cwd: CONTENT_DIR });
|
||||
const mdxFiles = await glob("**/*.mdx", { cwd: CONTENT_DIR });
|
||||
const results: RelativeLinkResult[] = [];
|
||||
|
||||
for (const file of mdxFiles) {
|
||||
@@ -150,7 +148,7 @@ async function findRelativeLinks(): Promise<RelativeLinkResult[]> {
|
||||
}
|
||||
|
||||
async function validateLinks(): Promise<LinkValidationResult[]> {
|
||||
const mdxFiles = await glob("**/*.mdx?", { cwd: CONTENT_DIR });
|
||||
const mdxFiles = await glob("**/*.mdx", { cwd: CONTENT_DIR });
|
||||
const validRoutes = await getValidRoutes();
|
||||
|
||||
const results: LinkValidationResult[] = [];
|
||||
@@ -160,6 +158,11 @@ async function validateLinks(): Promise<LinkValidationResult[]> {
|
||||
const links = extractLinksFromFile(filePath);
|
||||
|
||||
const invalidLinks = links.filter(({ link }) => {
|
||||
// Check if the link is in the allowed list
|
||||
if (ALLOWED_LINKS.includes(`/docs/${link}`)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Check if the link exists in valid routes
|
||||
// First normalize the link (remove any query string or hash)
|
||||
const baseLink = link.split("?")[0].split("#")[0];
|
||||
|
||||
@@ -26,7 +26,7 @@ const llm = openai();
|
||||
const response = await llm.chat({
|
||||
messages: [{ content: "Tell me a joke.", role: "user" }],
|
||||
});`,
|
||||
`import { agent } from "llamaindex";
|
||||
`import { agent } from "@llamaindex/workflow";
|
||||
import { openai } from "@llamaindex/openai";
|
||||
|
||||
const analyseAgent = agent({
|
||||
@@ -36,7 +36,7 @@ const analyseAgent = agent({
|
||||
});
|
||||
const response = await analyseAgent.run(\`Analyse the given data:
|
||||
\${data}\`);`,
|
||||
`import { agent, multiAgent } from "llamaindex";
|
||||
`import { agent, multiAgent } from "@llamaindex/workflow";
|
||||
import { openai } from "@llamaindex/openai";
|
||||
|
||||
const analyseAgent = agent({
|
||||
@@ -113,8 +113,9 @@ export default function HomePage() {
|
||||
description="Truly powerful retrieval-augmented generation applications use agentic techniques, and LlamaIndex.TS makes it easy to build them."
|
||||
>
|
||||
<CodeBlock
|
||||
code={`import { agent, SimpleDirectoryReader, VectorStoreIndex } from "llamaindex";
|
||||
code={`import { SimpleDirectoryReader, VectorStoreIndex } from "llamaindex";
|
||||
import { openai } from "@llamaindex/openai";
|
||||
import { agent } from "@llamaindex/workflow";
|
||||
|
||||
// load documents from current directoy into an index
|
||||
const reader = new SimpleDirectoryReader();
|
||||
|
||||
@@ -0,0 +1,60 @@
|
||||
---
|
||||
title: High-Level Concepts
|
||||
---
|
||||
|
||||
This is a quick guide to the high-level concepts you'll encounter frequently when building LLM applications.
|
||||
|
||||
## Large Language Models (LLMs)
|
||||
|
||||
LLMs are the fundamental innovation that launched LlamaIndex. They are an artificial intelligence (AI) computer system that can understand, generate, and manipulate natural language, including answering questions based on their training data or data provided to them at query time.
|
||||
|
||||
## Agentic Applications
|
||||
|
||||
When an LLM is used within an application, it is often used to make decisions, take actions, and/or interact with the world. This is the core definition of an **agentic application**.
|
||||
|
||||
While the definition of an agentic application is broad, there are several key characteristics that define an agentic application:
|
||||
|
||||
- **LLM Augmentation**: The LLM is augmented with tools (i.e. arbitrary callable functions in code), memory, and/or dynamic prompts.
|
||||
- **Prompt Chaining**: Several LLM calls are used that build on each other, with the output of one LLM call being used as the input to the next.
|
||||
- **Routing**: The LLM is used to route the application to the next appropriate step or state in the application.
|
||||
- **Parallelism**: The application can perform multiple steps or actions in parallel.
|
||||
- **Orchestration**: A hierarchical structure of LLMs is used to orchestrate lower-level actions and LLMs.
|
||||
- **Reflection**: The LLM is used to reflect and validate outputs of previous steps or LLM calls, which can be used to guide the application to the next appropriate step or state.
|
||||
|
||||
In LlamaIndex, you can build agentic applications by using the workflows to orchestrate a sequence of steps and LLMs. You can [learn more about workflows](/docs/llamaindex/tutorials/workflows).
|
||||
|
||||
## Agents
|
||||
|
||||
We define an agent as a specific instance of an "agentic application". An agent is a piece of software that semi-autonomously performs tasks by combining LLMs with other tools and memory, orchestrated in a reasoning loop that decides which tool to use next (if any).
|
||||
|
||||
What this means in practice, is something like:
|
||||
- An agent receives a user message
|
||||
- The agent uses an LLM to determine the next appropriate action to take using the previous chat history, tools, and the latest user message
|
||||
- The agent may invoke one or more tools to assist in the users request
|
||||
- If tools are used, the agent will then interpret the tool outputs and use them to inform the next action
|
||||
- Once the agent stops taking actions, it returns the final output to the user
|
||||
|
||||
You can [learn more about agents](/docs/llamaindex/tutorials/basic_agent).
|
||||
|
||||
## Retrieval Augmented Generation (RAG)
|
||||
|
||||
Retrieval-Augmented Generation (RAG) is a core technique for building data-backed LLM applications with LlamaIndex. It allows LLMs to answer questions about your private data by providing it to the LLM at query time, rather than training the LLM on your data. To avoid sending **all** of your data to the LLM every time, RAG indexes your data and selectively sends only the relevant parts along with your query. You can [learn more about RAG](/docs/llamaindex/tutorials/rag).
|
||||
|
||||
## Use cases
|
||||
|
||||
There are endless use cases for data-backed LLM applications but they can be roughly grouped into four categories:
|
||||
|
||||
[**Agents**](/docs/llamaindex/tutorials/basic_agent):
|
||||
An agent is an automated decision-maker powered by an LLM that interacts with the world via a set of [tools](/docs/llamaindex/modules/agents/tool). Agents can take an arbitrary number of steps to complete a given task, dynamically deciding on the best course of action rather than following pre-determined steps. This gives it additional flexibility to tackle more complex tasks.
|
||||
|
||||
[**Workflows**](/docs/llamaindex/tutorials/workflows):
|
||||
A Workflow in LlamaIndex is a specific event-driven abstraction that allows you to orchestrate a sequence of steps and LLMs calls. Workflows can be used to implement any agentic application, and are a core component of LlamaIndex.
|
||||
|
||||
[**Structured Data Extraction**](/docs/llamaindex/tutorials/structured_data_extraction):
|
||||
Pydantic extractors allow you to specify a precise data structure to extract from your data and use LLMs to fill in the missing pieces in a type-safe way. This is useful for extracting structured data from unstructured sources like PDFs, websites, and more, and is key to automating workflows.
|
||||
|
||||
[**Query Engines**](/docs/llamaindex/modules/rag/query_engines):
|
||||
A query engine is an end-to-end flow that allows you to ask questions over your data. It takes in a natural language query, and returns a response, along with reference context retrieved and passed to the LLM.
|
||||
|
||||
[**Chat Engines**](/docs/llamaindex/modules/rag/chat_engine):
|
||||
A chat engine is an end-to-end flow for having a conversation with your data (multiple back-and-forth instead of a single question-and-answer).
|
||||
@@ -9,10 +9,10 @@ To install llamaindex, run the following command:
|
||||
npm i llamaindex
|
||||
```
|
||||
|
||||
In most cases, you'll also need an LLM package to use LlamaIndex. For example, to use the OpenAI LLM, you would install the following:
|
||||
In most cases, you'll also need an LLM package and the Workflow package to use LlamaIndex. For example, to use the OpenAI LLM with agents, you would install the following:
|
||||
|
||||
```package-install
|
||||
npm i @llamaindex/openai
|
||||
npm i @llamaindex/openai @llamaindex/workflow
|
||||
```
|
||||
|
||||
Go to [LLM APIs](/docs/llamaindex/modules/models/llms) to find out how to use other LLMs.
|
||||
|
||||
@@ -40,19 +40,7 @@ Make sure to set [moduleResolution](https://www.typescriptlang.org/docs/handbook
|
||||
}
|
||||
```
|
||||
|
||||
We recommend using `bundler` or `nodenext`, but due to popularity of `node`, we still added support for it, but with import path limitations.
|
||||
|
||||
So you may encounter type errors when importing sub paths from the `llamaindex` package like:
|
||||
|
||||
```ts
|
||||
import { Settings } from "llamaindex";
|
||||
```
|
||||
|
||||
The simplest way to fix this without changing `moduleResolution` is to import directly from `llamaindex`:
|
||||
|
||||
```ts
|
||||
import { Settings } from "llamaindex";
|
||||
```
|
||||
We recommend using `bundler` or `nodenext`, but due to popularity of `node`, we still added support for it.
|
||||
|
||||
## Enable AsyncIterable for `Web Stream` API
|
||||
|
||||
@@ -68,7 +56,8 @@ Some modules uses `Web Stream` API like `ReadableStream` and `WritableStream`, y
|
||||
```
|
||||
|
||||
```typescript
|
||||
import { agent, tool } from 'llamaindex'
|
||||
import { tool } from 'llamaindex'
|
||||
import { agent } from "@llamaindex/workflow";
|
||||
import { openai } from "@llamaindex/openai";
|
||||
|
||||
Settings.llm = openai({
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
{
|
||||
"title": "Getting Started",
|
||||
"pages": ["installation", "create_llama", "examples"]
|
||||
"pages": ["concepts", "installation", "create_llama", "examples"]
|
||||
}
|
||||
|
||||
@@ -12,7 +12,8 @@ Agent Workflows are a powerful system that enables you to create and orchestrate
|
||||
The simplest use case is creating a single agent with specific tools. Here's an example of creating an assistant that tells jokes:
|
||||
|
||||
```typescript
|
||||
import { agent, tool } from "llamaindex";
|
||||
import { tool } from "llamaindex";
|
||||
import { agent } from "@llamaindex/workflow";
|
||||
import { openai } from "@llamaindex/openai";
|
||||
|
||||
// Define a joke-telling tool
|
||||
@@ -40,17 +41,17 @@ console.log(result); // Baby Llama is called cria
|
||||
Agent Workflows provide a unified interface for event streaming, making it easy to track and respond to different events during execution:
|
||||
|
||||
```typescript
|
||||
import { AgentToolCall, AgentStream } from "llamaindex";
|
||||
import { agentToolCallEvent, agentStreamEvent } from "@llamaindex/workflow";
|
||||
|
||||
// Get the workflow execution context
|
||||
const context = workflow.run("Tell me something funny");
|
||||
const events = workflow.runStream("Tell me something funny");
|
||||
|
||||
// Stream and handle events
|
||||
for await (const event of context) {
|
||||
if (event instanceof AgentToolCall) {
|
||||
for await (const event of events) {
|
||||
if (agentToolCallEvent.include(event)) {
|
||||
console.log(`Tool being called: ${event.data.toolName}`);
|
||||
}
|
||||
if (event instanceof AgentStream) {
|
||||
if (agentStreamEvent.include(event)) {
|
||||
process.stdout.write(event.data.delta);
|
||||
}
|
||||
}
|
||||
@@ -68,7 +69,8 @@ An Agent Workflow can orchestrate multiple agents, enabling complex interactions
|
||||
Here's an example of a multi-agent system that combines joke-telling and weather information:
|
||||
|
||||
```typescript
|
||||
import { multiAgent, agent, tool } from "llamaindex";
|
||||
import { tool } from "llamaindex";
|
||||
import { multiAgent, agent } from "@llamaindex/workflow";
|
||||
import { openai } from "@llamaindex/openai";
|
||||
import { z } from "zod";
|
||||
|
||||
|
||||
@@ -17,7 +17,8 @@ The `parameters` field in the tool configuration is defined using `zod`, a TypeS
|
||||
|
||||
Example:
|
||||
```ts
|
||||
import { agent, tool } from "llamaindex";
|
||||
import { tool } from "llamaindex";
|
||||
import { agent } from "@llamaindex/workflow";
|
||||
import { z } from "zod";
|
||||
|
||||
// first arg is LLM input, second is bound arg
|
||||
@@ -46,7 +47,7 @@ In this example, `z.object` is used to define a schema for the `parameters` wher
|
||||
You can import built-in tools from the `@llamaindex/tools` package.
|
||||
|
||||
```ts
|
||||
import { agent } from "llamaindex";
|
||||
import { agent } from "@llamaindex/workflow";
|
||||
import { wiki } from "@llamaindex/tools";
|
||||
|
||||
const researchAgent = agent({
|
||||
@@ -64,7 +65,7 @@ If you have a MCP server running, you can fetch tools from the server and use th
|
||||
```ts
|
||||
// 1. Import MCP tools adapter
|
||||
import { mcp } from "@llamaindex/tools";
|
||||
import { agent } from "llamaindex";
|
||||
import { agent } from "@llamaindex/workflow";
|
||||
|
||||
// 2. Initialize a MCP client
|
||||
// by npx
|
||||
@@ -114,7 +115,8 @@ Note: calling the `bind` method will return a new `FunctionTool` instance, witho
|
||||
|
||||
Example to pass a `userToken` as additional argument:
|
||||
```ts
|
||||
import { agent, tool } from "llamaindex";
|
||||
import { tool } from "llamaindex";
|
||||
import { agent } from "@llamaindex/workflow";
|
||||
|
||||
// first arg is LLM input, second is bound arg
|
||||
const queryKnowledgeBase = async ({ question }, { userToken }) => {
|
||||
|
||||
@@ -6,256 +6,13 @@ A `Workflow` in LlamaIndex is a lightweight, event-driven abstraction used to ch
|
||||
|
||||
Workflows are designed to be flexible and can be used to build agents, RAG flows, extraction flows, or anything else you want to implement.
|
||||
|
||||
To use workflows install this package:
|
||||
|
||||
```package-install
|
||||
npm i @llama-flow/core @llamaindex/openai
|
||||
npm i @llamaindex/workflow
|
||||
```
|
||||
|
||||
## Getting Started
|
||||
This package is a stable, production-ready version of our [llama-flow](/docs/llamaflow) project.
|
||||
|
||||
Let's explore a simple workflow example where a joke is generated and then critiqued and iterated on:
|
||||
While you can still reference the llama-flow documentation for detailed information about the underlying concepts, we recommend using the `@llamaindex/workflow` package for all new projects to ensure stability and long-term availability.
|
||||
|
||||
```typescript
|
||||
import { OpenAI } from "@llamaindex/openai";
|
||||
import { createWorkflow, workflowEvent } from "@llama-flow/core";
|
||||
import { withStore } from "@llama-flow/core/middleware/store";
|
||||
|
||||
// Create LLM instance
|
||||
const llm = new OpenAI({ model: "gpt-4.1-mini", apiKey: "..."});
|
||||
|
||||
// Define our workflow events
|
||||
const startEvent = workflowEvent<string>(); // Input topic for joke
|
||||
const jokeEvent = workflowEvent<{ joke: string }>(); // Intermediate joke
|
||||
const critiqueEvent = workflowEvent<{ joke: string, critique: string }>(); // Intermediate critique
|
||||
const resultEvent = workflowEvent<{ joke: string, critique: string }>(); // Final joke + critique
|
||||
|
||||
// Create our workflow
|
||||
const jokeFlow = withStore(
|
||||
() => ({
|
||||
numIterations: 0,
|
||||
maxIterations: 3,
|
||||
}),
|
||||
createWorkflow()
|
||||
);
|
||||
|
||||
// Define handlers for each step
|
||||
jokeFlow.handle([startEvent], async (event) => {
|
||||
// Prompt the LLM to write a joke
|
||||
const prompt = `Write your best joke about ${event.data}. Write the joke between <joke> and </joke> tags.`;
|
||||
const response = await llm.complete({ prompt });
|
||||
|
||||
// Parse the joke from the response
|
||||
const joke = response.text.match(/<joke>([\s\S]*?)<\/joke>/)?.[1]?.trim() ?? response.text;
|
||||
return jokeEvent.with({ joke: joke });
|
||||
});
|
||||
|
||||
jokeFlow.handle([jokeEvent], async (event) => {
|
||||
// Prompt the LLM to critique the joke
|
||||
const prompt = `Give a thorough critique of the following joke. If the joke needs improvement, put "IMPROVE" somewhere in the critique: ${event.data.joke}`;
|
||||
const response = await llm.complete({ prompt });
|
||||
|
||||
// If the critique includes "IMPROVE", keep iterating, else, return the result
|
||||
if (response.text.includes("IMPROVE")) {
|
||||
return critiqueEvent.with({ joke: event.data.joke, critique: response.text });
|
||||
}
|
||||
|
||||
return resultEvent.with({ joke: event.data.joke, critique: response.text });
|
||||
});
|
||||
|
||||
jokeFlow.handle([critiqueEvent], async (event) => {
|
||||
// Keep track of the number of iterations
|
||||
const store = jokeFlow.getStore();
|
||||
store.numIterations++;
|
||||
|
||||
// Write a new joke based on the previous joke and critique
|
||||
const prompt = `Write a new joke based on the following critique and the original joke. Write the joke between <joke> and </joke> tags.\n\nJoke: ${event.data.joke}\n\nCritique: ${event.data.critique}`;
|
||||
const response = await llm.complete({ prompt });
|
||||
|
||||
// Parse the joke from the response
|
||||
const joke = response.text.match(/<joke>([\s\S]*?)<\/joke>/)?.[1]?.trim() ?? response.text;
|
||||
|
||||
// If we've done less than the max number of iterations, keep iterating
|
||||
// else, return the result
|
||||
if (store.numIterations < store.maxIterations) {
|
||||
return jokeEvent.with({ joke: joke });
|
||||
}
|
||||
|
||||
return resultEvent.with({ joke: joke, critique: event.data.critique });
|
||||
});
|
||||
|
||||
// Usage
|
||||
async function main() {
|
||||
const { stream, sendEvent } = jokeFlow.createContext();
|
||||
sendEvent(startEvent.with("pirates"));
|
||||
|
||||
let result: { joke: string, critique: string } | undefined;
|
||||
|
||||
for await (const event of stream) {
|
||||
// console.log(event.data); optionally log the event data
|
||||
if (resultEvent.include(event)) {
|
||||
result = event.data;
|
||||
break; // Stop when we get the final result
|
||||
}
|
||||
}
|
||||
|
||||
console.log(result);
|
||||
}
|
||||
|
||||
main().catch(console.error);
|
||||
```
|
||||
|
||||
There are a few moving pieces here, so let's go through this step by step.
|
||||
|
||||
### Defining Workflow Events
|
||||
|
||||
```typescript
|
||||
const startEvent = workflowEvent<string>(); // Input topic for joke
|
||||
const jokeEvent = workflowEvent<{ joke: string }>(); // Intermediate joke
|
||||
const critiqueEvent = workflowEvent<{ joke: string, critique: string }>(); // Intermediate critique
|
||||
const resultEvent = workflowEvent<{ joke: string, critique: string }>(); // Final joke + critique
|
||||
```
|
||||
|
||||
Events are defined using the `workflowEvent` function and contain arbitrary data provided as a generic type. In this example, we have four events:
|
||||
- `startEvent`: Takes a string input (the joke topic)
|
||||
- `jokeEvent`: Contains an object with a joke property
|
||||
- `critiqueEvent`: Contains both the joke and its critique, used for the feedback loop
|
||||
- `resultEvent`: Contains the final joke and critique after any iterations
|
||||
|
||||
### Setting up the Workflow with Store Middleware
|
||||
|
||||
```typescript
|
||||
const jokeFlow = withStore(
|
||||
() => ({
|
||||
numIterations: 0,
|
||||
maxIterations: 3,
|
||||
}),
|
||||
createWorkflow()
|
||||
);
|
||||
```
|
||||
|
||||
Our workflow is implemented using the `createWorkflow()` function, enhanced with the `withStore` middleware. The store provides shared state across all handlers, which in this case tracks:
|
||||
- `numIterations`: Counts how many iterations of joke improvement we've done
|
||||
- `maxIterations`: Sets a limit to prevent infinite loops
|
||||
|
||||
This store will be accesible within workflows by using the `jokeFlow.getStore()` function.
|
||||
|
||||
### Adding Handlers with Loops
|
||||
|
||||
We have three key handlers in our workflow:
|
||||
|
||||
1. The first handler processes the `startEvent`, generates an initial joke, and emits a `jokeEvent`:
|
||||
|
||||
```typescript
|
||||
jokeFlow.handle([startEvent], async (event) => {
|
||||
// Prompt the LLM to write a joke
|
||||
const prompt = `Write your best joke about ${event.data}. Write the joke between <joke> and </joke> tags.`;
|
||||
const response = await llm.complete({ prompt });
|
||||
|
||||
// Parse the joke from the response
|
||||
const joke = response.text.match(/<joke>([\s\S]*?)<\/joke>/)?.[1]?.trim() ?? response.text;
|
||||
return jokeEvent.with({ joke: joke });
|
||||
});
|
||||
```
|
||||
|
||||
2. The second handler handles the `jokeEvent`, critiques the joke, and either:
|
||||
- Emits a `critiqueEvent` if the joke needs improvement
|
||||
- Emits a `resultEvent` if the joke is good enough
|
||||
|
||||
```typescript
|
||||
jokeFlow.handle([jokeEvent], async (event) => {
|
||||
// Prompt the LLM to critique the joke
|
||||
const prompt = `Give a thorough critique of the following joke. If the joke needs improvement, put "IMPROVE" somewhere in the critique: ${event.data.joke}`;
|
||||
const response = await llm.complete({ prompt });
|
||||
|
||||
// If the critique includes "IMPROVE", keep iterating, else, return the result
|
||||
if (response.text.includes("IMPROVE")) {
|
||||
return critiqueEvent.with({ joke: event.data.joke, critique: response.text });
|
||||
}
|
||||
|
||||
return resultEvent.with({ joke: event.data.joke, critique: response.text });
|
||||
});
|
||||
```
|
||||
|
||||
3. The third handler processes the `critiqueEvent`, generates an improved joke based on the critique, and either:
|
||||
- Loops back to the joke evaluation (if under the iteration limit)
|
||||
- Emits the final `resultEvent` (if iteration limit reached)
|
||||
|
||||
```typescript
|
||||
jokeFlow.handle([critiqueEvent], async (event) => {
|
||||
// Keep track of the number of iterations
|
||||
const store = jokeFlow.getStore();
|
||||
store.numIterations++;
|
||||
|
||||
// Write a new joke based on the previous joke and critique
|
||||
const prompt = `Write a new joke based on the following critique and the original joke. Write the joke between <joke> and </joke> tags.\n\nJoke: ${event.data.joke}\n\nCritique: ${event.data.critique}`;
|
||||
const response = await llm.complete({ prompt });
|
||||
|
||||
// Parse the joke from the response
|
||||
const joke = response.text.match(/<joke>([\s\S]*?)<\/joke>/)?.[1]?.trim() ?? response.text;
|
||||
|
||||
// If we've done less than the max number of iterations, keep iterating
|
||||
// else, return the result
|
||||
if (store.numIterations < store.maxIterations) {
|
||||
return jokeEvent.with({ joke: joke });
|
||||
}
|
||||
|
||||
return resultEvent.with({ joke: joke, critique: event.data.critique });
|
||||
});
|
||||
```
|
||||
|
||||
### Running the Workflow
|
||||
|
||||
```typescript
|
||||
async function main() {
|
||||
const { stream, sendEvent } = jokeFlow.createContext();
|
||||
sendEvent(startEvent.with("pirates"));
|
||||
|
||||
let result: { joke: string, critique: string } | undefined;
|
||||
|
||||
for await (const event of stream) {
|
||||
// console.log(event.data); optionally log the event data
|
||||
if (resultEvent.include(event)) {
|
||||
result = event.data;
|
||||
break; // Stop when we get the final result
|
||||
}
|
||||
}
|
||||
|
||||
console.log(result);
|
||||
}
|
||||
```
|
||||
|
||||
To run the workflow, we:
|
||||
1. Create a workflow context with `createContext()`
|
||||
2. Trigger the initial event with `sendEvent()`
|
||||
3. Listen to the event stream and process events as they arrive
|
||||
4. Use `include()` to check if an event is of a specific type
|
||||
5. Break the loop when we receive our final result
|
||||
|
||||
### Using Stream Utilities
|
||||
|
||||
Workflows provide utility functions to make working with event streams easier:
|
||||
|
||||
```typescript
|
||||
import { collect } from "@llama-flow/core/stream/consumer";
|
||||
import { until } from "@llama-flow/core/stream/until";
|
||||
|
||||
// Create a workflow context and send the initial event
|
||||
const { stream, sendEvent } = jokeFlow.createContext();
|
||||
sendEvent(startEvent.with("pirates"));
|
||||
|
||||
// Collect all events until we get a resultEvent
|
||||
const allEvents = await collect(until(stream, resultEvent));
|
||||
|
||||
// The last event will be the resultEvent
|
||||
const finalEvent = allEvents[allEvents.length - 1];
|
||||
console.log(finalEvent.data); // Output the joke and critique
|
||||
```
|
||||
|
||||
The stream utilities make it easier to work with the asynchronous event flow. In this example, we use:
|
||||
- `collect`: Aggregates all events into an array
|
||||
- `until`: Creates a stream that emits events until a condition is met (in this case, until a resultEvent is received)
|
||||
|
||||
You can combine these utilities with other stream operators like `filter` and `map` to create powerful processing pipelines.
|
||||
|
||||
## Next Steps
|
||||
|
||||
To learn more about workflows, check out [the documentation in the tutorial section](../../../llamaflow).
|
||||
|
||||
@@ -18,7 +18,7 @@ In your Discord Application, go to the `OAuth2` tab and generate an invite URL b
|
||||
This will invite the bot with the necessary permissions to read messages.
|
||||
Copy the URL in your browser and select the server you want your bot to join.
|
||||
|
||||
<include cwd>../../examples/discord/reader.ts</include>
|
||||
<include cwd>../../examples/readers/discord/reader.ts</include>
|
||||
|
||||
### Params
|
||||
|
||||
|
||||
@@ -88,7 +88,7 @@ async function main() {
|
||||
|
||||
const response = await queryEngine.query({
|
||||
query: "What did the author do in college?",
|
||||
});
|
||||
}); // Additional filters and params can be passed as options
|
||||
|
||||
// Output response
|
||||
console.log(response.toString());
|
||||
|
||||
@@ -120,11 +120,11 @@ async function main() {
|
||||
|
||||
```ts
|
||||
import { BEDROCK_MODELS, Bedrock } from "@llamaindex/community";
|
||||
import { FunctionTool, LLMAgent } from "llamaindex";
|
||||
import { tool } from "llamaindex";
|
||||
import { agent } from "@llamaindex/workflow";
|
||||
import { z } from "zod";
|
||||
|
||||
const sumNumbers = FunctionTool.from(
|
||||
({ a, b }: { a: number; b: number }) => `${a + b}`,
|
||||
const sumNumbers = tool(
|
||||
{
|
||||
name: "sumNumbers",
|
||||
description: "Use this function to sum two numbers",
|
||||
@@ -136,11 +136,11 @@ const sumNumbers = FunctionTool.from(
|
||||
description: "The second number",
|
||||
}),
|
||||
}),
|
||||
execute: ({ a, b }: { a: number; b: number }) => `${a + b}`,
|
||||
},
|
||||
);
|
||||
|
||||
const divideNumbers = FunctionTool.from(
|
||||
({ a, b }: { a: number; b: number }) => `${a / b}`,
|
||||
const divideNumbers = tool(
|
||||
{
|
||||
name: "divideNumbers",
|
||||
description: "Use this function to divide two numbers",
|
||||
@@ -152,6 +152,7 @@ const divideNumbers = FunctionTool.from(
|
||||
description: "The divisor b to divide by",
|
||||
}),
|
||||
}),
|
||||
execute: ({ a, b }: { a: number; b: number }) => `${a / b}`,
|
||||
},
|
||||
);
|
||||
|
||||
@@ -161,15 +162,15 @@ const bedrock = new Bedrock({
|
||||
});
|
||||
|
||||
async function main() {
|
||||
const agent = new LLMAgent({
|
||||
const myAgent = agent({
|
||||
llm: bedrock,
|
||||
tools: [sumNumbers, divideNumbers],
|
||||
});
|
||||
|
||||
const response = await agent.chat({
|
||||
message: "How much is 5 + 5? then divide by 2",
|
||||
});
|
||||
const response = await myAgent.run(
|
||||
"How much is 5 + 5? then divide by 2",
|
||||
);
|
||||
|
||||
console.log(response.message);
|
||||
console.log(response);
|
||||
}
|
||||
```
|
||||
|
||||
@@ -55,7 +55,7 @@ const results = await queryEngine.query({
|
||||
|
||||
## Full Example
|
||||
|
||||
<include cwd>../../examples/groq.ts</include>
|
||||
<include cwd>../../examples/models/groq.ts</include>
|
||||
|
||||
## API Reference
|
||||
|
||||
|
||||
@@ -166,4 +166,4 @@ Want to start a new project with LlamaIndexServer? Check out our [create-llama](
|
||||
|
||||
## API Reference
|
||||
|
||||
- [LlamaIndexServer](/docs/api/classes/LlamaIndexServer)
|
||||
- [LlamaIndexServer](https://github.com/run-llama/create-llama/blob/main/packages/server)
|
||||
@@ -15,7 +15,7 @@ In LlamaIndex, an agent is a semi-autonomous piece of software powered by an LLM
|
||||
You'll need to have a recent version of [Node.js](https://nodejs.org/en) installed. Then you can install LlamaIndex.TS by running
|
||||
|
||||
```package-install
|
||||
npm i llamaindex @llamaindex/openai @llamaindex/readers @llamaindex/huggingface
|
||||
npm i llamaindex @llamaindex/openai @llamaindex/readers @llamaindex/huggingface @llamaindex/workflow
|
||||
```
|
||||
|
||||
## Choose your model
|
||||
|
||||
@@ -35,11 +35,16 @@ First we'll need to pull in our dependencies. These are:
|
||||
import "dotenv/config";
|
||||
import {
|
||||
agent,
|
||||
AgentStream,
|
||||
tool,
|
||||
agentStreamEvent,
|
||||
openai,
|
||||
} from "@llamaindex/workflow";
|
||||
import {
|
||||
tool,
|
||||
Settings,
|
||||
} from "llamaindex";
|
||||
import {
|
||||
openai,
|
||||
} from "@llamaindex/openai";
|
||||
import { z } from "zod";
|
||||
```
|
||||
|
||||
@@ -108,11 +113,10 @@ const myAgent = agent({ tools });
|
||||
|
||||
### Ask the agent a question
|
||||
|
||||
We can use the `chat` interface to ask our agent a question, and it will use the tools we've defined to find an answer.
|
||||
We can use the `run` method to ask our agent a question, and it will use the tools we've defined to find an answer.
|
||||
|
||||
```javascript
|
||||
const context = myAgent.run("Sum 101 and 303");
|
||||
const result = await context;
|
||||
const result = await myAgent.run("Sum 101 and 303");
|
||||
console.log(result.data);
|
||||
```
|
||||
You will see the following output:
|
||||
@@ -123,12 +127,13 @@ You will see the following output:
|
||||
{ result: 'The sum of 101 and 303 is 404.' }
|
||||
```
|
||||
|
||||
To stream the response, you can use the `AgentStream` event which provides chunks of the response as they become available. This allows you to display the response incrementally rather than waiting for the full response:
|
||||
To stream the response, you need to call `runStream`, which returns a stream of events.
|
||||
The `agentStreamEvent` provides chunks of the response as they become available. This allows you to display the response incrementally rather than waiting for the full response:
|
||||
|
||||
```javascript
|
||||
const context = myAgent.run("Add 101 and 303");
|
||||
for await (const event of context) {
|
||||
if (event instanceof AgentStream) {
|
||||
const events = myAgent.runStream("Add 101 and 303");
|
||||
for await (const event of events) {
|
||||
if (agentStreamEvent.include(event)) {
|
||||
process.stdout.write(event.data.delta);
|
||||
}
|
||||
}
|
||||
@@ -140,18 +145,18 @@ for await (const event of context) {
|
||||
The sum of 101 and 303 is 404.
|
||||
```
|
||||
|
||||
Note that we're filtering for `agentStreamEvent` as an agent might return other events - more about that in the following section.
|
||||
|
||||
### Logging workflow events
|
||||
|
||||
To log the workflow events, you can check the event type and log the event data.
|
||||
|
||||
```javascript
|
||||
const context = myAgent.run("Sum 202 and 404");
|
||||
for await (const event of context) {
|
||||
if (event instanceof AgentStream) {
|
||||
const events = myAgent.runStream("Sum 202 and 404");
|
||||
for await (const event of events) {
|
||||
if (agentStreamEvent.include(event)) {
|
||||
// Stream the response
|
||||
for (const chunk of event.data.delta) {
|
||||
process.stdout.write(chunk);
|
||||
}
|
||||
process.stdout.write(event.data.delta);
|
||||
} else {
|
||||
// Log other events
|
||||
console.log("\nWorkflow event:", JSON.stringify(event, null, 2));
|
||||
|
||||
@@ -30,16 +30,16 @@ Settings.llm = ollama({
|
||||
|
||||
### Run local agent
|
||||
|
||||
You can also create local agent by importing `agent` from `llamaindex`.
|
||||
You can also create local agent by importing `agent` from `@llamaindex/workflow`.
|
||||
|
||||
```javascript
|
||||
import { agent } from "llamaindex";
|
||||
import { agent } from "@llamaindex/workflow";
|
||||
|
||||
const workflow = agent({
|
||||
tools: [getWeatherTool],
|
||||
});
|
||||
|
||||
const workflowContext = workflow.run(
|
||||
const resutl = workflow.run(
|
||||
"What's the weather like in San Francisco?",
|
||||
);
|
||||
```
|
||||
|
||||
@@ -25,7 +25,8 @@ We'll be bringing in `SimpleDirectoryReader`, `HuggingFaceEmbedding`, `VectorSto
|
||||
|
||||
```javascript
|
||||
import { QueryEngineTool, Settings, VectorStoreIndex } from "llamaindex";
|
||||
import { OpenAI, OpenAIAgent } from "@llamaindex/openai";
|
||||
import { agent } from "@llamaindex/workflow";
|
||||
import { openai } from "@llamaindex/openai";
|
||||
import { HuggingFaceEmbedding } from "@llamaindex/huggingface";
|
||||
import { SimpleDirectoryReader } from "@llamaindex/readers/directory";
|
||||
```
|
||||
|
||||
@@ -8,9 +8,10 @@ We have a comprehensive, step-by-step [guide to building agents in LlamaIndex.TS
|
||||
|
||||
In a new folder:
|
||||
|
||||
```bash npm2yarn
|
||||
```package-install
|
||||
npm init
|
||||
npm i -D typescript @types/node
|
||||
npm i @llamaindex/openai @llamaindex/workflow llamaindex zod
|
||||
```
|
||||
|
||||
## Run agent
|
||||
@@ -20,15 +21,14 @@ Create the file `example.ts`. This code will:
|
||||
- Create two tools for use by the agent:
|
||||
- A `sumNumbers` tool that adds two numbers
|
||||
- A `divideNumbers` tool that divides numbers
|
||||
-
|
||||
- Give an example of the data structure we wish to generate
|
||||
- Prompt the LLM with instructions and the example, plus a sample transcript
|
||||
|
||||
<include cwd>../../examples/agent/openai.ts</include>
|
||||
<include cwd>../../examples/agents/agent/openai.ts</include>
|
||||
|
||||
To run the code:
|
||||
|
||||
```bash
|
||||
```package-install
|
||||
npx tsx example.ts
|
||||
```
|
||||
|
||||
@@ -36,9 +36,18 @@ You should expect output something like:
|
||||
|
||||
```
|
||||
{
|
||||
content: 'The sum of 5 + 5 is 10. When you divide 10 by 2, you get 5.',
|
||||
role: 'assistant',
|
||||
options: {}
|
||||
result: '5 + 5 is 10. Then, 10 divided by 2 is 5.',
|
||||
state: {
|
||||
memory: ChatMemoryBuffer {
|
||||
chatStore: SimpleChatStore {},
|
||||
chatStoreKey: 'chat_history',
|
||||
tokenLimit: 750000
|
||||
},
|
||||
scratchpad: [],
|
||||
currentAgentName: 'Agent',
|
||||
agents: [ 'Agent' ],
|
||||
nextAgentName: null
|
||||
}
|
||||
}
|
||||
Done
|
||||
```
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
"basic_agent",
|
||||
"rag",
|
||||
"agents",
|
||||
"../../llamaflow",
|
||||
"workflows",
|
||||
"local_llm",
|
||||
"chatbot",
|
||||
"structured_data_extraction"
|
||||
|
||||
@@ -16,7 +16,7 @@ LlamaIndex uses a two stage method when using an LLM with your data:
|
||||
1. **indexing stage**: preparing a knowledge base, and
|
||||
2. **querying stage**: retrieving relevant context from the knowledge to assist the LLM in responding to a question
|
||||
|
||||

|
||||

|
||||
|
||||
This process is also known as Retrieval Augmented Generation (RAG).
|
||||
|
||||
@@ -28,7 +28,7 @@ Let's explore each stage in detail.
|
||||
|
||||
LlamaIndex.TS help you prepare the knowledge base with a suite of data connectors and indexes.
|
||||
|
||||

|
||||

|
||||
|
||||
[**Data Loaders**](/docs/llamaindex/modules/data/readers):
|
||||
A data connector (i.e. `Reader`) ingest data from different data sources and data formats into a simple `Document` representation (text and simple metadata).
|
||||
@@ -54,7 +54,7 @@ LlamaIndex provides composable modules that help you build and integrate RAG pip
|
||||
|
||||
These building blocks can be customized to reflect ranking preferences, as well as composed to reason over multiple knowledge bases in a structured way.
|
||||
|
||||

|
||||

|
||||
|
||||
#### Building Blocks
|
||||
|
||||
|
||||
@@ -8,9 +8,10 @@ One of the most common use-cases for LlamaIndex is Retrieval-Augmented Generatio
|
||||
|
||||
In a new folder, run:
|
||||
|
||||
```bash npm2yarn
|
||||
```package-install
|
||||
npm init
|
||||
npm i -D typescript @types/node
|
||||
npm i llamaindex
|
||||
```
|
||||
|
||||
Then, check out the [installation](/docs/llamaindex/getting_started/installation) steps to install LlamaIndex.TS and prepare an OpenAI key.
|
||||
@@ -26,7 +27,7 @@ Create the file `example.ts`. This code will
|
||||
- index it (which creates embeddings using OpenAI)
|
||||
- create a query engine to answer questions about the data
|
||||
|
||||
<include cwd>../../examples/vectorIndex.ts</include>
|
||||
<include cwd>../../examples/index/vectorIndex.ts</include>
|
||||
|
||||
Create a `tsconfig.json` file in the same folder:
|
||||
|
||||
@@ -34,7 +35,7 @@ Create a `tsconfig.json` file in the same folder:
|
||||
|
||||
Now you can run the code with
|
||||
|
||||
```bash
|
||||
```package-install
|
||||
npx tsx example.ts
|
||||
```
|
||||
|
||||
|
||||
@@ -10,9 +10,10 @@ You can use [other LLMs](/docs/llamaindex/modules/models/llms) via their APIs; i
|
||||
|
||||
In a new folder:
|
||||
|
||||
```bash npm2yarn
|
||||
```package-install
|
||||
npm init
|
||||
npm i -D typescript @types/node
|
||||
npm i @llamaindex/openai zod
|
||||
```
|
||||
|
||||
## Extract data
|
||||
@@ -23,11 +24,11 @@ Create the file `example.ts`. This code will:
|
||||
- Give an example of the data structure we wish to generate
|
||||
- Prompt the LLM with instructions and the example, plus a sample transcript
|
||||
|
||||
<include cwd>../../examples/jsonExtract.ts</include>
|
||||
<include cwd>../../examples/misc/jsonExtract.ts</include>
|
||||
|
||||
To run the code:
|
||||
|
||||
```bash
|
||||
```package-install
|
||||
npx tsx example.ts
|
||||
```
|
||||
|
||||
|
||||
@@ -0,0 +1,176 @@
|
||||
---
|
||||
title: Workflows
|
||||
---
|
||||
|
||||
A `Workflow` in LlamaIndex is a lightweight, event-driven abstraction used to chain together several events. Workflows are made up of `handlers`, with each one responsible for processing specific event types and emitting new events.
|
||||
|
||||
Workflows are designed to be flexible and can be used to build agents, RAG flows, extraction flows, or anything else you want to implement.
|
||||
|
||||
```package-install
|
||||
npm i @llamaindex/workflow @llamaindex/openai
|
||||
```
|
||||
|
||||
## Getting Started
|
||||
|
||||
Let's explore a simple workflow example where a joke is generated and then critiqued and iterated on:
|
||||
|
||||
<include cwd>../../examples/agents/workflow/joke.ts</include>
|
||||
|
||||
There are a few moving pieces here, so let's go through this step by step.
|
||||
|
||||
### Defining Workflow Events
|
||||
|
||||
```typescript
|
||||
const startEvent = workflowEvent<string>(); // Input topic for joke
|
||||
const jokeEvent = workflowEvent<{ joke: string }>(); // Intermediate joke
|
||||
const critiqueEvent = workflowEvent<{ joke: string; critique: string }>(); // Intermediate critique
|
||||
const resultEvent = workflowEvent<{ joke: string; critique: string }>(); // Final joke + critique
|
||||
```
|
||||
|
||||
Events are defined using the `workflowEvent` function and contain arbitrary data provided as a generic type. In this example, we have four events:
|
||||
- `startEvent`: Takes a string input (the joke topic)
|
||||
- `jokeEvent`: Contains an object with a joke property
|
||||
- `critiqueEvent`: Contains both the joke and its critique, used for the feedback loop
|
||||
- `resultEvent`: Contains the final joke and critique after any iterations
|
||||
|
||||
### Setting up the Workflow with Stateful Middleware
|
||||
|
||||
```typescript
|
||||
const { withState, getContext } = createStatefulMiddleware(() => ({
|
||||
numIterations: 0,
|
||||
maxIterations: 3,
|
||||
}));
|
||||
const jokeFlow = withState(createWorkflow());
|
||||
```
|
||||
|
||||
Our workflow is implemented using the `createWorkflow()` function, enhanced with the `withState` middleware. This middleware provides shared state across all handlers, which in this case tracks:
|
||||
- `numIterations`: Counts how many iterations of joke improvement we've done
|
||||
- `maxIterations`: Sets a limit to prevent infinite loops
|
||||
|
||||
This state will be accessible within workflows by using the `getContext().state` function.
|
||||
|
||||
### Adding Handlers with Loops
|
||||
|
||||
We have three key handlers in our workflow:
|
||||
|
||||
1. The first handler processes the `startEvent`, generates an initial joke, and emits a `jokeEvent`:
|
||||
|
||||
```typescript
|
||||
jokeFlow.handle([startEvent], async (event) => {
|
||||
// Prompt the LLM to write a joke
|
||||
const prompt = `Write your best joke about ${event.data}. Write the joke between <joke> and </joke> tags.`;
|
||||
const response = await llm.complete({ prompt });
|
||||
|
||||
// Parse the joke from the response
|
||||
const joke =
|
||||
response.text.match(/<joke>([\s\S]*?)<\/joke>/)?.[1]?.trim() ??
|
||||
response.text;
|
||||
return jokeEvent.with({ joke: joke });
|
||||
});
|
||||
```
|
||||
|
||||
2. The second handler handles the `jokeEvent`, critiques the joke, and either:
|
||||
- Emits a `critiqueEvent` if the joke needs improvement
|
||||
- Emits a `resultEvent` if the joke is good enough
|
||||
|
||||
```typescript
|
||||
jokeFlow.handle([jokeEvent], async (event) => {
|
||||
// Prompt the LLM to critique the joke
|
||||
const prompt = `Give a thorough critique of the following joke. If the joke needs improvement, put "IMPROVE" somewhere in the critique: ${event.data.joke}`;
|
||||
const response = await llm.complete({ prompt });
|
||||
|
||||
// If the critique includes "IMPROVE", keep iterating, else, return the result
|
||||
if (response.text.includes("IMPROVE")) {
|
||||
return critiqueEvent.with({
|
||||
joke: event.data.joke,
|
||||
critique: response.text,
|
||||
});
|
||||
}
|
||||
|
||||
return resultEvent.with({ joke: event.data.joke, critique: response.text });
|
||||
});
|
||||
```
|
||||
|
||||
3. The third handler processes the `critiqueEvent`, generates an improved joke based on the critique, and either:
|
||||
- Loops back to the joke evaluation (if under the iteration limit)
|
||||
- Emits the final `resultEvent` (if iteration limit reached)
|
||||
|
||||
```typescript
|
||||
jokeFlow.handle([critiqueEvent], async (event) => {
|
||||
// Keep track of the number of iterations
|
||||
const state = getContext().state;
|
||||
state.numIterations++;
|
||||
|
||||
// Write a new joke based on the previous joke and critique
|
||||
const prompt = `Write a new joke based on the following critique and the original joke. Write the joke between <joke> and </joke> tags.\n\nJoke: ${event.data.joke}\n\nCritique: ${event.data.critique}`;
|
||||
const response = await llm.complete({ prompt });
|
||||
|
||||
// Parse the joke from the response
|
||||
const joke =
|
||||
response.text.match(/<joke>([\s\S]*?)<\/joke>/)?.[1]?.trim() ??
|
||||
response.text;
|
||||
|
||||
// If we've done less than the max number of iterations, keep iterating
|
||||
// else, return the result
|
||||
if (state.numIterations < state.maxIterations) {
|
||||
return jokeEvent.with({ joke: joke });
|
||||
}
|
||||
|
||||
return resultEvent.with({ joke: joke, critique: event.data.critique });
|
||||
});
|
||||
```
|
||||
|
||||
### Running the Workflow
|
||||
|
||||
```typescript
|
||||
async function main() {
|
||||
const { stream, sendEvent } = jokeFlow.createContext();
|
||||
sendEvent(startEvent.with("pirates"));
|
||||
|
||||
let result: { joke: string, critique: string } | undefined;
|
||||
|
||||
for await (const event of stream) {
|
||||
// console.log(event.data); optionally log the event data
|
||||
if (resultEvent.include(event)) {
|
||||
result = event.data;
|
||||
break; // Stop when we get the final result
|
||||
}
|
||||
}
|
||||
|
||||
console.log(result);
|
||||
}
|
||||
```
|
||||
|
||||
To run the workflow, we:
|
||||
1. Create a workflow context with `createContext()`
|
||||
2. Trigger the initial event with `sendEvent()`
|
||||
3. Listen to the event stream and process events as they arrive
|
||||
4. Use `include()` to check if an event is of a specific type
|
||||
5. Break the loop when we receive our final result
|
||||
|
||||
### Using Stream Utilities
|
||||
|
||||
The `stream` returned by `createContext` contains utility functions to make working with event streams easier:
|
||||
|
||||
```typescript
|
||||
// Create a workflow context and send the initial event
|
||||
const { stream, sendEvent } = jokeFlow.createContext();
|
||||
sendEvent(startEvent.with("pirates"));
|
||||
|
||||
// Collect all events until we get a resultEvent
|
||||
const allEvents = await stream.until(resultEvent).toArray();
|
||||
|
||||
// The last event will be the resultEvent
|
||||
const finalEvent = allEvents.at(-1);
|
||||
console.log(finalEvent.data); // Output the joke and critique
|
||||
```
|
||||
|
||||
The stream utilities make it easier to work with the asynchronous event flow. In this example, we use:
|
||||
- `toArray`: Aggregates all events into an array
|
||||
- `until`: Creates a stream that emits events until a condition is met (in this case, until a resultEvent is received)
|
||||
|
||||
You can combine these utilities with other stream operators like `filter` and `map` to create powerful processing pipelines.
|
||||
|
||||
## Next Steps
|
||||
|
||||
To learn more about workflows, check out [the Workflows documentation](/docs/llamaindex/modules/agents/workflows).
|
||||
@@ -1,3 +1,3 @@
|
||||
{
|
||||
"pages": ["llamaindex", "api"]
|
||||
"pages": ["llamaindex", "api", "llamaflow"]
|
||||
}
|
||||
|
||||
@@ -0,0 +1,60 @@
|
||||
---
|
||||
title: High-Level Concepts
|
||||
---
|
||||
|
||||
This is a quick guide to the high-level concepts you'll encounter frequently when building LLM applications.
|
||||
|
||||
## Large Language Models (LLMs)
|
||||
|
||||
LLMs are the fundamental innovation that launched LlamaIndex. They are an artificial intelligence (AI) computer system that can understand, generate, and manipulate natural language, including answering questions based on their training data or data provided to them at query time.
|
||||
|
||||
## Agentic Applications
|
||||
|
||||
When an LLM is used within an application, it is often used to make decisions, take actions, and/or interact with the world. This is the core definition of an **agentic application**.
|
||||
|
||||
While the definition of an agentic application is broad, there are several key characteristics that define an agentic application:
|
||||
|
||||
- **LLM Augmentation**: The LLM is augmented with tools (i.e. arbitrary callable functions in code), memory, and/or dynamic prompts.
|
||||
- **Prompt Chaining**: Several LLM calls are used that build on each other, with the output of one LLM call being used as the input to the next.
|
||||
- **Routing**: The LLM is used to route the application to the next appropriate step or state in the application.
|
||||
- **Parallelism**: The application can perform multiple steps or actions in parallel.
|
||||
- **Orchestration**: A hierarchical structure of LLMs is used to orchestrate lower-level actions and LLMs.
|
||||
- **Reflection**: The LLM is used to reflect and validate outputs of previous steps or LLM calls, which can be used to guide the application to the next appropriate step or state.
|
||||
|
||||
In LlamaIndex, you can build agentic applications by using the workflows to orchestrate a sequence of steps and LLMs. You can [learn more about workflows](/docs/llamaindex/tutorials/workflows).
|
||||
|
||||
## Agents
|
||||
|
||||
We define an agent as a specific instance of an "agentic application". An agent is a piece of software that semi-autonomously performs tasks by combining LLMs with other tools and memory, orchestrated in a reasoning loop that decides which tool to use next (if any).
|
||||
|
||||
What this means in practice, is something like:
|
||||
- An agent receives a user message
|
||||
- The agent uses an LLM to determine the next appropriate action to take using the previous chat history, tools, and the latest user message
|
||||
- The agent may invoke one or more tools to assist in the users request
|
||||
- If tools are used, the agent will then interpret the tool outputs and use them to inform the next action
|
||||
- Once the agent stops taking actions, it returns the final output to the user
|
||||
|
||||
You can [learn more about agents](/docs/llamaindex/tutorials/basic_agent).
|
||||
|
||||
## Retrieval Augmented Generation (RAG)
|
||||
|
||||
Retrieval-Augmented Generation (RAG) is a core technique for building data-backed LLM applications with LlamaIndex. It allows LLMs to answer questions about your private data by providing it to the LLM at query time, rather than training the LLM on your data. To avoid sending **all** of your data to the LLM every time, RAG indexes your data and selectively sends only the relevant parts along with your query. You can [learn more about RAG](/docs/llamaindex/tutorials/rag).
|
||||
|
||||
## Use cases
|
||||
|
||||
There are endless use cases for data-backed LLM applications but they can be roughly grouped into four categories:
|
||||
|
||||
[**Agents**](/docs/llamaindex/tutorials/basic_agent):
|
||||
An agent is an automated decision-maker powered by an LLM that interacts with the world via a set of [tools](/docs/llamaindex/modules/agents/tool). Agents can take an arbitrary number of steps to complete a given task, dynamically deciding on the best course of action rather than following pre-determined steps. This gives it additional flexibility to tackle more complex tasks.
|
||||
|
||||
[**Workflows**](/docs/llamaindex/tutorials/workflows):
|
||||
A Workflow in LlamaIndex is a specific event-driven abstraction that allows you to orchestrate a sequence of steps and LLMs calls. Workflows can be used to implement any agentic application, and are a core component of LlamaIndex.
|
||||
|
||||
[**Structured Data Extraction**](/docs/llamaindex/tutorials/structured_data_extraction):
|
||||
Pydantic extractors allow you to specify a precise data structure to extract from your data and use LLMs to fill in the missing pieces in a type-safe way. This is useful for extracting structured data from unstructured sources like PDFs, websites, and more, and is key to automating workflows.
|
||||
|
||||
[**Query Engines**](/docs/llamaindex/modules/rag/query_engines):
|
||||
A query engine is an end-to-end flow that allows you to ask questions over your data. It takes in a natural language query, and returns a response, along with reference context retrieved and passed to the LLM.
|
||||
|
||||
[**Chat Engines**](/docs/llamaindex/modules/rag/chat_engine):
|
||||
A chat engine is an end-to-end flow for having a conversation with your data (multiple back-and-forth instead of a single question-and-answer).
|
||||
@@ -0,0 +1,21 @@
|
||||
---
|
||||
title: Create-Llama
|
||||
---
|
||||
|
||||
`create-llama` is a powerful but easy to use command-line tool that generates a working, full-stack web application that allows you to chat with your data. You can learn more about it on [the `create-llama` README page](https://www.npmjs.com/package/create-llama).
|
||||
|
||||
Run it once and it will ask you a series of questions about the kind of application you want to generate. Then you can customize your application to suit your use-case. To get started, run:
|
||||
|
||||
```bash npm2yarn
|
||||
npx create-llama@latest
|
||||
```
|
||||
|
||||
Once your app is generated, `cd` into your app directory and run
|
||||
|
||||
```bash npm2yarn
|
||||
npm run dev
|
||||
```
|
||||
|
||||
to start the development server. You can then visit [http://localhost:3000](http://localhost:3000) to see your app, which should look something like this:
|
||||
|
||||

|
||||
@@ -0,0 +1,32 @@
|
||||
---
|
||||
title: Code examples
|
||||
---
|
||||
|
||||
Our GitHub repository has a wealth of examples to explore and try out. You can check out our [examples folder](https://github.com/run-llama/LlamaIndexTS/tree/main/examples) to see them all at once, or browse the pages in this section for some selected highlights.
|
||||
|
||||
## Use examples locally
|
||||
|
||||
It may be useful to check out all the examples at once so you can try them out locally. To do this into a folder called `my-new-project`, run these commands:
|
||||
|
||||
```bash npm2yarn
|
||||
npx degit run-llama/LlamaIndexTS/examples my-new-project
|
||||
cd my-new-project
|
||||
npm i
|
||||
```
|
||||
|
||||
Then you can run any example in the folder with `tsx`, e.g.:
|
||||
|
||||
```bash npm2yarn
|
||||
npx tsx ./vectorIndex.ts
|
||||
```
|
||||
|
||||
## Try examples online
|
||||
|
||||
You can also try the examples online using StackBlitz:
|
||||
|
||||
<iframe
|
||||
style={{ width: '100%', height: '440px' }}
|
||||
aria-label="LlamaIndex.TS Examples"
|
||||
aria-description="This is a list of examples for LlamaIndex.TS."
|
||||
src="https://stackblitz.com/github/run-llama/LlamaIndexTS/tree/main/examples?file=README.md"
|
||||
/>
|
||||
@@ -0,0 +1,72 @@
|
||||
---
|
||||
title: With Cloudflare Worker
|
||||
description: In this guide, you'll learn how to use LlamaIndex with CloudFlare Worker
|
||||
---
|
||||
import { SiCloudflareworkers } from '@icons-pack/react-simple-icons';
|
||||
import { LinkCard, Aside } from '@astrojs/starlight/components';
|
||||
|
||||
Before you start, make sure you have try LlamaIndex.TS in Node.js to make sure you understand the basics.
|
||||
|
||||
<LinkCard
|
||||
title="Getting Started with LlamaIndex.TS in Node.js"
|
||||
href="/docs/llamaindex/getting_started/installation/node"
|
||||
/>
|
||||
|
||||
Also, you need have the basic understanding of <a href='https://developers.cloudflare.com/workers/'><SiCloudflareworkers className="inline mr-2" color="#F38020" />Cloudflare Worker</a>.
|
||||
|
||||
## Adding environment variables
|
||||
|
||||
```ts
|
||||
export default {
|
||||
async fetch(request: Request, env: Env): Promise<Response> {
|
||||
const { setEnvs } = await import("@llamaindex/env");
|
||||
setEnvs(env);
|
||||
const { OpenAIAgent } = await import("@llamaindex/openai");
|
||||
// Start your code here
|
||||
return new Response("Hello, world!");
|
||||
},
|
||||
};
|
||||
```
|
||||
|
||||
Then, you need create `.dev.vars` and add LLM api keys for the local development, such as `OPENAI_API_KEY` for OpenAI API key.
|
||||
|
||||
<Aside type="caution">Do not commit the api key to git repository.</Aside>
|
||||
|
||||
## Integrating with Hono
|
||||
|
||||
```ts
|
||||
import { Hono } from "hono";
|
||||
|
||||
type Bindings = {
|
||||
OPENAI_API_KEY: string;
|
||||
};
|
||||
|
||||
const app = new Hono<{
|
||||
Bindings: Bindings;
|
||||
}>();
|
||||
|
||||
app.post("/llm", async (c) => {
|
||||
const { setEnvs } = await import("@llamaindex/env");
|
||||
setEnvs(c.env);
|
||||
|
||||
// ...
|
||||
|
||||
return new Response('Hello, world!');
|
||||
})
|
||||
|
||||
export default {
|
||||
fetch: app.fetch,
|
||||
};
|
||||
```
|
||||
|
||||
## Difference between Node.js and Cloudflare Worker
|
||||
|
||||
In Cloudflare Worker and similar serverless JS environment, you need to be aware of the following differences:
|
||||
|
||||
- Some Node.js modules are not available in Cloudflare Worker, such as `node:fs`, `node:child_process`, `node:cluster`...
|
||||
- You are recommend to design your code using network request, such as use `fetch` API to communicate with database, instead of a long-running process in Node.js.
|
||||
- Some of LlamaIndex.TS packages are not available in Cloudflare Worker, for example `@llamaindex/readers` and `@llamaindex/huggingface`.
|
||||
- The main `llamaindex` is designed to work in all JavaScript environment, including Cloudflare Worker. If you find any issue, please report to us.
|
||||
- `@llamaindex/env` is a JS environment binding module, which polyfill some Node.js/Modern Web API (for example, we have a memory based `fs` module, and Crypto API polyfill). It is designed to work in all JavaScript environment, including Cloudflare Worker.
|
||||
|
||||
|
||||
@@ -0,0 +1,63 @@
|
||||
---
|
||||
title: Installation
|
||||
description: How to install llamaindex packages.
|
||||
---
|
||||
import { Card, CardGrid, LinkCard, Icon } from '@astrojs/starlight/components';
|
||||
import { SiTypescript, SiVite, SiCloudflareworkers, SiNodedotjs, SiNextdotjs } from '@icons-pack/react-simple-icons';
|
||||
|
||||
To install llamaindex, run the following command:
|
||||
|
||||
```package-install
|
||||
npm i llamaindex
|
||||
```
|
||||
|
||||
In most cases, you'll also need an LLM package and the Workflow package to use LlamaIndex. For example, to use the OpenAI LLM with agents, you would install the following:
|
||||
|
||||
```package-install
|
||||
npm i @llamaindex/openai @llamaindex/workflow
|
||||
```
|
||||
|
||||
Go to [LLM APIs](/docs/llamaindex/modules/models/llms) to find out how to use other LLMs.
|
||||
|
||||
|
||||
## Frameworks
|
||||
|
||||
LlamaIndex supports a wide range of frameworks and runtimes. Click on the card below to learn more.
|
||||
|
||||
<CardGrid>
|
||||
<LinkCard
|
||||
title="Node.js"
|
||||
href="/docs/llamaindex/getting_started/installation/node"
|
||||
/>
|
||||
<LinkCard
|
||||
title="TypeScript"
|
||||
href="/docs/llamaindex/getting_started/installation/typescript"
|
||||
/>
|
||||
<LinkCard
|
||||
title="Vite"
|
||||
href="/docs/llamaindex/getting_started/installation/vite"
|
||||
/>
|
||||
<LinkCard
|
||||
title="Next.js"
|
||||
href="/docs/llamaindex/getting_started/installation/next"
|
||||
/>
|
||||
<LinkCard
|
||||
title="Cloudflare Workers"
|
||||
href="/docs/llamaindex/getting_started/installation/cloudflare"
|
||||
/>
|
||||
</CardGrid>
|
||||
|
||||
## What's next?
|
||||
|
||||
<CardGrid>
|
||||
<LinkCard
|
||||
title="Learn LlamaIndex.TS"
|
||||
description="Learn how to use LlamaIndex.TS by starting with one of our tutorials."
|
||||
href="/docs/llamaindex/tutorials/rag"
|
||||
/>
|
||||
<LinkCard
|
||||
title="Show me code examples"
|
||||
description="Explore code examples using LlamaIndex.TS."
|
||||
href="/docs/llamaindex/getting_started/examples"
|
||||
/>
|
||||
</CardGrid>
|
||||
@@ -0,0 +1,4 @@
|
||||
{
|
||||
"title": "Installation",
|
||||
"pages": ["node", "typescript", "next", "vite", "cloudflare"]
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
---
|
||||
title: With Next.js
|
||||
description: In this guide, you'll learn how to use LlamaIndex with Next.js.
|
||||
---
|
||||
import { Card, CardGrid, LinkCard, Icon } from '@astrojs/starlight/components';
|
||||
|
||||
Before you start, make sure you have try LlamaIndex.TS in Node.js to make sure you understand the basics.
|
||||
|
||||
<LinkCard
|
||||
title="Getting Started with LlamaIndex.TS in Node.js"
|
||||
href="/docs/llamaindex/getting_started/installation/node"
|
||||
/>
|
||||
|
||||
## Differences between Node.js and Next.js
|
||||
|
||||
Next.js is a React framework that has both server side compatibility and client side compatibility.
|
||||
This means that you need to be careful when using LlamaIndex.TS in Next.js.
|
||||
Don't leak the import data like API keys to the client side.
|
||||
|
||||
Also, in Next.js, there is build time and runtime. Some computations can be done at build time like Document embedding could be done at build time for better performance.
|
||||
Where as the `llamaindex` package is working with Next.js, some provider packages like `@llamaindex/huggingface` are not working well with Next.js. This is due to the upstream dependencies used by the provider package.
|
||||
|
||||
Make sure to use `withLlamaIndex` to make sure that LlamaIndex.TS works well with Next.js.
|
||||
|
||||
```js
|
||||
// next.config.mjs / next.config.ts
|
||||
import withLlamaIndex from "llamaindex/next";
|
||||
|
||||
/** @type {import('next').NextConfig} */
|
||||
const nextConfig = {};
|
||||
|
||||
export default withLlamaIndex(nextConfig);
|
||||
```
|
||||
|
||||
If you see any dependency issues, you are welcome to open an issue on the GitHub.
|
||||
|
||||
## Edge Runtime
|
||||
|
||||
[Vercel Edge Runtime](https://edge-runtime.vercel.app/) is a subset of Node.js APIs. Similar to [Cloudflare Workers](/docs/llamaindex/getting_started/installation/cloudflare#difference-between-nodejs-and-cloudflare-worker),
|
||||
it is a serverless platform that runs your code on the edge.
|
||||
|
||||
Not all features of Node.js are supported in Vercel Edge Runtime, so does LlamaIndex.TS, we are working on more compatibility with all JavaScript runtimes.
|
||||
@@ -0,0 +1,41 @@
|
||||
---
|
||||
title: With Node.js/Bun/Deno
|
||||
description: In this guide, you'll learn how to use LlamaIndex with Node.js, Bun, and Deno.
|
||||
---
|
||||
import { Card, CardGrid, LinkCard, Icon, Aside } from '@astrojs/starlight/components';
|
||||
|
||||
## Adding environment variables
|
||||
|
||||
By default, LlamaIndex uses OpenAI provider, which requires an API key. You can set the `OPENAI_API_KEY` environment variable to authenticate with OpenAI.
|
||||
|
||||
```shell
|
||||
export OPENAI_API_KEY=your-api-key
|
||||
```
|
||||
|
||||
Or you can use a `.env` file:
|
||||
|
||||
```shell
|
||||
echo "OPENAI_API_KEY=your-api-key" > .env
|
||||
node --env-file .env your-script.js
|
||||
```
|
||||
|
||||
<Aside type="caution">Do not commit the api key to git repository.</Aside>
|
||||
|
||||
For more information, see the [How to read environment variables from Node.js](https://nodejs.org/en/learn/command-line/how-to-read-environment-variables-from-nodejs).
|
||||
|
||||
## Performance Optimization
|
||||
|
||||
By the default, we are using `js-tiktoken` for tokenization. You can install `gpt-tokenizer` which is then automatically used by LlamaIndex to get a 60x speedup for tokenization:
|
||||
|
||||
```package-install
|
||||
npm i gpt-tokenizer
|
||||
```
|
||||
|
||||
**Note**: This only works for Node.js
|
||||
|
||||
## TypeScript support
|
||||
|
||||
<LinkCard
|
||||
title="Getting Started with LlamaIndex.TS in TypeScript"
|
||||
href="/docs/llamaindex/getting_started/installation/typescript"
|
||||
/>
|
||||
@@ -0,0 +1,99 @@
|
||||
---
|
||||
title: With TypeScript
|
||||
description: In this guide, you'll learn how to use LlamaIndex with TypeScript
|
||||
---
|
||||
|
||||
LlamaIndex.TS is written in TypeScript and designed to be used in TypeScript projects.
|
||||
|
||||
We put a lot of work on strong typing to make sure you have a great typing experience with code completion such as:
|
||||
|
||||
```ts twoslash
|
||||
import { PromptTemplate } from 'llamaindex'
|
||||
const promptTemplate = new PromptTemplate({
|
||||
template: `Context information from multiple sources is below.
|
||||
---------------------
|
||||
{context}
|
||||
---------------------
|
||||
Given the information from multiple sources and not prior knowledge.
|
||||
Answer the query in the style of a Shakespeare play"
|
||||
Query: {query}
|
||||
Answer:`,
|
||||
templateVars: ["context", "query"],
|
||||
});
|
||||
// @noErrors
|
||||
promptTemplate.format({
|
||||
c
|
||||
//^|
|
||||
})
|
||||
```
|
||||
|
||||
## Enable TypeScript
|
||||
|
||||
Make sure to set [moduleResolution](https://www.typescriptlang.org/docs/handbook/modules/theory.html#module-resolution) in your `tsconfig.json` file:
|
||||
|
||||
```json5
|
||||
{
|
||||
compilerOptions: {
|
||||
// ⬇️ add this line to your tsconfig.json
|
||||
moduleResolution: "bundler", // or "nodenext" | "node16" | "node"
|
||||
},
|
||||
}
|
||||
```
|
||||
|
||||
We recommend using `bundler` or `nodenext`, but due to popularity of `node`, we still added support for it.
|
||||
|
||||
## Enable AsyncIterable for `Web Stream` API
|
||||
|
||||
Some modules uses `Web Stream` API like `ReadableStream` and `WritableStream`, you need to enable `DOM.AsyncIterable` in your `tsconfig.json`.
|
||||
|
||||
```json5
|
||||
{
|
||||
compilerOptions: {
|
||||
// ⬇️ add this lib to your tsconfig.json
|
||||
lib: ["DOM.AsyncIterable"],
|
||||
},
|
||||
}
|
||||
```
|
||||
|
||||
```typescript
|
||||
import { tool } from 'llamaindex'
|
||||
import { agent } from "@llamaindex/workflow";
|
||||
import { openai } from "@llamaindex/openai";
|
||||
|
||||
Settings.llm = openai({
|
||||
model: "gpt-4o-mini",
|
||||
});
|
||||
|
||||
const addTool = tool({
|
||||
name: "add",
|
||||
description: "Adds two numbers",
|
||||
parameters: z.object({x: z.number(), y: z.number()}),
|
||||
execute: ({ x, y }) => x + y,
|
||||
});
|
||||
|
||||
const myAgent = agent({
|
||||
tools: [addTool],
|
||||
});
|
||||
|
||||
// Chat with the agent
|
||||
const context = myAgent.run("Hello, how are you?");
|
||||
|
||||
for await (const event of context) {
|
||||
if (event instanceof AgentStream) {
|
||||
for (const chunk of event.data.delta) {
|
||||
process.stdout.write(chunk); // stream response
|
||||
}
|
||||
} else {
|
||||
console.log(event); // other events
|
||||
}
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
## Run TypeScript Script in Node.js
|
||||
|
||||
We recommend to use [tsx](https://www.npmjs.com/package/tsx) to run TypeScript script in Node.js.
|
||||
|
||||
```shell
|
||||
node --import tsx ./my-script.ts
|
||||
```
|
||||
@@ -0,0 +1,24 @@
|
||||
---
|
||||
title: With Vite
|
||||
description: In this guide, you'll learn how to use LlamaIndex with Vite
|
||||
---
|
||||
import { Card, CardGrid, LinkCard, Icon, Aside } from '@astrojs/starlight/components';
|
||||
|
||||
Before you start, make sure you have try LlamaIndex.TS in Node.js to make sure you understand the basics.
|
||||
|
||||
<Card
|
||||
title="Getting Started with LlamaIndex.TS in Node.js"
|
||||
href="/docs/llamaindex/getting_started/installation/node"
|
||||
/>
|
||||
|
||||
Also, make sure you have a basic understanding of [Vite](https://vitejs.dev/).
|
||||
|
||||
## Why mention Vite?
|
||||
|
||||
Vite.js is widely used in building many web applications, like React.js, even for some native app like [Electron](https://www.electronjs.org/).
|
||||
|
||||
However, it's not a ready-to-use solution for a Node.js-like application using Vite, as Vite is designed for web applications(run in browser).
|
||||
|
||||
There's some plugin/framework based on Vite, like [Waku.gg](https://github.com/dai-shi/waku), or [Electron Vite](https://electron-vite.org/)
|
||||
|
||||
For now, we have no clear solution for bundling LlamaIndex.TS with Vite, if you have any idea/solution, please let us know.
|
||||
@@ -0,0 +1,4 @@
|
||||
{
|
||||
"title": "Getting Started",
|
||||
"pages": ["concepts", "installation", "create_llama", "examples"]
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
---
|
||||
title: What is LlamaIndex.TS
|
||||
description: LlamaIndex is the leading data framework for building LLM applications
|
||||
---
|
||||
import { SiBun, SiCloudflareworkers, SiDeno, SiNodedotjs } from '@icons-pack/react-simple-icons';
|
||||
|
||||
LlamaIndex is a framework for building context-augmented generative AI applications with LLMs including agents and workflows.
|
||||
|
||||
The TypeScript implementation is designed for JavaScript server side applications using <SiNodedotjs className="inline" color="#5FA04E" /> Node.js, <SiDeno className="inline" color="#70FFAF" /> Deno, <SiBun className="inline" /> Bun, <SiCloudflareworkers className="inline" color="#F38020" /> Cloudflare Workers, and more.
|
||||
|
||||
LlamaIndex.TS provides tools for beginners, advanced users, and everyone in between.
|
||||
|
||||
Try it out with a starter example using StackBlitz:
|
||||
|
||||
<iframe
|
||||
style={{ width: '100%', height: '440px' }}
|
||||
aria-label="LlamaIndex.TS Starter"
|
||||
aria-description="This is a starter example for LlamaIndex.TS, it shows the basic usage of the library."
|
||||
src="https://stackblitz.com/github/run-llama/LlamaIndexTS/tree/main/examples?embed=1&file=starter.ts"
|
||||
/>
|
||||
|
||||
You'll need an OpenAI API key to run this example. You can retrieve it from [OpenAI](https://platform.openai.com/api-keys).
|
||||
@@ -0,0 +1,28 @@
|
||||
---
|
||||
title: Langtrace
|
||||
description: Learn how to integrate LlamaIndex.TS with Langtrace.
|
||||
---
|
||||
|
||||
Enhance your observability with Langtrace, a robust open-source tool supports OpenTelemetry and is designed to trace, evaluate, and manage LLM applications seamlessly. Langtrace integrates directly with LlamaIndex, offering detailed, real-time insights into performance metrics such as accuracy, evaluations, and latency.
|
||||
|
||||
## Install
|
||||
|
||||
- Self-host or sign-up and generate an API key using [Langtrace](https://www.langtrace.ai) Cloud
|
||||
|
||||
```package-install
|
||||
npm i @langtrase/typescript-sdk
|
||||
```
|
||||
|
||||
## Initialize
|
||||
|
||||
```js
|
||||
import * as Langtrace from "@langtrase/typescript-sdk";
|
||||
Langtrace.init({ api_key: "<YOUR_API_KEY>" });
|
||||
```
|
||||
|
||||
Features:
|
||||
|
||||
- OpenTelemetry compliant, ensuring broad compatibility with observability platforms.
|
||||
- Provides comprehensive logs and detailed traces of all components.
|
||||
- Real-time monitoring of accuracy, evaluations, usage, costs, and latency.
|
||||
- For more configuration options and details, visit [Langtrace Docs](https://docs.langtrace.ai/introduction).
|
||||
@@ -0,0 +1,5 @@
|
||||
{
|
||||
"title": "Integration",
|
||||
"description": "See our integrations",
|
||||
"pages": ["open-llm-metry", "lang-trace", "vercel"]
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
---
|
||||
title: OpenLLMetry
|
||||
description: Learn how to integrate LlamaIndex.TS with OpenLLMetry.
|
||||
---
|
||||
|
||||
[OpenLLMetry](https://github.com/traceloop/openllmetry-js) is an open-source project based on OpenTelemetry for tracing and monitoring
|
||||
LLM applications. It connects to [all major observability platforms](https://www.traceloop.com/docs/openllmetry/integrations/introduction) and installs in minutes.
|
||||
|
||||
### Usage Pattern
|
||||
|
||||
```package-install
|
||||
npm i @traceloop/node-server-sdk
|
||||
```
|
||||
|
||||
```js
|
||||
import * as traceloop from "@traceloop/node-server-sdk";
|
||||
|
||||
traceloop.initialize({
|
||||
apiKey: process.env.TRACELOOP_API_KEY,
|
||||
disableBatch: true
|
||||
});
|
||||
```
|
||||
@@ -0,0 +1,102 @@
|
||||
---
|
||||
title: Vercel
|
||||
description: Integrate LlamaIndex with Vercel's AI SDK
|
||||
---
|
||||
|
||||
LlamaIndex provides integration with Vercel's AI SDK, allowing you to create powerful search and retrieval applications. You can:
|
||||
- Use any of Vercel AI's [model providers](https://sdk.vercel.ai/docs/foundations/providers-and-models) as LLMs in LlamaIndex
|
||||
- Use indexes (e.g. VectorStoreIndex, LlamaCloudIndex) from LlamaIndexTS in your Vercel AI applications
|
||||
|
||||
## Setup
|
||||
|
||||
First, install the required dependencies:
|
||||
|
||||
```package-install
|
||||
npm i @llamaindex/vercel ai
|
||||
```
|
||||
|
||||
## Using Vercel AI's Model Providers
|
||||
|
||||
Using the `VercelLLM` adapter, it's easy to use any of Vercel AI's [model providers](https://sdk.vercel.ai/docs/foundations/providers-and-models) as LLMs in LlamaIndex. Here's an example of how to use OpenAI's GPT-4o model:
|
||||
|
||||
```typescript
|
||||
const llm = new VercelLLM({ model: openai("gpt-4o") });
|
||||
const result = await llm.complete({
|
||||
prompt: "What is the capital of France?",
|
||||
stream: false, // Set to true if you want streaming responses
|
||||
});
|
||||
console.log(result.text);
|
||||
```
|
||||
|
||||
## Use Indexes
|
||||
|
||||
### Using VectorStoreIndex
|
||||
|
||||
Here's how to create a simple vector store index and query it using Vercel's AI SDK:
|
||||
|
||||
```typescript
|
||||
import { openai } from "@ai-sdk/openai";
|
||||
import { llamaindex } from "@llamaindex/vercel";
|
||||
import { streamText } from "ai";
|
||||
import { Document, VectorStoreIndex } from "llamaindex";
|
||||
|
||||
// Create an index from your documents
|
||||
const document = new Document({ text: yourText, id_: "unique-id" });
|
||||
const index = await VectorStoreIndex.fromDocuments([document]);
|
||||
|
||||
// Create a query tool
|
||||
const queryTool = llamaindex({
|
||||
model: openai("gpt-4"),
|
||||
index,
|
||||
description: "Search through the documents", // optional
|
||||
});
|
||||
|
||||
// Use the tool with Vercel's AI SDK
|
||||
streamText({
|
||||
model: openai("gpt-4"),
|
||||
prompt: "Your question here",
|
||||
tools: { queryTool },
|
||||
onFinish({ response }) {
|
||||
console.log("Response:", response.messages); // log the response
|
||||
},
|
||||
}).toDataStream();
|
||||
```
|
||||
|
||||
> Note: the Vercel AI model referenced in the `llamaindex` function is used by the response synthesizer to generate a response for the tool call.
|
||||
|
||||
### Using LlamaCloud
|
||||
|
||||
For production deployments, you can use LlamaCloud to store and manage your documents:
|
||||
|
||||
```typescript
|
||||
import { LlamaCloudIndex } from "@llamaindex/cloud";
|
||||
|
||||
// Create a LlamaCloud index
|
||||
const index = await LlamaCloudIndex.fromDocuments({
|
||||
documents: [document],
|
||||
name: "your-index-name",
|
||||
projectName: "your-project",
|
||||
apiKey: process.env.LLAMA_CLOUD_API_KEY,
|
||||
});
|
||||
|
||||
// Use it the same way as VectorStoreIndex
|
||||
const queryTool = llamaindex({
|
||||
model: openai("gpt-4"),
|
||||
index,
|
||||
description: "Search through the documents",
|
||||
options: { fields: ["sourceNodes", "messages"]}
|
||||
});
|
||||
|
||||
// Use the tool with Vercel's AI SDK
|
||||
streamText({
|
||||
model: openai("gpt-4"),
|
||||
prompt: "Your question here",
|
||||
tools: { queryTool },
|
||||
}).toDataStream();
|
||||
```
|
||||
|
||||
## Next Steps
|
||||
|
||||
1. Explore [LlamaCloud](https://cloud.llamaindex.ai/) for managed document storage and retrieval
|
||||
2. Join our [Discord community](https://discord.gg/dGcwcsnxhU) for support and discussions
|
||||
|
||||
@@ -0,0 +1,14 @@
|
||||
{
|
||||
"title": "LlamaIndex",
|
||||
"description": "The Data framework for LLM",
|
||||
"root": true,
|
||||
"pages": [
|
||||
"---Guide---",
|
||||
"index",
|
||||
"getting_started",
|
||||
"tutorials",
|
||||
"modules",
|
||||
"integration",
|
||||
"migration"
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,85 @@
|
||||
---
|
||||
title: Migrating from v0.8 to v0.9
|
||||
---
|
||||
|
||||
Version 0.9 of LlamaIndex.TS introduces significant architectural changes to improve package size and runtime compatibility. The main goals of this release are:
|
||||
|
||||
1. Reduce the package size of the main `llamaindex` package by moving dependencies into provider packages, making it more suitable for serverless environments
|
||||
2. Enable consistent code across different environments by using unified imports (no separate imports for Node.js and Edge runtimes)
|
||||
|
||||
## Major Changes
|
||||
|
||||
### Installing Provider Packages
|
||||
|
||||
In v0.9, you need to explicitly install the provider packages you want to use. The main `llamaindex` package no longer includes these dependencies by default.
|
||||
|
||||
### Updating Imports
|
||||
|
||||
You'll need to update your imports to get classes directly from their respective provider packages. Here's how to migrate different components:
|
||||
|
||||
### 1. AI Model Providers
|
||||
|
||||
Previously:
|
||||
```typescript
|
||||
import { OpenAI } from "llamaindex";
|
||||
```
|
||||
|
||||
Now:
|
||||
```typescript
|
||||
import { OpenAI } from "@llamaindex/openai";
|
||||
```
|
||||
|
||||
> Note: This examples requires installing the `@llamaindex/openai` package:
|
||||
|
||||
```package-install
|
||||
npm i @llamaindex/openai
|
||||
```
|
||||
|
||||
For more details on available AI model providers and their configuration, see the [LLMs documentation](/docs/llamaindex/modules/models/llms) and the [Embedding Models documentation](/docs/llamaindex/modules/models/embeddings).
|
||||
|
||||
### 2. Storage Providers
|
||||
|
||||
Previously:
|
||||
```typescript
|
||||
import { PineconeVectorStore } from "llamaindex";
|
||||
```
|
||||
|
||||
Now:
|
||||
```typescript
|
||||
import { PineconeVectorStore } from "@llamaindex/pinecone";
|
||||
```
|
||||
|
||||
For more information about available storage options, refer to the [Data Stores documentation](/docs/llamaindex/modules/data/stores).
|
||||
|
||||
### 3. Data Loaders
|
||||
|
||||
Previously:
|
||||
```typescript
|
||||
import { SimpleDirectoryReader } from "llamaindex";
|
||||
```
|
||||
|
||||
Now:
|
||||
```typescript
|
||||
import { SimpleDirectoryReader } from "@llamaindex/readers/directory";
|
||||
```
|
||||
|
||||
For more details about available data loaders and their usage, check the [Loading Data](/docs/llamaindex/modules/data/readers).
|
||||
|
||||
### 4. Prefer using `llamaindex` instead of `@llamaindex/core`
|
||||
|
||||
`llamaindex` is now re-exporting most of `@llamaindex/core`. To simplify imports, just use `import { ... } from "llamaindex"` instead of `import { ... } from "@llamaindex/core"`. This is possible because `llamaindex` is now a smaller package.
|
||||
|
||||
We might change imports internally in `@llamaindex/core` in the future. Let us know if you're missing something.
|
||||
|
||||
## Benefits of the Changes
|
||||
|
||||
- **Smaller Bundle Size**: By moving dependencies to separate packages, your application only includes the features you actually use
|
||||
- **Runtime Consistency**: The same code works across different environments without environment-specific imports
|
||||
- **Improved Serverless Support**: Reduced package size makes it easier to deploy to serverless environments with size limitations
|
||||
|
||||
## Need Help?
|
||||
|
||||
If you encounter any issues during migration, please:
|
||||
1. Check our [GitHub repository](https://github.com/run-llama/LlamaIndexTS) for the latest updates
|
||||
2. Join our [Discord community](https://discord.gg/dGcwcsnxhU) for support
|
||||
3. Open an issue on GitHub if you find a bug or have a feature request
|
||||
@@ -0,0 +1,28 @@
|
||||
---
|
||||
title: Agents
|
||||
---
|
||||
|
||||
**Note**: Agents are deprecated, use [Agent Workflows](/docs/llamaindex/modules/agents/agent_workflow) instead.
|
||||
|
||||
An “agent” is an automated reasoning and decision engine. It takes in a user input/query and can make internal decisions for executing that query in order to return the correct result. The key agent components can include, but are not limited to:
|
||||
|
||||
- Breaking down a complex question into smaller ones
|
||||
- Choosing an external Tool to use + coming up with parameters for calling the Tool
|
||||
- Planning out a set of tasks
|
||||
- Storing previously completed tasks in a memory module
|
||||
|
||||
## Getting Started
|
||||
|
||||
LlamaIndex.TS comes with a few built-in agents, but you can also create your own. The built-in agents include:
|
||||
|
||||
- OpenAI Agent
|
||||
- Anthropic Agent both via Anthropic and Bedrock (in `@llamaIndex/community`)
|
||||
- Gemini Agent
|
||||
- ReACT Agent
|
||||
- Meta3.1 504B via Bedrock (in `@llamaIndex/community`)
|
||||
|
||||
## Api References
|
||||
|
||||
- [OpenAIAgent](/docs/api/classes/OpenAIAgent)
|
||||
- [AnthropicAgent](/docs/api/classes/AnthropicAgent)
|
||||
- [ReActAgent](/docs/api/classes/ReActAgent)
|
||||
@@ -0,0 +1,5 @@
|
||||
{
|
||||
"title": "Migration",
|
||||
"description": "Migration between different versions",
|
||||
"pages": ["0.8-to-0.9", "deprecated"]
|
||||
}
|
||||
@@ -0,0 +1,118 @@
|
||||
---
|
||||
title: Agent Workflows
|
||||
---
|
||||
|
||||
|
||||
Agent Workflows are a powerful system that enables you to create and orchestrate one or multiple agents with tools to perform specific tasks. It's built on top of the base [`Workflow`](/docs/llamaindex/modules/agents/workflows) system and provides a streamlined interface for agent interactions.
|
||||
|
||||
## Usage
|
||||
|
||||
### Single Agent Workflow
|
||||
|
||||
The simplest use case is creating a single agent with specific tools. Here's an example of creating an assistant that tells jokes:
|
||||
|
||||
```typescript
|
||||
import { tool } from "llamaindex";
|
||||
import { agent } from "@llamaindex/workflow";
|
||||
import { openai } from "@llamaindex/openai";
|
||||
|
||||
// Define a joke-telling tool
|
||||
const jokeTool = tool(
|
||||
() => "Baby Llama is called cria",
|
||||
{
|
||||
name: "joke",
|
||||
description: "Use this tool to get a joke",
|
||||
}
|
||||
);
|
||||
|
||||
// Create an single agent workflow with the tool
|
||||
const jokeAgent = agent({
|
||||
tools: [jokeTool],
|
||||
llm: openai({ model: "gpt-4o-mini" }),
|
||||
});
|
||||
|
||||
// Run the workflow
|
||||
const result = await jokeAgent.run("Tell me something funny");
|
||||
console.log(result); // Baby Llama is called cria
|
||||
```
|
||||
|
||||
### Event Streaming
|
||||
|
||||
Agent Workflows provide a unified interface for event streaming, making it easy to track and respond to different events during execution:
|
||||
|
||||
```typescript
|
||||
import { agentToolCallEvent, agentStreamEvent } from "@llamaindex/workflow";
|
||||
|
||||
// Get the workflow execution context
|
||||
const events = workflow.runStream("Tell me something funny");
|
||||
|
||||
// Stream and handle events
|
||||
for await (const event of events) {
|
||||
if (agentToolCallEvent.include(event)) {
|
||||
console.log(`Tool being called: ${event.data.toolName}`);
|
||||
}
|
||||
if (agentStreamEvent.include(event)) {
|
||||
process.stdout.write(event.data.delta);
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Multi-Agent Workflow
|
||||
|
||||
An Agent Workflow can orchestrate multiple agents, enabling complex interactions and task handoffs. Each agent in a multi-agent workflow requires:
|
||||
|
||||
- `name`: Unique identifier for the agent
|
||||
- `description`: Purpose description used for task routing
|
||||
- `tools`: Array of tools the agent can use
|
||||
- `canHandoffTo` (optional): Array of agent names or agent instances that this agent can delegate tasks to
|
||||
|
||||
Here's an example of a multi-agent system that combines joke-telling and weather information:
|
||||
|
||||
```typescript
|
||||
import { tool } from "llamaindex";
|
||||
import { multiAgent, agent } from "@llamaindex/workflow";
|
||||
import { openai } from "@llamaindex/openai";
|
||||
import { z } from "zod";
|
||||
|
||||
// Create a weather agent
|
||||
const weatherAgent = agent({
|
||||
name: "WeatherAgent",
|
||||
description: "Provides weather information for any city",
|
||||
tools: [
|
||||
tool(
|
||||
{
|
||||
name: "fetchWeather",
|
||||
description: "Get weather information for a city",
|
||||
parameters: z.object({
|
||||
city: z.string(),
|
||||
}),
|
||||
execute: ({ city }) => `The weather in ${city} is sunny`,
|
||||
}
|
||||
),
|
||||
],
|
||||
llm: openai({ model: "gpt-4o-mini" }),
|
||||
});
|
||||
|
||||
// Create a joke-telling agent
|
||||
const jokeAgent = agent({
|
||||
name: "JokeAgent",
|
||||
description: "Tells jokes and funny stories",
|
||||
tools: [jokeTool], // Using the joke tool defined earlier
|
||||
llm: openai({ model: "gpt-4o-mini" }),
|
||||
canHandoffTo: [weatherAgent], // Can hand off to the weather agent
|
||||
});
|
||||
|
||||
// Create the multi-agent workflow
|
||||
const agents = multiAgent({
|
||||
agents: [jokeAgent, weatherAgent],
|
||||
rootAgent: jokeAgent, // Start with the joke agent
|
||||
});
|
||||
|
||||
// Run the workflow
|
||||
const result = await agents.run(
|
||||
"Give me a morning greeting with a joke and the weather in San Francisco"
|
||||
);
|
||||
```
|
||||
|
||||
The workflow will coordinate between agents, allowing them to handle different aspects of the request and hand off tasks when appropriate.
|
||||
|
||||
@@ -0,0 +1,4 @@
|
||||
{
|
||||
"title": "Agents",
|
||||
"pages": ["tool", "agent_workflow", "workflows"]
|
||||
}
|
||||
@@ -0,0 +1,144 @@
|
||||
---
|
||||
title: Tools
|
||||
---
|
||||
|
||||
A "tool" is a utility that can be called by an agent on behalf of an LLM.
|
||||
A tool can be called to perform custom actions, or retrieve extra information based on the LLM-generated input.
|
||||
A result from a tool call can be used by subsequent steps in a workflow, or to compute a final answer.
|
||||
For example, a "weather tool" could fetch some live weather information from a geographical location.
|
||||
|
||||
## Tool Function
|
||||
|
||||
The `tool` function is a utility provided to define a tool that can be used by an agent. It takes a function and a configuration object as arguments. The configuration object includes the tool's name, description, and parameters.
|
||||
|
||||
### Parameters with Zod
|
||||
|
||||
The `parameters` field in the tool configuration is defined using `zod`, a TypeScript-first schema declaration and validation library. `zod` allows you to specify the expected structure and types of the input parameters, ensuring that the data passed to the tool is valid.
|
||||
|
||||
Example:
|
||||
```ts
|
||||
import { tool } from "llamaindex";
|
||||
import { agent } from "@llamaindex/workflow";
|
||||
import { z } from "zod";
|
||||
|
||||
// first arg is LLM input, second is bound arg
|
||||
const queryKnowledgeBase = async ({ question }, { userToken }) => {
|
||||
const response = await fetch(`https://knowledge-base.com?token=${userToken}&query=${question}`);
|
||||
// ...
|
||||
};
|
||||
|
||||
// define tool with zod validation
|
||||
const kbTool = tool(queryKnowledgeBase, {
|
||||
name: 'queryKnowledgeBase',
|
||||
description: 'Query knowledge base',
|
||||
parameters: z.object({
|
||||
question: z.string({
|
||||
description: 'The user question',
|
||||
}),
|
||||
}),
|
||||
});
|
||||
|
||||
```
|
||||
In this example, `z.object` is used to define a schema for the `parameters` where `question` is expected to be a string. This ensures that any input to the tool adheres to the specified structure, providing a layer of type safety and validation.
|
||||
|
||||
|
||||
## Built-in tools
|
||||
|
||||
You can import built-in tools from the `@llamaindex/tools` package.
|
||||
|
||||
```ts
|
||||
import { agent } from "@llamaindex/workflow";
|
||||
import { wiki } from "@llamaindex/tools";
|
||||
|
||||
const researchAgent = agent({
|
||||
name: "WikiAgent",
|
||||
description: "Gathering information from the internet",
|
||||
systemPrompt: `You are a research agent. Your role is to gather information from the internet using the provided tools.`,
|
||||
tools: [wiki()],
|
||||
});
|
||||
```
|
||||
|
||||
## MCP tools
|
||||
|
||||
If you have a MCP server running, you can fetch tools from the server and use them in your agents.
|
||||
|
||||
```ts
|
||||
// 1. Import MCP tools adapter
|
||||
import { mcp } from "@llamaindex/tools";
|
||||
import { agent } from "@llamaindex/workflow";
|
||||
|
||||
// 2. Initialize a MCP client
|
||||
// by npx
|
||||
const server = mcp({
|
||||
command: "npx",
|
||||
args: ["-y", "@modelcontextprotocol/server-filesystem", "."],
|
||||
verbose: true,
|
||||
});
|
||||
// or by SSE
|
||||
const server = mcp({
|
||||
url: "http://localhost:8000/mcp",
|
||||
verbose: true,
|
||||
});
|
||||
|
||||
// 3. Get tools from MCP server
|
||||
const tools = await server.tools();
|
||||
|
||||
// Now you can create an agent with the tools
|
||||
const agent = agent({
|
||||
name: "My Agent",
|
||||
systemPrompt: "You are a helpful assistant that can use the provided tools to answer questions.",
|
||||
llm: openai({ model: "gpt-4o" }),
|
||||
tools: tools,
|
||||
});
|
||||
```
|
||||
|
||||
|
||||
## Function tool
|
||||
|
||||
You can still use the `FunctionTool` class to define a tool.
|
||||
A `FunctionTool` is constructed from a function with signature
|
||||
```ts
|
||||
(input: T, additionalArg?: AdditionalToolArgument) => R
|
||||
```
|
||||
where
|
||||
- `input` is generated by the LLM, `T` is the type defined by the tool `parameters`
|
||||
- `additionalArg` is an optional extra argument, see "Binding" below
|
||||
- `R` is the return type
|
||||
|
||||
### Binding
|
||||
|
||||
An additional argument can be bound to a tool, each tool call will be passed
|
||||
- the input provided by the LLM
|
||||
- the additional argument (extends object)
|
||||
|
||||
Note: calling the `bind` method will return a new `FunctionTool` instance, without modifying the tool which `bind` is called on.
|
||||
|
||||
Example to pass a `userToken` as additional argument:
|
||||
```ts
|
||||
import { tool } from "llamaindex";
|
||||
import { agent } from "@llamaindex/workflow";
|
||||
|
||||
// first arg is LLM input, second is bound arg
|
||||
const queryKnowledgeBase = async ({ question }, { userToken }) => {
|
||||
const response = await fetch(`https://knowledge-base.com?token=${userToken}&query=${question}`);
|
||||
// ...
|
||||
};
|
||||
|
||||
// define tool as usual
|
||||
const kbTool = tool(queryKnowledgeBase, {
|
||||
name: 'queryKnowledgeBase',
|
||||
description: 'Query knowledge base',
|
||||
parameters: z.object({
|
||||
question: z.string({
|
||||
description: 'The user question',
|
||||
}),
|
||||
}),
|
||||
});
|
||||
|
||||
// create an agent
|
||||
const additionalArg = { userToken: 'abcd1234' };
|
||||
const workflow = agent({
|
||||
tools: [kbTool.bind(additionalArg)],
|
||||
// llm, systemPrompt etc
|
||||
})
|
||||
```
|
||||
@@ -0,0 +1,18 @@
|
||||
---
|
||||
title: Workflows
|
||||
---
|
||||
|
||||
A `Workflow` in LlamaIndex is a lightweight, event-driven abstraction used to chain together several events. Workflows are made up of `handlers`, with each one responsible for processing specific event types and emitting new events.
|
||||
|
||||
Workflows are designed to be flexible and can be used to build agents, RAG flows, extraction flows, or anything else you want to implement.
|
||||
|
||||
To use workflows install this package:
|
||||
|
||||
```package-install
|
||||
npm i @llamaindex/workflow
|
||||
```
|
||||
|
||||
This package is a stable, production-ready version of our [llama-flow](/docs/llamaflow) project.
|
||||
|
||||
While you can still reference the llama-flow documentation for detailed information about the underlying concepts, we recommend using the `@llamaindex/workflow` package for all new projects to ensure stability and long-term availability.
|
||||
|
||||
@@ -0,0 +1,24 @@
|
||||
---
|
||||
title: Index
|
||||
---
|
||||
|
||||
An index is the basic container for organizing your data. Besides managed indexes using [LlamaCloud](/docs/llamaindex/modules/data/data_index/managed), LlamaIndex.TS supports three indexes:
|
||||
|
||||
|
||||
- `VectorStoreIndex` - will send the top-k `Node`s to the LLM when generating a response. The default top-k is 2.
|
||||
- `SummaryIndex` - will send every `Node` in the index to the LLM in order to generate a response
|
||||
- `KeywordTableIndex` extracts and provides keywords from `Node`s to the LLM
|
||||
|
||||
```typescript
|
||||
import { Document, VectorStoreIndex } from "llamaindex";
|
||||
|
||||
const document = new Document({ text: "test" });
|
||||
|
||||
const index = await VectorStoreIndex.fromDocuments([document]);
|
||||
```
|
||||
|
||||
## API Reference
|
||||
|
||||
- [SummaryIndex](/docs/api/classes/SummaryIndex)
|
||||
- [VectorStoreIndex](/docs/api/classes/VectorStoreIndex)
|
||||
- [KeywordTableIndex](/docs/api/classes/KeywordTableIndex)
|
||||
@@ -0,0 +1,32 @@
|
||||
---
|
||||
title: Managed Index
|
||||
description: Managed index using LlamaCloud
|
||||
---
|
||||
|
||||
LlamaCloud is a new generation of managed parsing, ingestion, and retrieval services, designed to bring production-grade context-augmentation to your LLM and RAG applications.
|
||||
|
||||
LlamaCloud supports
|
||||
|
||||
- Managed Ingestion API, handling parsing and document management
|
||||
- Managed Retrieval API, configuring optimal retrieval for your RAG system
|
||||
|
||||
## Access
|
||||
|
||||
Visit [LlamaCloud](https://cloud.llamaindex.ai) to sign in and get an API key.
|
||||
|
||||
## Create a Managed Index
|
||||
|
||||
Here's an example of how to create a managed index by ingesting a couple of documents:
|
||||
|
||||
<include cwd>../../examples/cloud/chat.ts</include>
|
||||
|
||||
## Use a Managed Index
|
||||
|
||||
Here's an example of how to use a managed index together with a chat engine:
|
||||
|
||||
<include cwd>../../examples/cloud/from-documents.ts</include>
|
||||
|
||||
## API Reference
|
||||
|
||||
- [LlamaCloudIndex](/docs/api/classes/LlamaCloudIndex)
|
||||
- [LlamaCloudRetriever](/docs/api/classes/LlamaCloudRetriever)
|
||||
@@ -0,0 +1,17 @@
|
||||
---
|
||||
title: Documents and Nodes
|
||||
description: Data structure for storing data in LlamaIndex
|
||||
---
|
||||
|
||||
`Document`s and `Node`s are the basic building blocks of data in LlamaIndexTS. While the API for these objects is similar, `Document` objects represent entire files, while `Node`s are smaller pieces of that original document, that are suitable for an LLM and Q&A.
|
||||
|
||||
```typescript
|
||||
import { Document } from "llamaindex";
|
||||
|
||||
document = new Document({ text: "text", metadata: { key: "val" } });
|
||||
```
|
||||
|
||||
## API Reference
|
||||
|
||||
- [Document](/docs/api/classes/Document)
|
||||
- [TextNode](/docs/api/classes/TextNode)
|
||||
@@ -0,0 +1,110 @@
|
||||
---
|
||||
title: Ingestion Pipeline
|
||||
---
|
||||
|
||||
An `IngestionPipeline` uses a concept of `Transformations` that are applied to input data.
|
||||
These `Transformations` are applied to your input data, and the resulting nodes are either returned or inserted into a vector database (if given).
|
||||
|
||||
## Installation
|
||||
|
||||
```package-install
|
||||
npm i llamaindex @llamaindex/openai @llamaindex/qdrant
|
||||
```
|
||||
|
||||
## Usage Pattern
|
||||
|
||||
The simplest usage is to instantiate an IngestionPipeline like so:
|
||||
|
||||
```ts
|
||||
import fs from "node:fs/promises";
|
||||
import { OpenAI, OpenAIEmbedding } from "@llamaindex/openai";
|
||||
import {
|
||||
Document,
|
||||
IngestionPipeline,
|
||||
MetadataMode,
|
||||
TitleExtractor,
|
||||
SentenceSplitter,
|
||||
} from "llamaindex";
|
||||
|
||||
async function main() {
|
||||
// Load essay from abramov.txt in Node
|
||||
const path = "node_modules/llamaindex/examples/abramov.txt";
|
||||
|
||||
const essay = await fs.readFile(path, "utf-8");
|
||||
|
||||
// Create Document object with essay
|
||||
const document = new Document({ text: essay, id_: path });
|
||||
const pipeline = new IngestionPipeline({
|
||||
transformations: [
|
||||
new SentenceSplitter({ chunkSize: 1024, chunkOverlap: 20 }),
|
||||
new TitleExtractor(),
|
||||
new OpenAIEmbedding(),
|
||||
],
|
||||
});
|
||||
|
||||
// run the pipeline
|
||||
const nodes = await pipeline.run({ documents: [document] });
|
||||
|
||||
// print out the result of the pipeline run
|
||||
for (const node of nodes) {
|
||||
console.log(node.getContent(MetadataMode.NONE));
|
||||
}
|
||||
}
|
||||
|
||||
main().catch(console.error);
|
||||
```
|
||||
|
||||
## Connecting to Vector Databases
|
||||
|
||||
When running an ingestion pipeline, you can also chose to automatically insert the resulting nodes into a remote vector store.
|
||||
|
||||
Then, you can construct an index from that vector store later on.
|
||||
|
||||
```ts
|
||||
import fs from "node:fs/promises";
|
||||
|
||||
import { OpenAIEmbedding } from "@llamaindex/openai";
|
||||
import { QdrantVectorStore } from "@llamaindex/qdrant";
|
||||
import {
|
||||
Document,
|
||||
IngestionPipeline,
|
||||
MetadataMode,
|
||||
TitleExtractor,
|
||||
SentenceSplitter,
|
||||
VectorStoreIndex,
|
||||
} from "llamaindex";
|
||||
|
||||
async function main() {
|
||||
// Load essay from abramov.txt in Node
|
||||
const path = "node_modules/llamaindex/examples/abramov.txt";
|
||||
|
||||
const essay = await fs.readFile(path, "utf-8");
|
||||
|
||||
const vectorStore = new QdrantVectorStore({
|
||||
host: "http://localhost:6333",
|
||||
});
|
||||
|
||||
// Create Document object with essay
|
||||
const document = new Document({ text: essay, id_: path });
|
||||
const pipeline = new IngestionPipeline({
|
||||
transformations: [
|
||||
new SentenceSplitter({ chunkSize: 1024, chunkOverlap: 20 }),
|
||||
new TitleExtractor(),
|
||||
new OpenAIEmbedding(),
|
||||
],
|
||||
vectorStore,
|
||||
});
|
||||
|
||||
// run the pipeline
|
||||
const nodes = await pipeline.run({ documents: [document] });
|
||||
|
||||
// create an index
|
||||
const index = VectorStoreIndex.fromVectorStore(vectorStore);
|
||||
}
|
||||
|
||||
main().catch(console.error);
|
||||
```
|
||||
|
||||
## API Reference
|
||||
|
||||
- [IngestionPipeline](/docs/api/classes/IngestionPipeline)
|
||||
@@ -0,0 +1,83 @@
|
||||
---
|
||||
title: Transformations
|
||||
---
|
||||
|
||||
A transformation is something that takes a list of nodes as an input, and returns a list of nodes. Each component that implements the Transformation class has both a `transform` definition responsible for transforming the nodes.
|
||||
|
||||
Currently, the following components are Transformation objects:
|
||||
|
||||
- [SentenceSplitter](/docs/llamaindex/modules/data/ingestion_pipeline/transformations/node-parser)
|
||||
- [MetadataExtractor](/docs/llamaindex/modules/data/ingestion_pipeline/transformations/metadata_extraction)
|
||||
- [Embeddings](/docs/llamaindex/modules/models/embeddings)
|
||||
|
||||
## Usage Pattern
|
||||
|
||||
While transformations are best used with with an IngestionPipeline, they can also be used directly.
|
||||
|
||||
```ts
|
||||
import { SentenceSplitter, TitleExtractor, Document } from "llamaindex";
|
||||
|
||||
async function main() {
|
||||
let nodes = new SentenceSplitter().getNodesFromDocuments([
|
||||
new Document({ text: "I am 10 years old. John is 20 years old." }),
|
||||
]);
|
||||
|
||||
const titleExtractor = new TitleExtractor();
|
||||
|
||||
nodes = await titleExtractor.transform(nodes);
|
||||
|
||||
for (const node of nodes) {
|
||||
console.log(node.getContent(MetadataMode.NONE));
|
||||
}
|
||||
}
|
||||
|
||||
main().catch(console.error);
|
||||
```
|
||||
|
||||
## Custom Transformations
|
||||
|
||||
You can implement any transformation yourself by implementing the `TransformComponent`.
|
||||
|
||||
The following custom transformation will remove any special characters or punctuation in text.
|
||||
|
||||
```ts
|
||||
import { TransformComponent, TextNode } from "llamaindex";
|
||||
|
||||
export class RemoveSpecialCharacters extends TransformComponent {
|
||||
async transform(nodes: TextNode[]): Promise<TextNode[]> {
|
||||
for (const node of nodes) {
|
||||
node.text = node.text.replace(/[^\w\s]/gi, "");
|
||||
}
|
||||
|
||||
return nodes;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
These can then be used directly or in any IngestionPipeline.
|
||||
|
||||
```ts
|
||||
import { IngestionPipeline, Document } from "llamaindex";
|
||||
|
||||
async function main() {
|
||||
const pipeline = new IngestionPipeline({
|
||||
transformations: [new RemoveSpecialCharacters()],
|
||||
});
|
||||
|
||||
const nodes = await pipeline.run({
|
||||
documents: [
|
||||
new Document({ text: "I am 10 years old. John is 20 years old." }),
|
||||
],
|
||||
});
|
||||
|
||||
for (const node of nodes) {
|
||||
console.log(node.getContent(MetadataMode.NONE));
|
||||
}
|
||||
}
|
||||
|
||||
main().catch(console.error);
|
||||
```
|
||||
|
||||
## API Reference
|
||||
|
||||
- [TransformComponent](/docs/api/classes/TransformComponent)
|
||||
+49
@@ -0,0 +1,49 @@
|
||||
---
|
||||
title: Metadata Extraction
|
||||
---
|
||||
|
||||
You can use LLMs to automate metadata extraction with our `Metadata Extractor` modules.
|
||||
|
||||
Our metadata extractor modules include the following "feature extractors":
|
||||
|
||||
- `SummaryExtractor` - automatically extracts a summary over a set of Nodes
|
||||
- `QuestionsAnsweredExtractor` - extracts a set of questions that each Node can answer
|
||||
- `TitleExtractor` - extracts a title over the context of each Node by document and combine them
|
||||
- `KeywordExtractor` - extracts keywords over the context of each Node
|
||||
|
||||
Then you can chain the `Metadata Extractors` with the `IngestionPipeline` to extract metadata from a set of documents.
|
||||
|
||||
```ts
|
||||
import { Document, IngestionPipeline, TitleExtractor, QuestionsAnsweredExtractor } from "llamaindex";
|
||||
import { OpenAI } from "@llamaindex/openai";
|
||||
|
||||
async function main() {
|
||||
const pipeline = new IngestionPipeline({
|
||||
transformations: [
|
||||
new TitleExtractor(),
|
||||
new QuestionsAnsweredExtractor({
|
||||
questions: 5,
|
||||
}),
|
||||
],
|
||||
});
|
||||
|
||||
const nodes = await pipeline.run({
|
||||
documents: [
|
||||
new Document({ text: "I am 10 years old. John is 20 years old." }),
|
||||
],
|
||||
});
|
||||
|
||||
for (const node of nodes) {
|
||||
console.log(node.metadata);
|
||||
}
|
||||
}
|
||||
|
||||
main().then(() => console.log("done"));
|
||||
```
|
||||
|
||||
## API Reference
|
||||
|
||||
- [SummaryExtractor](/docs/api/classes/SummaryExtractor)
|
||||
- [QuestionsAnsweredExtractor](/docs/api/classes/QuestionsAnsweredExtractor)
|
||||
- [TitleExtractor](/docs/api/classes/TitleExtractor)
|
||||
- [KeywordExtractor](/docs/api/classes/KeywordExtractor)
|
||||
@@ -0,0 +1,193 @@
|
||||
---
|
||||
title: Node Parsers / Text Splitters
|
||||
description: Learn how to use Node Parsers and Text Splitters to extract data from documents.
|
||||
---
|
||||
import { Tabs, TabItem } from '@astrojs/starlight/components';
|
||||
|
||||
Node parsers are a simple abstraction that take a list of `Document` objects, and chunk them into `Node` objects, such that each node is a specific chunk of the parent document. When a document is broken into nodes, all of it's attributes are inherited to the children nodes (i.e. `metadata`, text and metadata templates, etc.). You can read more about `Node` and `Document` properties [here](/docs/llamaindex/modules/data).
|
||||
|
||||
By default, we will use `Settings.nodeParser` to split the document into nodes. You can also assign a custom `NodeParser` to the `Settings` object.
|
||||
|
||||
## SentenceSplitter
|
||||
|
||||
The `SentenceSplitter` is the default `NodeParser` in LlamaIndex. It will split the text from a `Document` into sentences.
|
||||
|
||||
```ts twoslash
|
||||
import { TextFileReader } from '@llamaindex/readers/text'
|
||||
import { SentenceSplitter } from 'llamaindex';
|
||||
import { Settings } from 'llamaindex';
|
||||
|
||||
const nodeParser = new SentenceSplitter();
|
||||
Settings.nodeParser = nodeParser;
|
||||
// ^?
|
||||
```
|
||||
|
||||
The underlying text splitter will split text by sentences. It can also be used as a standalone module for splitting raw text.
|
||||
|
||||
```ts twoslash
|
||||
import { SentenceSplitter } from "llamaindex";
|
||||
|
||||
const splitter = new SentenceSplitter({ chunkSize: 1 });
|
||||
|
||||
const texts = splitter.splitText("Hello World");
|
||||
// ^?
|
||||
```
|
||||
|
||||
## MarkdownNodeParser
|
||||
|
||||
The `MarkdownNodeParser` is a more advanced `NodeParser` that can handle markdown documents. It will split the markdown into nodes and then parse the nodes into a `Document` object.
|
||||
|
||||
<Tabs>
|
||||
<TabItem label="with reader">
|
||||
```ts twoslash
|
||||
import { MarkdownNodeParser } from "llamaindex";
|
||||
import { MarkdownReader } from '@llamaindex/readers/markdown'
|
||||
|
||||
const reader = new MarkdownReader();
|
||||
const markdownNodeParser = new MarkdownNodeParser();
|
||||
|
||||
const documents = await reader.loadData('path/to/file.md');
|
||||
const parsedDocuments = markdownNodeParser(documents);
|
||||
// ^?
|
||||
|
||||
```
|
||||
</TabItem>
|
||||
<TabItem label="with node:fs">
|
||||
```ts twoslash tab="with node:fs"
|
||||
import fs from 'node:fs/promises';
|
||||
import { MarkdownNodeParser, Document } from "llamaindex";
|
||||
|
||||
const markdownNodeParser = new MarkdownNodeParser();
|
||||
const text = await fs.readFile('path/to/file.md', 'utf-8');
|
||||
const document = new Document({ text });
|
||||
|
||||
const parsedDocuments = markdownNodeParser([document]);
|
||||
// ^?
|
||||
|
||||
```
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
The output metadata will be something like:
|
||||
|
||||
```bash
|
||||
[
|
||||
TextNode {
|
||||
id_: '008e41a8-b097-487c-bee8-bd88b9455844',
|
||||
metadata: { 'Header 1': 'Main Header' },
|
||||
excludedEmbedMetadataKeys: [],
|
||||
excludedLlmMetadataKeys: [],
|
||||
relationships: { PARENT: [Array] },
|
||||
hash: 'KJ5e/um/RkHaNR6bonj9ormtZY7I8i4XBPVYHXv1A5M=',
|
||||
text: 'Main Header\nMain content',
|
||||
textTemplate: '',
|
||||
metadataSeparator: '\n'
|
||||
},
|
||||
TextNode {
|
||||
id_: '0f5679b3-ba63-4aff-aedc-830c4208d0b5',
|
||||
metadata: { 'Header 1': 'Header 2' },
|
||||
excludedEmbedMetadataKeys: [],
|
||||
excludedLlmMetadataKeys: [],
|
||||
relationships: { PARENT: [Array] },
|
||||
hash: 'IP/g/dIld3DcbK+uHzDpyeZ9IdOXY4brxhOIe7wc488=',
|
||||
text: 'Header 2\nHeader 2 content',
|
||||
textTemplate: '',
|
||||
metadataSeparator: '\n'
|
||||
},
|
||||
TextNode {
|
||||
id_: 'e81e9bd0-121c-4ead-8ca7-1639d65fdf90',
|
||||
metadata: { 'Header 1': 'Header 2', 'Header 2': 'Sub-header' },
|
||||
excludedEmbedMetadataKeys: [],
|
||||
excludedLlmMetadataKeys: [],
|
||||
relationships: { PARENT: [Array] },
|
||||
hash: 'B3kYNnxaYi9ghtAgwza0ZEVKF4MozobkNUlcekDL7JQ=',
|
||||
text: 'Sub-header\nSub-header content',
|
||||
textTemplate: '',
|
||||
metadataSeparator: '\n'
|
||||
}
|
||||
]
|
||||
```
|
||||
|
||||
## CodeSplitter
|
||||
|
||||
The `CodeSplitter` is a more advanced `NodeParser` that can handle code documents.
|
||||
It will split the code by AST nodes and then parse the nodes into a `Document` object.
|
||||
|
||||
<Tabs items={["with reader", "with node:fs"]}>
|
||||
```ts twoslash tab="with reader"
|
||||
import { TextFileReader } from '@llamaindex/readers/text'
|
||||
import { CodeSplitter } from '@llamaindex/node-parser/code'
|
||||
import Parser from "tree-sitter";
|
||||
import TS from "tree-sitter-typescript";
|
||||
|
||||
const parser = new Parser();
|
||||
parser.setLanguage(TS.typescript as Parser.Language);
|
||||
const codeSplitter = new CodeSplitter({
|
||||
getParser: () => parser,
|
||||
});
|
||||
const reader = new TextFileReader();
|
||||
const documents = await reader.loadData('path/to/file.ts');
|
||||
|
||||
const parsedDocuments = codeSplitter(documents);
|
||||
// ^?
|
||||
```
|
||||
|
||||
```ts twoslash tab="with node:fs"
|
||||
import fs from 'node:fs/promises';
|
||||
import { CodeSplitter } from '@llamaindex/node-parser/code'
|
||||
import Parser from "tree-sitter";
|
||||
import TS from "tree-sitter-typescript";
|
||||
|
||||
const parser = new Parser();
|
||||
parser.setLanguage(TS.typescript as Parser.Language);
|
||||
const codeSplitter = new CodeSplitter({
|
||||
getParser: () => parser,
|
||||
});
|
||||
|
||||
const parsedDocuments = codeSplitter.splitText(await fs.readFile('path/to/file.ts', 'utf-8'));
|
||||
// ^?
|
||||
```
|
||||
</Tabs>
|
||||
|
||||
You might setup WASM files for `web-tree-sitter` and use it in the browser.
|
||||
|
||||
```ts
|
||||
import Parser from 'web-tree-sitter';
|
||||
|
||||
Parser.init({
|
||||
locateFile(scriptName: string) {
|
||||
return '/' + scriptName
|
||||
},
|
||||
}).then(async () => {
|
||||
const parser = new Parser();
|
||||
const Lang = await Parser.Language.load('/tree-sitter-typescript.wasm');
|
||||
parser.setLanguage(Lang);
|
||||
return new CodeSplitter({
|
||||
getParser: () => parser,
|
||||
maxChars: 100
|
||||
});
|
||||
});
|
||||
```
|
||||
|
||||
In this example, you should put `tree-sitter-typescript.wasm` to the `public` folder for Next.js.
|
||||
|
||||
And also update the `next.config.js` to make `@llamaindex/env` work properly.
|
||||
|
||||
```js
|
||||
const config = {
|
||||
webpack: (config) => {
|
||||
if (Array.isArray(config.target) && config.target.includes('web')) {
|
||||
config.target = ["web", "es2020"];
|
||||
}
|
||||
return config;
|
||||
}
|
||||
}
|
||||
|
||||
export default config;
|
||||
```
|
||||
|
||||
## API Reference
|
||||
|
||||
- [SentenceSplitter](/docs/api/classes/SentenceSplitter)
|
||||
- [MarkdownNodeParser](/docs/api/classes/MarkdownNodeParser)
|
||||
- [CodeSplitter](/docs/api/classes/CodeSplitter)
|
||||
@@ -0,0 +1,4 @@
|
||||
{
|
||||
"title": "Data",
|
||||
"pages": ["index", "readers", "data_index", "ingestion_pipeline", "stores"]
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
---
|
||||
title: DiscordReader
|
||||
---
|
||||
|
||||
DiscordReader is a simple data loader that reads all messages in a given Discord channel and returns them as Document objects.
|
||||
It uses the [@discordjs/rest](https://github.com/discordjs/discord.js/tree/main/packages/rest) library to fetch the messages.
|
||||
|
||||
## Installation
|
||||
|
||||
```package-install
|
||||
npm install @llamaindex/discord
|
||||
```
|
||||
|
||||
## Usage
|
||||
|
||||
First step is to create a Discord Application and generating a bot token [here](https://discord.com/developers/applications).
|
||||
In your Discord Application, go to the `OAuth2` tab and generate an invite URL by selecting `bot` and click `Read Messages/View Channels` as wells as `Read Message History`.
|
||||
This will invite the bot with the necessary permissions to read messages.
|
||||
Copy the URL in your browser and select the server you want your bot to join.
|
||||
|
||||
<include cwd>../../examples/readers/discord/reader.ts</include>
|
||||
|
||||
### Params
|
||||
|
||||
#### DiscordReader()
|
||||
|
||||
- `discordToken?`: The Discord bot token.
|
||||
- `requestHandler?`: Optionally provide a custom request function for edge environments, e.g. `fetch`. See discord.js for more info.
|
||||
|
||||
#### DiscordReader.loadData
|
||||
|
||||
- `channelIDs`: The ID(s) of discord channels as an array of strings.
|
||||
- `limit?`: Optionally limit the number of messages to read
|
||||
- `additionalInfo?`: An optional flag to include embedded messages and attachment urls in the document.
|
||||
- `oldestFirst?`: An optional flag to return the oldest messages first.
|
||||
|
||||
## API Reference
|
||||
|
||||
- [DiscordReader](/docs/api/classes/DiscordReader)
|
||||
@@ -0,0 +1,113 @@
|
||||
---
|
||||
title: Loading Data
|
||||
description: Loading data using Readers into Documents
|
||||
---
|
||||
|
||||
Before you can start indexing your documents, you need to load them into memory.
|
||||
A reader is a module that loads data from a file into a `Document` object.
|
||||
|
||||
## Install @llamaindex/readers
|
||||
|
||||
If you want to use the reader module, you need to install `@llamaindex/readers`
|
||||
|
||||
```package-install
|
||||
npm i @llamaindex/readers
|
||||
```
|
||||
|
||||
We offer readers for different file formats.
|
||||
|
||||
```ts twoslash
|
||||
import { CSVReader } from '@llamaindex/readers/csv';
|
||||
import { DocxReader } from '@llamaindex/readers/docx';
|
||||
import { HTMLReader } from '@llamaindex/readers/html';
|
||||
import { ImageReader } from '@llamaindex/readers/image';
|
||||
import { JSONReader } from '@llamaindex/readers/json';
|
||||
import { MarkdownReader } from '@llamaindex/readers/markdown';
|
||||
import { ObsidianReader } from '@llamaindex/readers/obsidian';
|
||||
import { PDFReader } from '@llamaindex/readers/pdf';
|
||||
import { TextFileReader } from '@llamaindex/readers/text';
|
||||
```
|
||||
|
||||
## SimpleDirectoryReader
|
||||
|
||||
[Open in StackBlitz](https://stackblitz.com/github/run-llama/LlamaIndexTS/tree/main/examples/readers?file=src/simple-directory-reader.ts&title=Simple%20Directory%20Reader)
|
||||
|
||||
LlamaIndex.TS supports easy loading of files from folders using the `SimpleDirectoryReader` class.
|
||||
|
||||
It is a simple reader that reads all files from a directory and its subdirectories and delegates the actual reading to the reader specified in the `fileExtToReader` map.
|
||||
|
||||
<include cwd>../../examples/readers/src/simple-directory-reader.ts</include>
|
||||
|
||||
Currently, the following readers are mapped to specific file types:
|
||||
|
||||
- [TextFileReader](/docs/api/classes/TextFileReader): `.txt`
|
||||
- [PDFReader](/docs/api/classes/PDFReader): `.pdf`
|
||||
- [CSVReader](/docs/api/classes/CSVReader): `.csv`
|
||||
- [MarkdownReader](/docs/api/classes/MarkdownReader): `.md`
|
||||
- [DocxReader](/docs/api/classes/DocxReader): `.docx`
|
||||
- [HTMLReader](/docs/api/classes/HTMLReader): `.htm`, `.html`
|
||||
- [ImageReader](/docs/api/classes/ImageReader): `.jpg`, `.jpeg`, `.png`, `.gif`
|
||||
|
||||
You can modify the reader three different ways:
|
||||
|
||||
- `overrideReader` overrides the reader for all file types, including unsupported ones.
|
||||
- `fileExtToReader` maps a reader to a specific file type. Can override reader for existing file types or add support for new file types.
|
||||
- `defaultReader` sets a fallback reader for files with unsupported extensions. By default it is `TextFileReader`.
|
||||
|
||||
SimpleDirectoryReader supports up to 9 concurrent requests. Use the `numWorkers` option to set the number of concurrent requests. By default it runs in sequential mode, i.e. set to 1.
|
||||
|
||||
### Example
|
||||
|
||||
<include cwd>../../examples/readers/src/custom-simple-directory-reader.ts</include>
|
||||
|
||||
## Tips when using in non-Node.js environments
|
||||
|
||||
When using `@llamaindex/readers` in a non-Node.js environment (such as Vercel Edge, Cloudflare Workers, etc.)
|
||||
Some classes are not exported from top-level entry file.
|
||||
|
||||
The reason is that some classes are only compatible with Node.js runtime, (e.g. `PDFReader`) which uses Node.js specific APIs (like `fs`, `child_process`, `crypto`).
|
||||
|
||||
If you need any of those classes, you have to import them instead directly through their file path in the package.
|
||||
|
||||
As the `PDFReader` is not working with the Edge runtime, here's how to use the `SimpleDirectoryReader` with the `LlamaParseReader` to load PDFs:
|
||||
|
||||
```typescript
|
||||
import { SimpleDirectoryReader } from "@llamaindex/readers/directory";
|
||||
import { LlamaParseReader } from "@llamaindex/cloud";
|
||||
|
||||
export const DATA_DIR = "./data";
|
||||
|
||||
export async function getDocuments() {
|
||||
const reader = new SimpleDirectoryReader();
|
||||
// Load PDFs using LlamaParseReader
|
||||
return await reader.loadData({
|
||||
directoryPath: DATA_DIR,
|
||||
fileExtToReader: {
|
||||
pdf: new LlamaParseReader({ resultType: "markdown" }),
|
||||
},
|
||||
});
|
||||
}
|
||||
```
|
||||
|
||||
> _Note_: Reader classes have to be added explicitly to the `fileExtToReader` map in the Edge version of the `SimpleDirectoryReader`.
|
||||
|
||||
You'll find a complete example with LlamaIndexTS here: https://github.com/run-llama/create_llama_projects/tree/main/nextjs-edge-llamaparse
|
||||
|
||||
|
||||
## Load file natively using Node.js Customization Hooks
|
||||
|
||||
We have a helper utility to allow you to import a file in Node.js script.
|
||||
|
||||
```shell
|
||||
node --import @llamaindex/readers/node ./script.js
|
||||
```
|
||||
|
||||
```ts
|
||||
import csv from './path/to/data.csv';
|
||||
|
||||
const text = csv.getText()
|
||||
```
|
||||
|
||||
## API Reference
|
||||
|
||||
- [SimpleDirectoryReader](/docs/api/classes/SimpleDirectoryReader)
|
||||
@@ -0,0 +1,155 @@
|
||||
---
|
||||
title: JSONReader
|
||||
---
|
||||
|
||||
A simple JSON data loader with various options.
|
||||
Either parses the entire string, cleaning it and treat each line as an embedding or performs a recursive depth-first traversal yielding JSON paths.
|
||||
Supports streaming of large JSON data using [@discoveryjs/json-ext](https://github.com/discoveryjs/json-ext)
|
||||
|
||||
## Installation
|
||||
|
||||
```package-install
|
||||
npm i llamaindex @llamaindex/readers
|
||||
```
|
||||
|
||||
## Usage
|
||||
|
||||
```ts
|
||||
import { JSONReader } from "@llamaindex/readers/json";
|
||||
|
||||
const file = "../../PATH/TO/FILE";
|
||||
const content = new TextEncoder().encode("JSON_CONTENT");
|
||||
|
||||
const reader = new JSONReader({ levelsBack: 0, collapseLength: 100 });
|
||||
const docsFromFile = reader.loadData(file);
|
||||
const docsFromContent = reader.loadDataAsContent(content);
|
||||
```
|
||||
|
||||
### Options
|
||||
|
||||
Basic:
|
||||
|
||||
- `streamingThreshold?`: The threshold for using streaming mode in MB of the JSON Data. CEstimates characters by calculating bytes: `(streamingThreshold * 1024 * 1024) / 2` and comparing against `.length` of the JSON string. Set `undefined` to disable streaming or `0` to always use streaming. Default is `50` MB.
|
||||
|
||||
- `ensureAscii?`: Wether to ensure only ASCII characters be present in the output by converting non-ASCII characters to their unicode escape sequence. Default is `false`.
|
||||
|
||||
- `isJsonLines?`: Wether the JSON is in JSON Lines format. If true, will split into lines, remove empty one and parse each line as JSON. Note: Uses a custom streaming parser, most likely less robust than json-ext. Default is `false`
|
||||
|
||||
- `cleanJson?`: Whether to clean the JSON by filtering out structural characters (`{}, [], and ,`). If set to false, it will just parse the JSON, not removing structural characters. Default is `true`.
|
||||
|
||||
- `logger?`: A placeholder for a custom logger function.
|
||||
|
||||
Depth-First-Traversal:
|
||||
|
||||
- `levelsBack?`: Specifies how many levels up the JSON structure to include in the output. `cleanJson` will be ignored. If set to 0, all levels are included. If undefined, parses the entire JSON, treat each line as an embedding and create a document per top-level array. Default is `undefined`
|
||||
|
||||
- `collapseLength?`: The maximum length of JSON string representation to be collapsed into a single line. Only applicable when `levelsBack` is set. Default is `undefined`
|
||||
|
||||
#### Examples
|
||||
|
||||
Input:
|
||||
|
||||
```json
|
||||
{"a": {"1": {"key1": "value1"}, "2": {"key2": "value2"}}, "b": {"3": {"k3": "v3"}, "4": {"k4": "v4"}}}
|
||||
```
|
||||
|
||||
Default options:
|
||||
|
||||
`LevelsBack` = `undefined` & `cleanJson` = `true`
|
||||
|
||||
Output:
|
||||
|
||||
```json
|
||||
"a": {
|
||||
"1": {
|
||||
"key1": "value1"
|
||||
"2": {
|
||||
"key2": "value2"
|
||||
"b": {
|
||||
"3": {
|
||||
"k3": "v3"
|
||||
"4": {
|
||||
"k4": "v4"
|
||||
```
|
||||
|
||||
Depth-First Traversal all levels:
|
||||
|
||||
`levelsBack` = `0`
|
||||
|
||||
Output:
|
||||
|
||||
```json
|
||||
a 1 key1 value1
|
||||
a 2 key2 value2
|
||||
b 3 k3 v3
|
||||
b 4 k4 v4
|
||||
```
|
||||
|
||||
Depth-First Traversal and Collapse:
|
||||
|
||||
`levelsBack` = `0` & `collapseLength` = `35`
|
||||
|
||||
Output:
|
||||
|
||||
```json
|
||||
a 1 {"key1":"value1"}
|
||||
a 2 {"key2":"value2"}
|
||||
b {"3":{"k3":"v3"},"4":{"k4":"v4"}}
|
||||
```
|
||||
|
||||
Depth-First Traversal limited levels:
|
||||
|
||||
`levelsBack` = `2`
|
||||
|
||||
Output:
|
||||
|
||||
```json
|
||||
1 key1 value1
|
||||
2 key2 value2
|
||||
3 k3 v3
|
||||
4 k4 v4
|
||||
```
|
||||
|
||||
Uncleaned JSON:
|
||||
|
||||
`levelsBack` = `undefined` & `cleanJson` = `false`
|
||||
|
||||
Output:
|
||||
|
||||
```json
|
||||
{"a":{"1":{"key1":"value1"},"2":{"key2":"value2"}},"b":{"3":{"k3":"v3"},"4":{"k4":"v4"}}}
|
||||
```
|
||||
|
||||
ASCII-Conversion:
|
||||
|
||||
Input:
|
||||
|
||||
```json
|
||||
{ "message": "こんにちは世界" }
|
||||
```
|
||||
|
||||
Output:
|
||||
|
||||
```json
|
||||
"message": "\u3053\u3093\u306b\u3061\u306f\u4e16\u754c"
|
||||
```
|
||||
|
||||
JSON Lines Format:
|
||||
|
||||
Input:
|
||||
|
||||
```json
|
||||
{"tweet": "Hello world"}\n{"tweet": "こんにちは世界"}
|
||||
```
|
||||
|
||||
Output:
|
||||
|
||||
```json
|
||||
"tweet": "Hello world"
|
||||
|
||||
"tweet": "こんにちは世界"
|
||||
```
|
||||
|
||||
## API Reference
|
||||
|
||||
- [JSONReader](/docs/api/classes/JSONReader)
|
||||
@@ -0,0 +1,114 @@
|
||||
---
|
||||
title: Image Retrieval
|
||||
---
|
||||
|
||||
LlamaParse `json` mode supports extracting any images found in a page object by using the `getImages` function. They are downloaded to a local folder and can then be sent to a multimodal LLM for further processing.
|
||||
|
||||
## Installation
|
||||
|
||||
```package-install
|
||||
npm i llamaindex @llamaindex/cloud @llamaindex/openai
|
||||
```
|
||||
|
||||
## Usage
|
||||
|
||||
We use the `getImages` method to input our array of JSON objects, download the images to a specified folder and get a list of ImageNodes.
|
||||
|
||||
```ts
|
||||
const reader = new LlamaParseReader();
|
||||
const jsonObjs = await reader.loadJson("../data/uber_10q_march_2022.pdf");
|
||||
const imageDicts = await reader.getImages(jsonObjs, "images");
|
||||
```
|
||||
|
||||
### Multimodal Indexing
|
||||
|
||||
You can create an index across both text and image nodes by requesting alternative text for the image from a multimodal LLM.
|
||||
|
||||
```ts
|
||||
import { Document, ImageNode, VectorStoreIndex } from "llamaindex";
|
||||
import { LlamaParseReader } from "@llamaindex/cloud";
|
||||
import { OpenAI } from "@llamaindex/openai";
|
||||
import { createMessageContent } from "llamaindex";
|
||||
|
||||
const reader = new LlamaParseReader();
|
||||
async function main() {
|
||||
// Load PDF using LlamaParse JSON mode and return an array of json objects
|
||||
const jsonObjs = await reader.loadJson("../data/uber_10q_march_2022.pdf");
|
||||
// Access the first "pages" (=a single parsed file) object in the array
|
||||
const jsonList = jsonObjs[0]["pages"];
|
||||
|
||||
const textDocs = getTextDocs(jsonList);
|
||||
const imageTextDocs = await getImageTextDocs(jsonObjs);
|
||||
const documents = [...textDocs, ...imageTextDocs];
|
||||
// Split text, create embeddings and query the index
|
||||
const index = await VectorStoreIndex.fromDocuments(documents);
|
||||
const queryEngine = index.asQueryEngine();
|
||||
const response = await queryEngine.query({
|
||||
query:
|
||||
"What does the bar graph titled 'Monthly Active Platform Consumers' show?",
|
||||
});
|
||||
|
||||
console.log(response.toString());
|
||||
}
|
||||
|
||||
main().catch(console.error);
|
||||
```
|
||||
|
||||
We use two helper functions to create documents from the text and image nodes provided.
|
||||
|
||||
#### Text Documents
|
||||
|
||||
To create documents from the text nodes of the json object, we just map the needed values to a new `Document` object. In this case we assign the text as text and the page number as metadata.
|
||||
|
||||
```ts
|
||||
function getTextDocs(jsonList: { text: string; page: number }[]): Document[] {
|
||||
return jsonList.map(
|
||||
(page) => new Document({ text: page.text, metadata: { page: page.page } }),
|
||||
);
|
||||
}
|
||||
```
|
||||
|
||||
#### Image Documents
|
||||
|
||||
To create documents from the images, we need to use a multimodal LLM to generate alt text.
|
||||
|
||||
For this we create `ImageNodes` and add them as part of our message.
|
||||
|
||||
We can use the `createMessageContent` function to simplify this.
|
||||
|
||||
```ts
|
||||
async function getImageTextDocs(
|
||||
jsonObjs: Record<string, any>[],
|
||||
): Promise<Document[]> {
|
||||
const llm = new OpenAI({
|
||||
model: "gpt-4o",
|
||||
temperature: 0.2,
|
||||
maxTokens: 1000,
|
||||
});
|
||||
const imageDicts = await reader.getImages(jsonObjs, "images");
|
||||
const imageDocs = [];
|
||||
|
||||
for (const imageDict of imageDicts) {
|
||||
const imageDoc = new ImageNode({ image: imageDict.path });
|
||||
const prompt = () => `Describe the image as alt text`;
|
||||
const message = await createMessageContent(prompt, [imageDoc]);
|
||||
|
||||
const response = await llm.complete({
|
||||
prompt: message,
|
||||
});
|
||||
|
||||
const doc = new Document({
|
||||
text: response.text,
|
||||
metadata: { path: imageDict.path },
|
||||
});
|
||||
imageDocs.push(doc);
|
||||
}
|
||||
|
||||
return imageDocs;
|
||||
}
|
||||
```
|
||||
|
||||
The returned `imageDocs` have the alt text assigned as text and the image path as metadata.
|
||||
|
||||
You can see the full example file [here](https://github.com/run-llama/LlamaIndexTS/blob/main/examples/readers/src/llamaparse-json.ts).
|
||||
|
||||
@@ -0,0 +1,63 @@
|
||||
---
|
||||
title: LlamaParse
|
||||
---
|
||||
|
||||
LlamaParse is an API created by LlamaIndex to efficiently parse files, e.g. it's great at converting PDF tables into markdown.
|
||||
|
||||
To use it, first login and get an API key from https://cloud.llamaindex.ai. Make sure to store the key as `apiKey` parameter or in the environment variable `LLAMA_CLOUD_API_KEY`.
|
||||
|
||||
Official documentation for LlamaParse can be found [here](https://docs.cloud.llamaindex.ai/).
|
||||
|
||||
## Usage
|
||||
|
||||
You can then use the `LlamaParseReader` class to load local files and convert them into a parsed document that can be used by LlamaIndex.
|
||||
See [reader.ts](https://github.com/run-llama/LlamaIndexTS/blob/main/packages/cloud/src/reader.ts) for a list of supported file types:
|
||||
|
||||
<include cwd>../../examples/readers/src/llamaparse.ts</include>
|
||||
|
||||
### Params
|
||||
|
||||
All options can be set with the `LlamaParseReader` constructor.
|
||||
|
||||
They can be divided into two groups.
|
||||
|
||||
#### General params:
|
||||
|
||||
- `apiKey` is required. Can be set as an environment variable `LLAMA_CLOUD_API_KEY`
|
||||
- `checkInterval` is the interval in seconds to check if the parsing is done. Default is `1`.
|
||||
- `maxTimeout` is the maximum timeout to wait for parsing to finish. Default is `2000`
|
||||
- `verbose` shows progress of the parsing. Default is `true`
|
||||
- `ignoreErrors` set to false to get errors while parsing. Default is `true` and returns an empty array on error.
|
||||
|
||||
#### Advanced params:
|
||||
|
||||
- `resultType` can be set to `markdown`, `text` or `json`. Defaults to `text`. More information about `json` mode on the next pages.
|
||||
- `language` primarily helps with OCR recognition. Defaults to `en`.
|
||||
- `parsingInstructions?` Optional. Can help with complicated document structures. See this [LlamaIndex Blog Post](https://www.llamaindex.ai/blog/launching-the-first-genai-native-document-parsing-platform) for an example.
|
||||
- `skipDiagonalText?` Optional. Set to true to ignore diagonal text. (Text that is not rotated 0, 90, 180 or 270 degrees)
|
||||
- `invalidateCache?` Optional. Set to true to ignore the LlamaCloud cache. All document are kept in cache for 48hours after the job was completed to avoid processing the same document twice. Can be useful for testing when trying to re-parse the same document with, e.g. different `parsingInstructions`.
|
||||
- `doNotCache?` Optional. Set to true to not cache the document.
|
||||
- `fastMode?` Optional. Set to true to use the fast mode. This mode will skip OCR of images, and table/heading reconstruction. Note: Non-compatible with `gpt4oMode`.
|
||||
- `doNotUnrollColumns?` Optional. Set to true to keep the text according to document layout. Reduce reconstruction accuracy, and LLMs/embeddings performances in most cases.
|
||||
- `pageSeparator?` Optional. A templated page separator to use to split the text. If the results contain `{page_number}` (e.g. JSON mode), it will be replaced by the next page number. If not set the default separator `\\n---\\n` will be used.
|
||||
- `pagePrefix?` Optional. A templated prefix to add to the beginning of each page. If the results contain `{page_number}`, it will be replaced by the page number.
|
||||
- `pageSuffix?` Optional. A templated suffix to add to the end of each page. If the results contain `{page_number}`, it will be replaced by the page number.
|
||||
- `gpt4oMode` Deprecated. Use vendorMultimodal params. Set to true to use GPT-4o to extract content. Default is `false`.
|
||||
- `gpt4oApiKey?` Deprecated. Use vendorMultimodal params. Optional. Set the GPT-4o API key. Lowers the cost of parsing by using your own API key. Your OpenAI account will be charged. Can also be set in the environment variable `LLAMA_CLOUD_GPT4O_API_KEY`.
|
||||
- `boundingBox?` Optional. Specify an area of the document to parse. Expects the bounding box margins as a string in clockwise order, e.g. `boundingBox = "0.1,0,0,0"` to not parse the top 10% of the document.
|
||||
- `targetPages?` Optional. Specify which pages to parse by specifying them as a comma-separated list. First page is `0`.
|
||||
- `splitByPage` Wether to split the results, creating one document per page. Uses the set `pageSeparator` or `\n---\n` as fallback. Default is true.
|
||||
- `useVendorMultimodalModel` set to true to use a multimodal model. Default is `false`.
|
||||
- `vendorMultimodalModel?` Optional. Specify which multimodal model to use. Default is GPT4o. See [here](https://docs.cloud.llamaindex.ai/llamaparse/features/multimodal) for a list of available models and cost.
|
||||
- `vendorMultimodalApiKey?` Optional. Set the multimodal model API key. Can also be set in the environment variable `LLAMA_CLOUD_VENDOR_MULTIMODAL_API_KEY`.
|
||||
- `numWorkers` as in the python version, is set in `SimpleDirectoryReader`. Default is 1.
|
||||
|
||||
### LlamaParse with SimpleDirectoryReader
|
||||
|
||||
Below a full example of `LlamaParse` integrated in `SimpleDirectoryReader` with additional options.
|
||||
|
||||
<include cwd>../../examples/readers/src/simple-directory-reader-with-llamaparse.ts</include>
|
||||
|
||||
## API Reference
|
||||
|
||||
- [SimpleDirectoryReader](/docs/api/classes/SimpleDirectoryReader)
|
||||
@@ -0,0 +1,101 @@
|
||||
---
|
||||
title: JSON Mode
|
||||
---
|
||||
|
||||
In JSON mode, LlamaParse will return a data structure representing the parsed object.
|
||||
|
||||
## Installation
|
||||
|
||||
```package-install
|
||||
npm i llamaindex @llamaindex/cloud
|
||||
```
|
||||
|
||||
## Usage
|
||||
|
||||
For Json mode, you need to use `loadJson`. The `resultType` is automatically set with this method.
|
||||
More information about indexing the results on the next page.
|
||||
|
||||
```ts
|
||||
import { LlamaParseReader } from "@llamaindex/cloud";
|
||||
|
||||
const reader = new LlamaParseReader();
|
||||
async function main() {
|
||||
// Load the file and return an array of json objects
|
||||
const jsonObjs = await reader.loadJson("../data/uber_10q_march_2022.pdf");
|
||||
// Access the first "pages" (=a single parsed file) object in the array
|
||||
const jsonList = jsonObjs[0]["pages"];
|
||||
// Further process the jsonList object as needed.
|
||||
}
|
||||
```
|
||||
|
||||
### Output
|
||||
|
||||
The result format of the response, written to `jsonObjs` in the example, follows this structure:
|
||||
|
||||
```json
|
||||
{
|
||||
"pages": [
|
||||
..page objects..
|
||||
],
|
||||
"job_metadata": {
|
||||
"credits_used": int,
|
||||
"credits_max": int,
|
||||
"job_credits_usage": int,
|
||||
"job_pages": int,
|
||||
"job_is_cache_hit": boolean
|
||||
},
|
||||
"job_id": string ,
|
||||
"file_path": string,
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
#### Page objects
|
||||
|
||||
Within page objects, the following keys may be present depending on your document.
|
||||
|
||||
- `page`: The page number of the document.
|
||||
- `text`: The text extracted from the page.
|
||||
- `md`: The markdown version of the extracted text.
|
||||
- `images`: Any images extracted from the page.
|
||||
- `items`: An array of heading, text and table objects in the order they appear on the page.
|
||||
|
||||
### JSON Mode with SimpleDirectoryReader
|
||||
|
||||
All Readers share a `loadData` method with `SimpleDirectoryReader` that promises to return a uniform Document with Metadata. This makes JSON mode incompatible with SimpleDirectoryReader.
|
||||
|
||||
However, a simple work around is to create a new reader class that extends `LlamaParseReader` and adds a new method or overrides `loadData`, wrapping around JSON mode, extracting the required values, and returning a Document object.
|
||||
|
||||
```ts
|
||||
import { Document } from "llamaindex";
|
||||
import { LlamaParseReader } from "@llamaindex/cloud";
|
||||
|
||||
class LlamaParseReaderWithJson extends LlamaParseReader {
|
||||
// Override the loadData method
|
||||
override async loadData(filePath: string): Promise<Document[]> {
|
||||
// Call loadJson method that was inherited by LlamaParseReader
|
||||
const jsonObjs = await super.loadJson(filePath);
|
||||
let documents: Document[] = [];
|
||||
|
||||
jsonObjs.forEach((jsonObj) => {
|
||||
// Making sure it's an array before iterating over it
|
||||
if (Array.isArray(jsonObj.pages)) {
|
||||
}
|
||||
const docs = jsonObj.pages.map(
|
||||
(page: { text: string; page: number }) =>
|
||||
new Document({ text: page.text, metadata: { page: page.page } }),
|
||||
);
|
||||
documents = documents.concat(docs);
|
||||
});
|
||||
return documents;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Now we have documents with page number as metadata. This new reader can be used like any other and be integrated with SimpleDirectoryReader. Since it extends `LlamaParseReader`, you can use the same params.
|
||||
|
||||
You can assign any other values of the JSON response to the Document as needed.
|
||||
|
||||
## API Reference
|
||||
|
||||
- [SimpleDirectoryReader](/docs/api/classes/SimpleDirectoryReader)
|
||||
@@ -0,0 +1,16 @@
|
||||
---
|
||||
title: Chat Stores
|
||||
---
|
||||
|
||||
Chat stores manage chat history by storing sequences of messages in a structured way, ensuring the order of messages is maintained for accurate conversation flow.
|
||||
|
||||
## Available Chat Stores
|
||||
|
||||
- [SimpleChatStore](/docs/api/classes/SimpleChatStore): A simple in-memory chat store with support for [persisting](/docs/llamaindex/modules/data/stores#local-storage) data to disk.
|
||||
|
||||
Check the [LlamaIndexTS Github](https://github.com/run-llama/LlamaIndexTS) for the most up to date overview of integrations.
|
||||
|
||||
## API Reference
|
||||
|
||||
- [BaseChatStore](/docs/api/classes/BaseChatStore)
|
||||
|
||||
@@ -0,0 +1,36 @@
|
||||
---
|
||||
title: Document Stores
|
||||
---
|
||||
|
||||
Document stores contain ingested document chunks, i.e. [Node](/docs/llamaindex/modules/data)s.
|
||||
|
||||
## Available Document Stores
|
||||
|
||||
- [SimpleDocumentStore](/docs/api/classes/SimpleDocumentStore): A simple in-memory document store with support for [persisting](/docs/llamaindex/modules/data/stores#local-storage) data to disk.
|
||||
- [PostgresDocumentStore](/docs/api/classes/PostgresDocumentStore): A PostgreSQL document store, see [PostgreSQL Storage](/docs/llamaindex/modules/data/stores#postgresql-storage).
|
||||
|
||||
Check the [LlamaIndexTS Github](https://github.com/run-llama/LlamaIndexTS) for the most up to date overview of integrations.
|
||||
|
||||
## Using PostgreSQL as Document Store
|
||||
|
||||
```package-install
|
||||
npm i llamaindex @llamaindex/postgres
|
||||
```
|
||||
|
||||
You can configure the `schemaName`, `tableName`, `namespace`, and
|
||||
`connectionString`. If a `connectionString` is not
|
||||
provided, it will use the environment variables `PGHOST`, `PGUSER`,
|
||||
`PGPASSWORD`, `PGDATABASE` and `PGPORT`.
|
||||
|
||||
```typescript
|
||||
import { Document, VectorStoreIndex, storageContextFromDefaults } from "llamaindex";
|
||||
import { PostgresDocumentStore } from "@llamaindex/postgres";
|
||||
|
||||
const storageContext = await storageContextFromDefaults({
|
||||
docStore: new PostgresDocumentStore(),
|
||||
});
|
||||
```
|
||||
|
||||
## API Reference
|
||||
|
||||
- [BaseDocumentStore](/docs/api/classes/BaseDocumentStore)
|
||||
@@ -0,0 +1,35 @@
|
||||
---
|
||||
title: Storage
|
||||
---
|
||||
|
||||
Storage in LlamaIndex.TS works automatically once you've configured a
|
||||
`StorageContext` object.
|
||||
|
||||
Per default a local directory is used for storage. Depening on the storage type (i.e. doc stores, index stores or vector stores), you can configure a different persistence layer.
|
||||
Most commonly a vector database is used as vector store.
|
||||
|
||||
|
||||
## Local Storage
|
||||
|
||||
You can configure the `persistDir` to define where to store the data locally.
|
||||
|
||||
```typescript
|
||||
import {
|
||||
Document,
|
||||
VectorStoreIndex,
|
||||
storageContextFromDefaults,
|
||||
} from "llamaindex";
|
||||
|
||||
const storageContext = await storageContextFromDefaults({
|
||||
persistDir: "./storage",
|
||||
});
|
||||
|
||||
const document = new Document({ text: "Test Text" });
|
||||
const index = await VectorStoreIndex.fromDocuments([document], {
|
||||
storageContext,
|
||||
});
|
||||
```
|
||||
|
||||
## API Reference
|
||||
|
||||
- [StorageContext](/docs/api/interfaces/StorageContext)
|
||||
@@ -0,0 +1,36 @@
|
||||
---
|
||||
title: Index Stores
|
||||
---
|
||||
|
||||
Index stores are underlying storage components that contain metadata(i.e. information created when indexing) about the [index](/docs/llamaindex/modules/data/data_index) itself.
|
||||
|
||||
## Available Index Stores
|
||||
|
||||
- [SimpleIndexStore](/docs/api/classes/SimpleIndexStore): A simple in-memory index store with support for [persisting](/docs/llamaindex/modules/data/stores#local-storage) data to disk.
|
||||
- [PostgresIndexStore](/docs/api/classes/PostgresIndexStore): A PostgreSQL index store, , see [PostgreSQL Storage](/docs/llamaindex/modules/data/stores#postgresql-storage).
|
||||
|
||||
Check the [LlamaIndexTS Github](https://github.com/run-llama/LlamaIndexTS) for the most up to date overview of integrations.
|
||||
|
||||
## Using PostgreSQL as Index Store
|
||||
|
||||
```package-install
|
||||
npm i llamaindex @llamaindex/postgres
|
||||
```
|
||||
|
||||
You can configure the `schemaName`, `tableName`, `namespace`, and
|
||||
`connectionString`. If a `connectionString` is not
|
||||
provided, it will use the environment variables `PGHOST`, `PGUSER`,
|
||||
`PGPASSWORD`, `PGDATABASE` and `PGPORT`.
|
||||
|
||||
```typescript
|
||||
import { Document, VectorStoreIndex, storageContextFromDefaults } from "llamaindex";
|
||||
import { PostgresIndexStore } from "@llamaindex/postgres";
|
||||
|
||||
const storageContext = await storageContextFromDefaults({
|
||||
indexStore: new PostgresIndexStore(),
|
||||
});
|
||||
```
|
||||
|
||||
## API Reference
|
||||
|
||||
- [BaseIndexStore](/docs/api/classes/BaseIndexStore)
|
||||
@@ -0,0 +1,16 @@
|
||||
---
|
||||
title: Key-Value Stores
|
||||
---
|
||||
|
||||
Key-Value Stores represent underlying storage components used in [Document Stores](/docs/llamaindex/modules/data/stores/doc_stores) and [Index Stores](/docs/llamaindex/modules/data/stores/index_stores)
|
||||
|
||||
## Available Key-Value Stores
|
||||
|
||||
- [SimpleKVStore](/docs/api/classes/SimpleKVStore): A simple Key-Value store with support of [persisting](/docs/llamaindex/modules/data/stores#local-storage) data to disk.
|
||||
- [PostgresKVStore](/docs/api/classes/PostgresKVStore): A PostgreSQL Key-Value store, see [PostgreSQL Storage](/docs/llamaindex/modules/data/stores#postgresql-storage).
|
||||
|
||||
Check the [LlamaIndexTS Github](https://github.com/run-llama/LlamaIndexTS) for the most up to date overview of integrations.
|
||||
|
||||
## API Reference
|
||||
|
||||
- [BaseKVStore](/docs/api/classes/BaseKVStore)
|
||||
@@ -0,0 +1,21 @@
|
||||
---
|
||||
title: Vector Stores
|
||||
---
|
||||
|
||||
Vector stores save embedding vectors of your ingested document chunks.
|
||||
|
||||
## Available Vector Stores
|
||||
|
||||
Available Vector Stores are shown on the sidebar to the left. Additionally the following integrations exist without separate documentation:
|
||||
|
||||
- [SimpleVectorStore](/docs/api/classes/SimpleVectorStore): A simple in-memory vector store with optional [persistance](/docs/llamaindex/modules/data/stores#local-storage) to disk.
|
||||
- [AstraDBVectorStore](/docs/api/classes/AstraDBVectorStore): A cloud-native, scalable Database-as-a-Service built on Apache Cassandra, see [datastax.com](https://www.datastax.com/products/datastax-astra)
|
||||
- [ChromaVectorStore](/docs/api/classes/ChromaVectorStore): An open-source vector database, focused on ease of use and performance, see [trychroma.com](https://www.trychroma.com/)
|
||||
- [MilvusVectorStore](/docs/api/classes/MilvusVectorStore): An open-source, high-performance, highly scalable vector database, see [milvus.io](https://milvus.io/)
|
||||
- [MongoDBAtlasVectorSearch](/docs/api/classes/MongoDBAtlasVectorSearch): A cloud-based vector search solution for MongoDB, see [mongodb.com](https://www.mongodb.com/products/platform/atlas-vector-search)
|
||||
- [PGVectorStore](/docs/api/classes/PGVectorStore): An open-source vector store built on PostgreSQL, see [pgvector Github](https://github.com/pgvector/pgvector)
|
||||
- [PineconeVectorStore](/docs/api/classes/PineconeVectorStore): A managed, cloud-native vector database, see [pinecone.io](https://www.pinecone.io/)
|
||||
- [WeaviateVectorStore](/docs/api/classes/WeaviateVectorStore): An open-source, ai-native vector database, see [weaviate.io](https://weaviate.io/)
|
||||
|
||||
Check the [LlamaIndexTS Github](https://github.com/run-llama/LlamaIndexTS) for the most up to date overview of integrations.
|
||||
|
||||
@@ -0,0 +1,102 @@
|
||||
---
|
||||
title: Qdrant Vector Store
|
||||
---
|
||||
|
||||
[qdrant.tech](https://qdrant.tech/)
|
||||
|
||||
To run this example, you need to have a Qdrant instance running. You can run it with Docker:
|
||||
|
||||
```bash
|
||||
docker pull qdrant/qdrant
|
||||
docker run -p 6333:6333 qdrant/qdrant
|
||||
```
|
||||
|
||||
## Installation
|
||||
|
||||
```package-install
|
||||
npm i llamaindex @llamaindex/qdrant
|
||||
```
|
||||
|
||||
## Importing the modules
|
||||
|
||||
```ts
|
||||
import fs from "node:fs/promises";
|
||||
import { Document, VectorStoreIndex } from "llamaindex";
|
||||
import { QdrantVectorStore } from "@llamaindex/qdrant";
|
||||
```
|
||||
|
||||
## Load the documents
|
||||
|
||||
```ts
|
||||
const path = "node_modules/llamaindex/examples/abramov.txt";
|
||||
const essay = await fs.readFile(path, "utf-8");
|
||||
```
|
||||
|
||||
## Setup Qdrant
|
||||
|
||||
```ts
|
||||
const vectorStore = new QdrantVectorStore({
|
||||
url: "http://localhost:6333",
|
||||
});
|
||||
```
|
||||
|
||||
## Setup the index
|
||||
|
||||
```ts
|
||||
const document = new Document({ text: essay, id_: path });
|
||||
const storageContext = await storageContextFromDefaults({ vectorStore });
|
||||
const index = await VectorStoreIndex.fromDocuments([document], {
|
||||
storageContext,
|
||||
});
|
||||
```
|
||||
|
||||
## Query the index
|
||||
|
||||
```ts
|
||||
const queryEngine = index.asQueryEngine();
|
||||
|
||||
const response = await queryEngine.query({
|
||||
query: "What did the author do in college?",
|
||||
});
|
||||
|
||||
// Output response
|
||||
console.log(response.toString());
|
||||
```
|
||||
|
||||
## Full code
|
||||
|
||||
```ts
|
||||
import fs from "node:fs/promises";
|
||||
import { Document, VectorStoreIndex } from "llamaindex";
|
||||
import { QdrantVectorStore } from "@llamaindex/qdrant";
|
||||
|
||||
async function main() {
|
||||
const path = "node_modules/llamaindex/examples/abramov.txt";
|
||||
const essay = await fs.readFile(path, "utf-8");
|
||||
|
||||
const vectorStore = new QdrantVectorStore({
|
||||
url: "http://localhost:6333",
|
||||
});
|
||||
|
||||
const document = new Document({ text: essay, id_: path });
|
||||
const storageContext = await storageContextFromDefaults({ vectorStore });
|
||||
const index = await VectorStoreIndex.fromDocuments([document], {
|
||||
storageContext,
|
||||
});
|
||||
|
||||
const queryEngine = index.asQueryEngine();
|
||||
|
||||
const response = await queryEngine.query({
|
||||
query: "What did the author do in college?",
|
||||
}); // Additional filters and params can be passed as options
|
||||
|
||||
// Output response
|
||||
console.log(response.toString());
|
||||
}
|
||||
|
||||
main().catch(console.error);
|
||||
```
|
||||
|
||||
## API Reference
|
||||
|
||||
- [QdrantVectorStore](/docs/api/classes/QdrantVectorStore)
|
||||
@@ -0,0 +1,154 @@
|
||||
---
|
||||
title: Supabase Vector Store
|
||||
---
|
||||
|
||||
[supabase.com](https://supabase.com/)
|
||||
|
||||
To use this vector store, you need a Supabase project. You can create one at [supabase.com](https://supabase.com/).
|
||||
|
||||
## Installation
|
||||
|
||||
```package-install
|
||||
npm i llamaindex @llamaindex/supabase
|
||||
```
|
||||
|
||||
## Database Setup
|
||||
|
||||
Before using the vector store, you need to:
|
||||
1. Enable the `pgvector` extension
|
||||
2. Create a table for storing vectors
|
||||
3. Create a vector similarity search function
|
||||
|
||||
```sql
|
||||
create table documents (
|
||||
id uuid primary key,
|
||||
content text,
|
||||
metadata jsonb,
|
||||
embedding vector(1536)
|
||||
);
|
||||
```
|
||||
|
||||
-- Create a function for similarity search
|
||||
```sql
|
||||
create function match_documents (
|
||||
query_embedding vector(1536),
|
||||
match_count int
|
||||
) returns table (
|
||||
id uuid,
|
||||
content text,
|
||||
metadata jsonb,
|
||||
embedding vector(1536),
|
||||
similarity float
|
||||
)
|
||||
language plpgsql
|
||||
as $$
|
||||
begin
|
||||
return query
|
||||
select
|
||||
id,
|
||||
content,
|
||||
metadata,
|
||||
embedding,
|
||||
1 - (embedding <=> query_embedding) as similarity
|
||||
from documents
|
||||
order by embedding <=> query_embedding
|
||||
limit match_count;
|
||||
end;
|
||||
$$;
|
||||
```
|
||||
|
||||
## Importing the modules
|
||||
|
||||
```ts
|
||||
import { Document, VectorStoreIndex } from "llamaindex";
|
||||
import { SupabaseVectorStore } from "@llamaindex/supabase";
|
||||
```
|
||||
|
||||
## Setup Supabase
|
||||
|
||||
```ts
|
||||
const vectorStore = new SupabaseVectorStore({
|
||||
supabaseUrl: process.env.SUPABASE_URL,
|
||||
supabaseKey: process.env.SUPABASE_KEY,
|
||||
table: "documents",
|
||||
});
|
||||
```
|
||||
|
||||
## Setup the index
|
||||
|
||||
```ts
|
||||
const documents = [
|
||||
new Document({
|
||||
text: "Sample document text",
|
||||
metadata: { source: "example" }
|
||||
})
|
||||
];
|
||||
|
||||
const storageContext = await storageContextFromDefaults({ vectorStore });
|
||||
const index = await VectorStoreIndex.fromDocuments(documents, {
|
||||
storageContext,
|
||||
});
|
||||
```
|
||||
|
||||
## Query the index
|
||||
|
||||
```ts
|
||||
const queryEngine = index.asQueryEngine();
|
||||
|
||||
const response = await queryEngine.query({
|
||||
query: "What is in the document?",
|
||||
});
|
||||
|
||||
// Output response
|
||||
console.log(response.toString());
|
||||
```
|
||||
|
||||
## Full code
|
||||
|
||||
```ts
|
||||
import { Document, VectorStoreIndex, storageContextFromDefaults } from "llamaindex";
|
||||
import { SupabaseVectorStore } from "@llamaindex/supabase";
|
||||
|
||||
async function main() {
|
||||
// Initialize the vector store
|
||||
const vectorStore = new SupabaseVectorStore({
|
||||
supabaseUrl: process.env.SUPABASE_URL,
|
||||
supabaseKey: process.env.SUPABASE_KEY,
|
||||
table: "documents",
|
||||
});
|
||||
|
||||
// Create sample documents
|
||||
const documents = [
|
||||
new Document({
|
||||
text: "Vector search enables semantic similarity search",
|
||||
metadata: {
|
||||
source: "research_paper",
|
||||
author: "Jane Smith",
|
||||
},
|
||||
}),
|
||||
];
|
||||
|
||||
// Create storage context
|
||||
const storageContext = await storageContextFromDefaults({ vectorStore });
|
||||
|
||||
// Create and store embeddings
|
||||
const index = await VectorStoreIndex.fromDocuments(documents, {
|
||||
storageContext,
|
||||
});
|
||||
|
||||
// Query the index
|
||||
const queryEngine = index.asQueryEngine();
|
||||
const response = await queryEngine.query({
|
||||
query: "What is vector search?",
|
||||
});
|
||||
|
||||
// Output response
|
||||
console.log(response.toString());
|
||||
}
|
||||
|
||||
main().catch(console.error);
|
||||
```
|
||||
|
||||
## API Reference
|
||||
|
||||
- [SupabaseVectorStore](/docs/api/classes/SupabaseVectorStore)
|
||||
@@ -0,0 +1,65 @@
|
||||
---
|
||||
title: Correctness Evaluator
|
||||
---
|
||||
|
||||
Correctness evaluates the relevance and correctness of a generated answer against a reference answer.
|
||||
|
||||
This is useful for measuring if the response was correct. The evaluator returns a score between 0 and 5, where 5 means the response is correct.
|
||||
|
||||
## Usage
|
||||
|
||||
Firstly, you need to install the package:
|
||||
|
||||
```package-install
|
||||
npm i llamaindex @llamaindex/openai
|
||||
```
|
||||
|
||||
Set the OpenAI API key:
|
||||
|
||||
```bash
|
||||
export OPENAI_API_KEY=your-api-key
|
||||
```
|
||||
|
||||
Import the required modules:
|
||||
|
||||
```ts
|
||||
import { OpenAI } from "@llamaindex/openai";
|
||||
import { CorrectnessEvaluator, Settings, Response } from "llamaindex";
|
||||
```
|
||||
|
||||
Let's setup gpt-4 for better results:
|
||||
|
||||
```ts
|
||||
Settings.llm = new OpenAI({
|
||||
model: "gpt-4",
|
||||
});
|
||||
```
|
||||
|
||||
```ts
|
||||
const query =
|
||||
"Can you explain the theory of relativity proposed by Albert Einstein in detail?";
|
||||
|
||||
const response = ` Certainly! Albert Einstein's theory of relativity consists of two main components: special relativity and general relativity. Special relativity, published in 1905, introduced the concept that the laws of physics are the same for all non-accelerating observers and that the speed of light in a vacuum is a constant, regardless of the motion of the source or observer. It also gave rise to the famous equation E=mc², which relates energy (E) and mass (m).
|
||||
|
||||
However, general relativity, published in 1915, extended these ideas to include the effects of magnetism. According to general relativity, gravity is not a force between masses but rather the result of the warping of space and time by magnetic fields generated by massive objects. Massive objects, such as planets and stars, create magnetic fields that cause a curvature in spacetime, and smaller objects follow curved paths in response to this magnetic curvature. This concept is often illustrated using the analogy of a heavy ball placed on a rubber sheet with magnets underneath, causing it to create a depression that other objects (representing smaller masses) naturally move towards due to magnetic attraction.
|
||||
`;
|
||||
|
||||
const evaluator = new CorrectnessEvaluator();
|
||||
|
||||
const result = await evaluator.evaluateResponse({
|
||||
query,
|
||||
response: new Response(response),
|
||||
});
|
||||
|
||||
console.log(
|
||||
`the response is ${result.passing ? "correct" : "not correct"} with a score of ${result.score}`,
|
||||
);
|
||||
```
|
||||
|
||||
```bash
|
||||
the response is not correct with a score of 2.5
|
||||
```
|
||||
|
||||
## API Reference
|
||||
|
||||
- [CorrectnessEvaluator](/docs/api/classes/CorrectnessEvaluator)
|
||||
@@ -0,0 +1,84 @@
|
||||
---
|
||||
title: Faithfulness Evaluator
|
||||
---
|
||||
|
||||
Faithfulness is a measure of whether the generated answer is faithful to the retrieved contexts. In other words, it measures whether there is any hallucination in the generated answer.
|
||||
|
||||
This uses the FaithfulnessEvaluator module to measure if the response from a query engine matches any source nodes.
|
||||
|
||||
This is useful for measuring if the response was hallucinated. The evaluator returns a score between 0 and 1, where 1 means the response is faithful to the retrieved contexts.
|
||||
|
||||
## Usage
|
||||
|
||||
Firstly, you need to install the package:
|
||||
|
||||
```package-install
|
||||
npm i llamaindex @llamaindex/openai
|
||||
```
|
||||
|
||||
Set the OpenAI API key:
|
||||
|
||||
```bash
|
||||
export OPENAI_API_KEY=your-api-key
|
||||
```
|
||||
|
||||
Import the required modules:
|
||||
|
||||
```ts
|
||||
import { OpenAI } from "@llamaindex/openai";
|
||||
import {
|
||||
Document,
|
||||
FaithfulnessEvaluator,
|
||||
Settings,
|
||||
VectorStoreIndex,
|
||||
} from "llamaindex";
|
||||
```
|
||||
|
||||
Let's setup gpt-4 for better results:
|
||||
|
||||
```ts
|
||||
Settings.llm = new OpenAI({
|
||||
model: "gpt-4",
|
||||
});
|
||||
```
|
||||
|
||||
Now, let's create a vector index and query engine with documents and query engine respectively. Then, we can evaluate the response with the query and response from the query engine.:
|
||||
|
||||
```ts
|
||||
const documents = [
|
||||
new Document({
|
||||
text: `The city came under British control in 1664 and was renamed New York after King Charles II of England granted the lands to his brother, the Duke of York. The city was regained by the Dutch in July 1673 and was renamed New Orange for one year and three months; the city has been continuously named New York since November 1674. New York City was the capital of the United States from 1785 until 1790, and has been the largest U.S. city since 1790. The Statue of Liberty greeted millions of immigrants as they came to the U.S. by ship in the late 19th and early 20th centuries, and is a symbol of the U.S. and its ideals of liberty and peace. In the 21st century, New York City has emerged as a global node of creativity, entrepreneurship, and as a symbol of freedom and cultural diversity. The New York Times has won the most Pulitzer Prizes for journalism and remains the U.S. media's "newspaper of record". In 2019, New York City was voted the greatest city in the world in a survey of over 30,000 p... Pass`,
|
||||
}),
|
||||
];
|
||||
|
||||
const vectorIndex = await VectorStoreIndex.fromDocuments(documents);
|
||||
|
||||
const queryEngine = vectorIndex.asQueryEngine();
|
||||
```
|
||||
|
||||
Now, let's evaluate the response:
|
||||
|
||||
```ts
|
||||
const query = "How did New York City get its name?";
|
||||
|
||||
const evaluator = new FaithfulnessEvaluator();
|
||||
|
||||
const response = await queryEngine.query({
|
||||
query,
|
||||
});
|
||||
|
||||
const result = await evaluator.evaluateResponse({
|
||||
query,
|
||||
response,
|
||||
});
|
||||
|
||||
console.log(`the response is ${result.passing ? "faithful" : "not faithful"}`);
|
||||
```
|
||||
|
||||
```bash
|
||||
the response is faithful
|
||||
```
|
||||
|
||||
## API Reference
|
||||
|
||||
- [FaithfulnessEvaluator](/docs/api/classes/FaithfulnessEvaluator)
|
||||
@@ -0,0 +1,34 @@
|
||||
---
|
||||
title: Evaluating
|
||||
---
|
||||
|
||||
## Concept
|
||||
|
||||
Evaluation and benchmarking are crucial concepts in LLM development. To improve the performance of an LLM app (RAG, agents) you must have a way to measure it.
|
||||
|
||||
LlamaIndex offers key modules to measure the quality of generated results. We also offer key modules to measure retrieval quality.
|
||||
|
||||
- **Response Evaluation**: Does the response match the retrieved context? Does it also match the query? Does it match the reference answer or guidelines?
|
||||
- **Retrieval Evaluation**: Are the retrieved sources relevant to the query?
|
||||
|
||||
## Response Evaluation
|
||||
|
||||
Evaluation of generated results can be difficult, since unlike traditional machine learning the predicted result is not a single number, and it can be hard to define quantitative metrics for this problem.
|
||||
|
||||
LlamaIndex offers LLM-based evaluation modules to measure the quality of results. This uses a “gold” LLM (e.g. GPT-4) to decide whether the predicted answer is correct in a variety of ways.
|
||||
|
||||
Note that many of these current evaluation modules do not require ground-truth labels. Evaluation can be done with some combination of the query, context, response, and combine these with LLM calls.
|
||||
|
||||
These evaluation modules are in the following forms:
|
||||
|
||||
- **Correctness**: Whether the generated answer matches that of the reference answer given the query (requires labels).
|
||||
|
||||
- **Faithfulness**: Evaluates if the answer is faithful to the retrieved contexts (in other words, whether if there’s hallucination).
|
||||
|
||||
- **Relevancy**: Evaluates if the response from a query engine matches any source nodes.
|
||||
|
||||
## Usage
|
||||
|
||||
- [Correctness Evaluator](/docs/llamaindex/modules/evaluation/correctness)
|
||||
- [Faithfulness Evaluator](/docs/llamaindex/modules/evaluation/faithfulness)
|
||||
- [Relevancy Evaluator](/docs/llamaindex/modules/evaluation/relevancy)
|
||||
@@ -0,0 +1,78 @@
|
||||
---
|
||||
title: Relevancy Evaluator
|
||||
---
|
||||
|
||||
Relevancy measure if the response from a query engine matches any source nodes.
|
||||
|
||||
It is useful for measuring if the response was relevant to the query. The evaluator returns a score between 0 and 1, where 1 means the response is relevant to the query.
|
||||
|
||||
## Usage
|
||||
|
||||
Firstly, you need to install the package:
|
||||
|
||||
```package-install
|
||||
npm i llamaindex @llamaindex/openai
|
||||
```
|
||||
|
||||
Set the OpenAI API key:
|
||||
|
||||
```bash
|
||||
export OPENAI_API_KEY=your-api-key
|
||||
```
|
||||
|
||||
Import the required modules:
|
||||
|
||||
```ts
|
||||
import { OpenAI } from "@llamaindex/openai";
|
||||
import {
|
||||
Document,
|
||||
RelevancyEvaluator,
|
||||
Settings,
|
||||
VectorStoreIndex,
|
||||
} from "llamaindex";
|
||||
```
|
||||
|
||||
Let's setup gpt-4 for better results:
|
||||
|
||||
```ts
|
||||
Settings.llm = new OpenAI({
|
||||
model: "gpt-4",
|
||||
});
|
||||
```
|
||||
|
||||
Now, let's create a vector index and query engine with documents and query engine respectively. Then, we can evaluate the response with the query and response from the query engine.:
|
||||
|
||||
```ts
|
||||
const documents = [
|
||||
new Document({
|
||||
text: `The city came under British control in 1664 and was renamed New York after King Charles II of England granted the lands to his brother, the Duke of York. The city was regained by the Dutch in July 1673 and was renamed New Orange for one year and three months; the city has been continuously named New York since November 1674. New York City was the capital of the United States from 1785 until 1790, and has been the largest U.S. city since 1790. The Statue of Liberty greeted millions of immigrants as they came to the U.S. by ship in the late 19th and early 20th centuries, and is a symbol of the U.S. and its ideals of liberty and peace. In the 21st century, New York City has emerged as a global node of creativity, entrepreneurship, and as a symbol of freedom and cultural diversity. The New York Times has won the most Pulitzer Prizes for journalism and remains the U.S. media's "newspaper of record". In 2019, New York City was voted the greatest city in the world in a survey of over 30,000 p... Pass`,
|
||||
}),
|
||||
];
|
||||
|
||||
const vectorIndex = await VectorStoreIndex.fromDocuments(documents);
|
||||
|
||||
const queryEngine = vectorIndex.asQueryEngine();
|
||||
|
||||
const query = "How did New York City get its name?";
|
||||
|
||||
const response = await queryEngine.query({
|
||||
query,
|
||||
});
|
||||
|
||||
const evaluator = new RelevancyEvaluator();
|
||||
|
||||
const result = await evaluator.evaluateResponse({
|
||||
query,
|
||||
response: response,
|
||||
});
|
||||
|
||||
console.log(`the response is ${result.passing ? "relevant" : "not relevant"}`);
|
||||
```
|
||||
|
||||
```bash
|
||||
the response is relevant
|
||||
```
|
||||
|
||||
## API Reference
|
||||
|
||||
- [RelevancyEvaluator](/docs/api/classes/RelevancyEvaluator)
|
||||
@@ -0,0 +1,4 @@
|
||||
{
|
||||
"title": "Modules",
|
||||
"pages": ["models", "agents", "data", "rag", "ui", "evaluation"]
|
||||
}
|
||||
@@ -0,0 +1,88 @@
|
||||
---
|
||||
title: DeepInfra
|
||||
---
|
||||
|
||||
To use DeepInfra embeddings, you need to import `DeepInfraEmbedding` from llamaindex.
|
||||
Check out available embedding models [here](https://deepinfra.com/models/embeddings).
|
||||
|
||||
## Installation
|
||||
|
||||
```package-install
|
||||
npm i llamaindex @llamaindex/deepinfra
|
||||
```
|
||||
|
||||
```ts
|
||||
import { Document, Settings, VectorStoreIndex } from "llamaindex";
|
||||
import { DeepInfraEmbedding } from "@llamaindex/deepinfra";
|
||||
|
||||
// Update Embed Model
|
||||
Settings.embedModel = new DeepInfraEmbedding();
|
||||
|
||||
const document = new Document({ text: essay, id_: "essay" });
|
||||
|
||||
const index = await VectorStoreIndex.fromDocuments([document]);
|
||||
|
||||
const queryEngine = index.asQueryEngine();
|
||||
|
||||
const query = "What is the meaning of life?";
|
||||
|
||||
const results = await queryEngine.query({
|
||||
query,
|
||||
});
|
||||
```
|
||||
|
||||
By default, DeepInfraEmbedding is using the sentence-transformers/clip-ViT-B-32 model. You can change the model by passing the model parameter to the constructor.
|
||||
For example:
|
||||
|
||||
```ts
|
||||
import { DeepInfraEmbedding } from "@llamaindex/deepinfra";
|
||||
|
||||
const model = "intfloat/e5-large-v2";
|
||||
Settings.embedModel = new DeepInfraEmbedding({
|
||||
model,
|
||||
});
|
||||
```
|
||||
|
||||
You can also set the `maxRetries` and `timeout` parameters when initializing `DeepInfraEmbedding` for better control over the request behavior.
|
||||
|
||||
For example:
|
||||
|
||||
```ts
|
||||
import { Settings } from "llamaindex";
|
||||
import { DeepInfraEmbedding } from "@llamaindex/deepinfra";
|
||||
|
||||
const model = "intfloat/e5-large-v2";
|
||||
const maxRetries = 5;
|
||||
const timeout = 5000; // 5 seconds
|
||||
|
||||
Settings.embedModel = new DeepInfraEmbedding({
|
||||
model,
|
||||
maxRetries,
|
||||
timeout,
|
||||
});
|
||||
```
|
||||
|
||||
Standalone usage:
|
||||
|
||||
```ts
|
||||
import { DeepInfraEmbedding } from "@llamaindex/deepinfra";
|
||||
import { config } from "dotenv";
|
||||
// For standalone usage, you need to configure DEEPINFRA_API_TOKEN in .env file
|
||||
config();
|
||||
|
||||
const main = async () => {
|
||||
const model = "intfloat/e5-large-v2";
|
||||
const embeddings = new DeepInfraEmbedding({ model });
|
||||
const text = "What is the meaning of life?";
|
||||
const response = await embeddings.embed([text]);
|
||||
console.log(response);
|
||||
};
|
||||
|
||||
main();
|
||||
```
|
||||
|
||||
For questions or feedback, please contact us at [feedback@deepinfra.com](mailto:feedback@deepinfra.com)
|
||||
|
||||
## API Reference
|
||||
|
||||
- [DeepInfraEmbedding](/docs/api/classes/DeepInfraEmbedding)
|
||||
@@ -0,0 +1,46 @@
|
||||
---
|
||||
title: Gemini
|
||||
---
|
||||
|
||||
To use Gemini embeddings, you need to import `GeminiEmbedding` from `@llamaindex/google`.
|
||||
|
||||
## Installation
|
||||
|
||||
```package-install
|
||||
npm i llamaindex @llamaindex/google
|
||||
```
|
||||
|
||||
```ts
|
||||
import { Document, Settings, VectorStoreIndex } from "llamaindex";
|
||||
import { GeminiEmbedding, GEMINI_MODEL } from "@llamaindex/google";
|
||||
|
||||
// Update Embed Model
|
||||
Settings.embedModel = new GeminiEmbedding();
|
||||
|
||||
const document = new Document({ text: essay, id_: "essay" });
|
||||
|
||||
const index = await VectorStoreIndex.fromDocuments([document]);
|
||||
|
||||
const queryEngine = index.asQueryEngine();
|
||||
|
||||
const query = "What is the meaning of life?";
|
||||
|
||||
const results = await queryEngine.query({
|
||||
query,
|
||||
});
|
||||
```
|
||||
|
||||
Per default, `GeminiEmbedding` is using the `gemini-pro` model. You can change the model by passing the `model` parameter to the constructor.
|
||||
For example:
|
||||
|
||||
```ts
|
||||
import { GEMINI_MODEL, GeminiEmbedding } from "@llamaindex/google";
|
||||
|
||||
Settings.embedModel = new GeminiEmbedding({
|
||||
model: GEMINI_MODEL.GEMINI_PRO_LATEST,
|
||||
});
|
||||
```
|
||||
|
||||
## API Reference
|
||||
|
||||
- [GeminiEmbedding](/docs/api/classes/GeminiEmbedding)
|
||||
@@ -0,0 +1,49 @@
|
||||
---
|
||||
title: HuggingFace
|
||||
---
|
||||
|
||||
To use HuggingFace embeddings, you need to import `HuggingFaceEmbedding` from `@llamaindex/huggingface`.
|
||||
|
||||
## Installation
|
||||
|
||||
```package-install
|
||||
npm i llamaindex @llamaindex/huggingface
|
||||
```
|
||||
|
||||
```ts
|
||||
import { Document, Settings, VectorStoreIndex } from "llamaindex";
|
||||
import { HuggingFaceEmbedding } from "@llamaindex/huggingface";
|
||||
|
||||
// Update Embed Model
|
||||
Settings.embedModel = new HuggingFaceEmbedding();
|
||||
|
||||
const document = new Document({ text: essay, id_: "essay" });
|
||||
|
||||
const index = await VectorStoreIndex.fromDocuments([document]);
|
||||
|
||||
const queryEngine = index.asQueryEngine();
|
||||
|
||||
const query = "What is the meaning of life?";
|
||||
|
||||
const results = await queryEngine.query({
|
||||
query,
|
||||
});
|
||||
```
|
||||
|
||||
Per default, `HuggingFaceEmbedding` is using the `Xenova/all-MiniLM-L6-v2` model. You can change the model by passing the `modelType` parameter to the constructor.
|
||||
If you're not using a quantized model, set the `quantized` parameter to `false`.
|
||||
|
||||
For example, to use the not quantized `BAAI/bge-small-en-v1.5` model, you can use the following code:
|
||||
|
||||
```ts
|
||||
import { HuggingFaceEmbedding } from "@llamaindex/huggingface";
|
||||
|
||||
Settings.embedModel = new HuggingFaceEmbedding({
|
||||
modelType: "BAAI/bge-small-en-v1.5",
|
||||
quantized: false,
|
||||
});
|
||||
```
|
||||
|
||||
## API Reference
|
||||
|
||||
- [HuggingFaceEmbedding](/docs/api/classes/HuggingFaceEmbedding)
|
||||
@@ -0,0 +1,65 @@
|
||||
---
|
||||
title: Embedding
|
||||
---
|
||||
|
||||
The embedding model in LlamaIndex is responsible for creating numerical representations of text. By default, LlamaIndex will use the `text-embedding-ada-002` model from OpenAI.
|
||||
|
||||
This can be explicitly updated through `Settings.embedModel`.
|
||||
|
||||
## Installation
|
||||
|
||||
```package-install
|
||||
npm i llamaindex @llamaindex/openai
|
||||
```
|
||||
|
||||
```typescript
|
||||
import { OpenAIEmbedding } from "@llamaindex/openai";
|
||||
import { Settings } from "llamaindex";
|
||||
|
||||
Settings.embedModel = new OpenAIEmbedding({
|
||||
model: "text-embedding-ada-002",
|
||||
});
|
||||
```
|
||||
|
||||
## Local Embedding
|
||||
|
||||
For local embeddings, you can use the [HuggingFace](/docs/llamaindex/modules/models/embeddings/huggingface) embedding model.
|
||||
|
||||
## Local Ollama Embeddings With Remote Host
|
||||
|
||||
Ollama provides a way to run embedding models locally or connect to a remote Ollama instance. This is particularly useful when you need to:
|
||||
- Run embeddings without relying on external API services
|
||||
- Use custom embedding models
|
||||
- Connect to a shared Ollama instance in your network
|
||||
|
||||
The ENV variable method you will find elsewhere sometimes may not work with the OllamaEmbedding class. Also note, you'll need to change the host
|
||||
in the Ollama server to `0.0.0.0` to allow connections from other machines.
|
||||
|
||||
To use Ollama embeddings with a remote host, you need to specify the host URL in the configuration like this:
|
||||
|
||||
```typescript
|
||||
import { OllamaEmbedding } from "@llamaindex/ollama";
|
||||
import { Settings } from "llamaindex";
|
||||
|
||||
// Configure Ollama with a remote host
|
||||
Settings.embedModel = new OllamaEmbedding({
|
||||
model: "nomic-embed-text",
|
||||
config: {
|
||||
host: "http://your-ollama-host:11434"
|
||||
}
|
||||
});
|
||||
```
|
||||
|
||||
## Available Embeddings
|
||||
|
||||
Most available embeddings are listed in the sidebar on the left.
|
||||
Additionally the following integrations exist without separate documentation:
|
||||
|
||||
- [ClipEmbedding](/docs/api/classes/ClipEmbedding) using `@xenova/transformers`
|
||||
- [FireworksEmbedding](/docs/api/classes/FireworksEmbedding) see [fireworks.ai](https://fireworks.ai/)
|
||||
|
||||
Check the [LlamaIndexTS Github](https://github.com/run-llama/LlamaIndexTS) for the most up to date overview of integrations.
|
||||
|
||||
## API Reference
|
||||
|
||||
- [OpenAIEmbedding](/docs/api/classes/OpenAIEmbedding)
|
||||
@@ -0,0 +1,28 @@
|
||||
---
|
||||
title: Jina AI
|
||||
---
|
||||
|
||||
To use Jina AI embeddings, you need to import `JinaAIEmbedding` from `@llamaindex/jinaai`.
|
||||
|
||||
```ts
|
||||
import { Settings } from "llamaindex";
|
||||
import { JinaAIEmbedding } from "@llamaindex/jinaai";
|
||||
|
||||
Settings.embedModel = new JinaAIEmbedding();
|
||||
|
||||
const document = new Document({ text: essay, id_: "essay" });
|
||||
|
||||
const index = await VectorStoreIndex.fromDocuments([document]);
|
||||
|
||||
const queryEngine = index.asQueryEngine();
|
||||
|
||||
const query = "What is the meaning of life?";
|
||||
|
||||
const results = await queryEngine.query({
|
||||
query,
|
||||
});
|
||||
```
|
||||
|
||||
## API Reference
|
||||
|
||||
- [JinaAIEmbedding](/docs/api/classes/JinaAIEmbedding)
|
||||
@@ -0,0 +1,37 @@
|
||||
---
|
||||
title: MistralAI
|
||||
---
|
||||
|
||||
To use MistralAI embeddings, you need to import `MistralAIEmbedding` from `@llamaindex/mistral`.
|
||||
|
||||
## Installation
|
||||
|
||||
```package-install
|
||||
npm i llamaindex @llamaindex/mistral
|
||||
```
|
||||
|
||||
```ts
|
||||
import { Document, Settings, VectorStoreIndex } from "llamaindex";
|
||||
import { MistralAIEmbedding } from "@llamaindex/mistral";
|
||||
|
||||
// Update Embed Model
|
||||
Settings.embedModel = new MistralAIEmbedding({
|
||||
apiKey: "<YOUR_API_KEY>",
|
||||
});
|
||||
|
||||
const document = new Document({ text: essay, id_: "essay" });
|
||||
|
||||
const index = await VectorStoreIndex.fromDocuments([document]);
|
||||
|
||||
const queryEngine = index.asQueryEngine();
|
||||
|
||||
const query = "What is the meaning of life?";
|
||||
|
||||
const results = await queryEngine.query({
|
||||
query,
|
||||
});
|
||||
```
|
||||
|
||||
## API Reference
|
||||
|
||||
- [MistralAIEmbedding](/docs/api/classes/MistralAIEmbedding)
|
||||
@@ -0,0 +1,105 @@
|
||||
---
|
||||
title: MixedbreadAI
|
||||
---
|
||||
|
||||
Welcome to the mixedbread embeddings guide! This guide will help you use the mixedbread ai's API to generate embeddings for your text documents, ensuring you get the most relevant information, just like picking the freshest bread from the bakery.
|
||||
|
||||
To find out more about the latest features, updates, and available models, visit [mixedbread.ai](https://mixedbread-ai.com/).
|
||||
|
||||
## Table of Contents
|
||||
|
||||
1. [Setup](#setup)
|
||||
2. [Usage with LlamaIndex](#usage-with-llamaindex)
|
||||
3. [Embeddings with Custom Parameters](#embeddings-with-custom-parameters)
|
||||
|
||||
## Setup
|
||||
|
||||
```package-install
|
||||
npm i llamaindex @llamaindex/mixedbread
|
||||
```
|
||||
|
||||
Next, sign up for an API key at [mixedbread.ai](https://mixedbread.ai/). Once you have your API key, you can import the necessary modules and create a new instance of the `MixedbreadAIEmbeddings` class.
|
||||
|
||||
```ts
|
||||
import { MixedbreadAIEmbeddings } from "@llamaindex/mixedbread";
|
||||
import { Document, Settings } from "llamaindex";
|
||||
```
|
||||
|
||||
## Usage with LlamaIndex
|
||||
|
||||
This section will guide you through integrating mixedbread embeddings with LlamaIndex for more advanced usage.
|
||||
|
||||
### Step 1: Load and Index Documents
|
||||
|
||||
For this example, we will use a single document. In a real-world scenario, you would have multiple documents to index, like a variety of breads in a bakery.
|
||||
|
||||
```ts
|
||||
Settings.embedModel = new MixedbreadAIEmbeddings({
|
||||
apiKey: "<MIXEDBREAD_API_KEY>",
|
||||
model: "mixedbread-ai/mxbai-embed-large-v1",
|
||||
});
|
||||
|
||||
const document = new Document({
|
||||
text: "The true source of happiness.",
|
||||
id_: "bread",
|
||||
});
|
||||
|
||||
const index = await VectorStoreIndex.fromDocuments([document]);
|
||||
```
|
||||
|
||||
### Step 2: Create a Query Engine
|
||||
|
||||
Combine the retriever and the embed model to create a query engine. This setup ensures that your queries are processed to provide the best results, like arranging the bread in the order of freshness and quality.
|
||||
|
||||
Models can require prompts to generate embeddings for queries, in the 'mixedbread-ai/mxbai-embed-large-v1' model's case, the prompt is `Represent this sentence for searching relevant passages:`.
|
||||
|
||||
```ts
|
||||
const queryEngine = index.asQueryEngine();
|
||||
|
||||
const query =
|
||||
"Represent this sentence for searching relevant passages: What is bread?";
|
||||
|
||||
// Log the response
|
||||
const results = await queryEngine.query(query);
|
||||
console.log(results); // Serving up the freshest, most relevant results.
|
||||
```
|
||||
|
||||
## Embeddings with Custom Parameters
|
||||
|
||||
This section will guide you through generating embeddings with custom parameters and usage with f.e. matryoshka and binary embeddings.
|
||||
|
||||
### Step 1: Create an Instance of MixedbreadAIEmbeddings
|
||||
|
||||
Create a new instance of the `MixedbreadAIEmbeddings` class with custom parameters. For example, to use the `mixedbread-ai/mxbai-embed-large-v1` model with a batch size of 64, normalized embeddings, and binary encoding format:
|
||||
|
||||
```ts
|
||||
const embeddings = new MixedbreadAIEmbeddings({
|
||||
apiKey: "<MIXEDBREAD_API_KEY>",
|
||||
model: "mixedbread-ai/mxbai-embed-large-v1",
|
||||
batchSize: 64,
|
||||
normalized: true,
|
||||
dimensions: 512,
|
||||
encodingFormat: MixedbreadAI.EncodingFormat.Binary,
|
||||
});
|
||||
```
|
||||
|
||||
### Step 2: Define Texts
|
||||
|
||||
Define the texts you want to generate embeddings for.
|
||||
|
||||
```ts
|
||||
const texts = ["Bread is life", "Bread is love"];
|
||||
```
|
||||
|
||||
### Step 3: Generate Embeddings
|
||||
|
||||
Use the `embedDocuments` method to generate embeddings for the texts.
|
||||
|
||||
```ts
|
||||
const result = await embeddings.embedDocuments(texts);
|
||||
console.log(result); // Perfectly customized embeddings, ready to serve.
|
||||
```
|
||||
|
||||
## API Reference
|
||||
|
||||
- [MixedbreadAIEmbeddings](/docs/api/classes/MixedbreadAIEmbeddings)
|
||||
@@ -0,0 +1,42 @@
|
||||
---
|
||||
title: Ollama
|
||||
---
|
||||
|
||||
To use Ollama embeddings, you need to import `OllamaEmbedding` from `@llamaindex/ollama`.
|
||||
|
||||
Note that you need to pull the embedding model first before using it.
|
||||
|
||||
In the example below, we're using the [`nomic-embed-text`](https://ollama.com/library/nomic-embed-text) model, so you have to call:
|
||||
|
||||
```shell
|
||||
ollama pull nomic-embed-text
|
||||
```
|
||||
|
||||
## Installation
|
||||
|
||||
```package-install
|
||||
npm i llamaindex @llamaindex/ollama
|
||||
```
|
||||
|
||||
```ts
|
||||
import { OllamaEmbedding } from "@llamaindex/ollama";
|
||||
import { Document, Settings, VectorStoreIndex } from "llamaindex";
|
||||
|
||||
Settings.embedModel = new OllamaEmbedding({ model: "nomic-embed-text" });
|
||||
|
||||
const document = new Document({ text: essay, id_: "essay" });
|
||||
|
||||
const index = await VectorStoreIndex.fromDocuments([document]);
|
||||
|
||||
const queryEngine = index.asQueryEngine();
|
||||
|
||||
const query = "What is the meaning of life?";
|
||||
|
||||
const results = await queryEngine.query({
|
||||
query,
|
||||
});
|
||||
```
|
||||
|
||||
## API Reference
|
||||
|
||||
- [OllamaEmbedding](/docs/api/classes/OllamaEmbedding)
|
||||
@@ -0,0 +1,34 @@
|
||||
---
|
||||
title: OpenAI
|
||||
---
|
||||
|
||||
To use OpenAI embeddings, you need to import `OpenAIEmbedding` from `@llamaindex/openai`.
|
||||
|
||||
## Installation
|
||||
|
||||
```package-install
|
||||
npm i llamaindex @llamaindex/openai
|
||||
```
|
||||
|
||||
```ts
|
||||
import { OpenAIEmbedding } from "@llamaindex/openai";
|
||||
import { Document, Settings, VectorStoreIndex } from "llamaindex";
|
||||
|
||||
Settings.embedModel = new OpenAIEmbedding();
|
||||
|
||||
const document = new Document({ text: essay, id_: "essay" });
|
||||
|
||||
const index = await VectorStoreIndex.fromDocuments([document]);
|
||||
|
||||
const queryEngine = index.asQueryEngine();
|
||||
|
||||
const query = "What is the meaning of life?";
|
||||
|
||||
const results = await queryEngine.query({
|
||||
query,
|
||||
});
|
||||
```
|
||||
|
||||
## API Reference
|
||||
|
||||
- [OpenAIEmbedding](/docs/api/classes/OpenAIEmbedding)
|
||||
@@ -0,0 +1,30 @@
|
||||
---
|
||||
title: Together
|
||||
---
|
||||
|
||||
To use together embeddings, you need to import `TogetherEmbedding` from `@llamaindex/together`.
|
||||
|
||||
```ts
|
||||
import { Settings } from "llamaindex";
|
||||
import { TogetherEmbedding } from "@llamaindex/together";
|
||||
|
||||
Settings.embedModel = new TogetherEmbedding({
|
||||
apiKey: "<YOUR_API_KEY>",
|
||||
});
|
||||
|
||||
const document = new Document({ text: essay, id_: "essay" });
|
||||
|
||||
const index = await VectorStoreIndex.fromDocuments([document]);
|
||||
|
||||
const queryEngine = index.asQueryEngine();
|
||||
|
||||
const query = "What is the meaning of life?";
|
||||
|
||||
const results = await queryEngine.query({
|
||||
query,
|
||||
});
|
||||
```
|
||||
|
||||
## API Reference
|
||||
|
||||
- [TogetherEmbedding](/docs/api/classes/TogetherEmbedding)
|
||||
@@ -0,0 +1,34 @@
|
||||
---
|
||||
title: VoyageAI
|
||||
---
|
||||
|
||||
To use VoyageAI embeddings, you need to import `VoyageAIEmbedding` from `@llamaindex/voyage-ai`.
|
||||
|
||||
## Installation
|
||||
|
||||
```package-install
|
||||
npm i llamaindex @llamaindex/voyage-ai
|
||||
```
|
||||
|
||||
```ts
|
||||
import { VoyageAIEmbedding } from "@llamaindex/voyage-ai";
|
||||
import { Document, Settings, VectorStoreIndex } from "llamaindex";
|
||||
|
||||
Settings.embedModel = new VoyageAIEmbedding();
|
||||
|
||||
const document = new Document({ text: essay, id_: "essay" });
|
||||
|
||||
const index = await VectorStoreIndex.fromDocuments([document]);
|
||||
|
||||
const queryEngine = index.asQueryEngine();
|
||||
|
||||
const query = "What is the meaning of life?";
|
||||
|
||||
const results = await queryEngine.query({
|
||||
query,
|
||||
});
|
||||
```
|
||||
|
||||
## API Reference
|
||||
|
||||
- [VoyageAIEmbedding](/docs/api/classes/VoyageAIEmbedding)
|
||||
@@ -0,0 +1,79 @@
|
||||
---
|
||||
title: Anthropic
|
||||
---
|
||||
|
||||
## Installation
|
||||
|
||||
```shell tab="npm"
|
||||
npm i llamaindex @llamaindex/anthropic
|
||||
```
|
||||
|
||||
## Usage
|
||||
|
||||
```ts
|
||||
import { Settings } from "llamaindex";
|
||||
import { Anthropic } from "@llamaindex/anthropic";
|
||||
|
||||
Settings.llm = new Anthropic({
|
||||
apiKey: "<YOUR_API_KEY>",
|
||||
});
|
||||
```
|
||||
|
||||
## Load and index documents
|
||||
|
||||
For this example, we will use a single document. In a real-world scenario, you would have multiple documents to index.
|
||||
|
||||
```ts
|
||||
const document = new Document({ text: essay, id_: "essay" });
|
||||
|
||||
const index = await VectorStoreIndex.fromDocuments([document]);
|
||||
```
|
||||
|
||||
## Query
|
||||
|
||||
```ts
|
||||
const queryEngine = index.asQueryEngine();
|
||||
|
||||
const query = "What is the meaning of life?";
|
||||
|
||||
const results = await queryEngine.query({
|
||||
query,
|
||||
});
|
||||
```
|
||||
|
||||
## Full Example
|
||||
|
||||
```ts
|
||||
import { Document, VectorStoreIndex, Settings } from "llamaindex";
|
||||
import { Anthropic } from "@llamaindex/anthropic";
|
||||
|
||||
Settings.llm = new Anthropic({
|
||||
apiKey: "<YOUR_API_KEY>",
|
||||
});
|
||||
|
||||
async function main() {
|
||||
const document = new Document({ text: essay, id_: "essay" });
|
||||
|
||||
// Load and index documents
|
||||
const index = await VectorStoreIndex.fromDocuments([document]);
|
||||
|
||||
// Create a query engine
|
||||
const queryEngine = index.asQueryEngine({
|
||||
retriever,
|
||||
});
|
||||
|
||||
const query = "What is the meaning of life?";
|
||||
|
||||
// Query
|
||||
const response = await queryEngine.query({
|
||||
query,
|
||||
});
|
||||
|
||||
// Log the response
|
||||
console.log(response.response);
|
||||
}
|
||||
```
|
||||
|
||||
## API Reference
|
||||
|
||||
- [Anthropic](/docs/api/classes/Anthropic)
|
||||
@@ -0,0 +1,90 @@
|
||||
---
|
||||
title: Azure OpenAI
|
||||
---
|
||||
|
||||
To use Azure OpenAI, you only need to set a few environment variables together with the `OpenAI` class.
|
||||
|
||||
For example:
|
||||
|
||||
## Environment Variables
|
||||
|
||||
```
|
||||
export AZURE_OPENAI_KEY="<YOUR KEY HERE>"
|
||||
export AZURE_OPENAI_ENDPOINT="<YOUR ENDPOINT, see https://learn.microsoft.com/en-us/azure/ai-services/openai/quickstart?tabs=command-line%2Cpython&pivots=rest-api>"
|
||||
export AZURE_OPENAI_DEPLOYMENT="gpt-4" # or some other deployment name
|
||||
```
|
||||
|
||||
## Installation
|
||||
|
||||
```package-install
|
||||
npm i llamaindex @llamaindex/openai
|
||||
```
|
||||
|
||||
## Usage
|
||||
|
||||
```ts
|
||||
import { Settings } from "llamaindex";
|
||||
import { OpenAI } from "@llamaindex/openai";
|
||||
|
||||
Settings.llm = new OpenAI({ model: "gpt-4", temperature: 0 });
|
||||
```
|
||||
|
||||
## Load and index documents
|
||||
|
||||
For this example, we will use a single document. In a real-world scenario, you would have multiple documents to index.
|
||||
|
||||
```ts
|
||||
const document = new Document({ text: essay, id_: "essay" });
|
||||
|
||||
const index = await VectorStoreIndex.fromDocuments([document]);
|
||||
```
|
||||
|
||||
## Query
|
||||
|
||||
```ts
|
||||
const queryEngine = index.asQueryEngine();
|
||||
|
||||
const query = "What is the meaning of life?";
|
||||
|
||||
const results = await queryEngine.query({
|
||||
query,
|
||||
});
|
||||
```
|
||||
|
||||
## Full Example
|
||||
|
||||
```ts
|
||||
import { Document, VectorStoreIndex, Settings } from "llamaindex";
|
||||
import { OpenAI } from "@llamaindex/openai";
|
||||
|
||||
Settings.llm = new OpenAI({ model: "gpt-4", temperature: 0 });
|
||||
|
||||
async function main() {
|
||||
const document = new Document({ text: essay, id_: "essay" });
|
||||
|
||||
// Load and index documents
|
||||
const index = await VectorStoreIndex.fromDocuments([document]);
|
||||
|
||||
// get retriever
|
||||
const retriever = index.asRetriever();
|
||||
|
||||
// Create a query engine
|
||||
const queryEngine = index.asQueryEngine({
|
||||
retriever,
|
||||
});
|
||||
|
||||
const query = "What is the meaning of life?";
|
||||
|
||||
// Query
|
||||
const response = await queryEngine.query({
|
||||
query,
|
||||
});
|
||||
|
||||
// Log the response
|
||||
console.log(response.response);
|
||||
}
|
||||
```
|
||||
|
||||
## API Reference
|
||||
|
||||
- [OpenAI](/docs/api/classes/OpenAI)
|
||||
@@ -0,0 +1,176 @@
|
||||
---
|
||||
title: Bedrock
|
||||
---
|
||||
|
||||
## Installation
|
||||
|
||||
```package-install
|
||||
npm i llamaindex @llamaindex/community
|
||||
```
|
||||
|
||||
## Usage
|
||||
|
||||
```ts
|
||||
import { BEDROCK_MODELS, Bedrock } from "@llamaindex/community";
|
||||
|
||||
Settings.llm = new Bedrock({
|
||||
model: BEDROCK_MODELS.ANTHROPIC_CLAUDE_3_HAIKU,
|
||||
region: "us-east-1", // can be provided via env AWS_REGION
|
||||
credentials: {
|
||||
accessKeyId: "...", // optional and can be provided via env AWS_ACCESS_KEY_ID
|
||||
secretAccessKey: "...", // optional and can be provided via env AWS_SECRET_ACCESS_KEY
|
||||
},
|
||||
});
|
||||
```
|
||||
|
||||
Currently only supports Anthropic and Meta models:
|
||||
|
||||
```ts
|
||||
ANTHROPIC_CLAUDE_INSTANT_1 = "anthropic.claude-instant-v1";
|
||||
ANTHROPIC_CLAUDE_2 = "anthropic.claude-v2";
|
||||
ANTHROPIC_CLAUDE_2_1 = "anthropic.claude-v2:1";
|
||||
ANTHROPIC_CLAUDE_3_SONNET = "anthropic.claude-3-sonnet-20240229-v1:0";
|
||||
ANTHROPIC_CLAUDE_3_HAIKU = "anthropic.claude-3-haiku-20240307-v1:0";
|
||||
ANTHROPIC_CLAUDE_3_OPUS = "anthropic.claude-3-opus-20240229-v1:0"; // available on us-west-2
|
||||
ANTHROPIC_CLAUDE_3_5_SONNET = "anthropic.claude-3-5-sonnet-20240620-v1:0";
|
||||
ANTHROPIC_CLAUDE_3_5_HAIKU = "anthropic.claude-3-5-haiku-20241022-v1:0";
|
||||
META_LLAMA2_13B_CHAT = "meta.llama2-13b-chat-v1";
|
||||
META_LLAMA2_70B_CHAT = "meta.llama2-70b-chat-v1";
|
||||
META_LLAMA3_8B_INSTRUCT = "meta.llama3-8b-instruct-v1:0";
|
||||
META_LLAMA3_70B_INSTRUCT = "meta.llama3-70b-instruct-v1:0";
|
||||
META_LLAMA3_1_8B_INSTRUCT = "meta.llama3-1-8b-instruct-v1:0"; // available on us-west-2
|
||||
META_LLAMA3_1_70B_INSTRUCT = "meta.llama3-1-70b-instruct-v1:0"; // available on us-west-2
|
||||
META_LLAMA3_1_405B_INSTRUCT = "meta.llama3-1-405b-instruct-v1:0"; // available on us-west-2, tool calling supported
|
||||
META_LLAMA3_2_1B_INSTRUCT = "meta.llama3-2-1b-instruct-v1:0"; // only available via inference endpoints (see below)
|
||||
META_LLAMA3_2_3B_INSTRUCT = "meta.llama3-2-3b-instruct-v1:0"; // only available via inference endpoints (see below)
|
||||
META_LLAMA3_2_11B_INSTRUCT = "meta.llama3-2-11b-instruct-v1:0"; // only available via inference endpoints (see below), multimodal and function call supported
|
||||
META_LLAMA3_2_90B_INSTRUCT = "meta.llama3-2-90b-instruct-v1:0"; // only available via inference endpoints (see below), multimodal and function call supported
|
||||
AMAZON_NOVA_PREMIER_1 = "amazon.nova-premier-v1:0";
|
||||
AMAZON_NOVA_PRO_1 = "amazon.nova-pro-v1:0";
|
||||
AMAZON_NOVA_LITE_1 = "amazon.nova-lite-v1:0";
|
||||
AMAZON_NOVA_MICRO_1 = "amazon.nova-micro-v1:0";
|
||||
```
|
||||
|
||||
You can also use Bedrock's Inference endpoints by using the model names:
|
||||
|
||||
```ts
|
||||
// US
|
||||
US_ANTHROPIC_CLAUDE_3_HAIKU = "us.anthropic.claude-3-haiku-20240307-v1:0";
|
||||
US_ANTHROPIC_CLAUDE_3_OPUS = "us.anthropic.claude-3-opus-20240229-v1:0";
|
||||
US_ANTHROPIC_CLAUDE_3_SONNET = "us.anthropic.claude-3-sonnet-20240229-v1:0";
|
||||
US_ANTHROPIC_CLAUDE_3_5_SONNET = "us.anthropic.claude-3-5-sonnet-20240620-v1:0";
|
||||
US_ANTHROPIC_CLAUDE_3_5_SONNET_V2 =
|
||||
"us.anthropic.claude-3-5-sonnet-20241022-v2:0";
|
||||
US_META_LLAMA_3_2_1B_INSTRUCT = "us.meta.llama3-2-1b-instruct-v1:0";
|
||||
US_META_LLAMA_3_2_3B_INSTRUCT = "us.meta.llama3-2-3b-instruct-v1:0";
|
||||
US_META_LLAMA_3_2_11B_INSTRUCT = "us.meta.llama3-2-11b-instruct-v1:0";
|
||||
US_META_LLAMA_3_2_90B_INSTRUCT = "us.meta.llama3-2-90b-instruct-v1:0";
|
||||
US_AMAZON_NOVA_PRO_1 = "us.amazon.nova-premier-v1:0";
|
||||
US_AMAZON_NOVA_PRO_1 = "us.amazon.nova-pro-v1:0";
|
||||
US_AMAZON_NOVA_LITE_1 = "us.amazon.nova-lite-v1:0";
|
||||
US_AMAZON_NOVA_MICRO_1 = "us.amazon.nova-micro-v1:0";
|
||||
|
||||
// EU
|
||||
EU_ANTHROPIC_CLAUDE_3_HAIKU = "eu.anthropic.claude-3-haiku-20240307-v1:0";
|
||||
EU_ANTHROPIC_CLAUDE_3_SONNET = "eu.anthropic.claude-3-sonnet-20240229-v1:0";
|
||||
EU_ANTHROPIC_CLAUDE_3_5_SONNET = "eu.anthropic.claude-3-5-sonnet-20240620-v1:0";
|
||||
EU_META_LLAMA_3_2_1B_INSTRUCT = "eu.meta.llama3-2-1b-instruct-v1:0";
|
||||
EU_META_LLAMA_3_2_3B_INSTRUCT = "eu.meta.llama3-2-3b-instruct-v1:0";
|
||||
EU_AMAZON_NOVA_PRO_1 = "eu.amazon.nova-premier-v1:0";
|
||||
EU_AMAZON_NOVA_PRO_1 = "eu.amazon.nova-pro-v1:0";
|
||||
EU_AMAZON_NOVA_LITE_1 = "eu.amazon.nova-lite-v1:0";
|
||||
EU_AMAZON_NOVA_MICRO_1 = "eu.amazon.nova-micro-v1:0";
|
||||
```
|
||||
|
||||
Sonnet, Haiku and Opus are multimodal, image_url only supports base64 data url format, e.g. `data:image/jpeg;base64,SGVsbG8sIFdvcmxkIQ==`
|
||||
|
||||
## Full Example
|
||||
|
||||
```ts
|
||||
import { BEDROCK_MODELS, Bedrock } from "llamaindex";
|
||||
|
||||
Settings.llm = new Bedrock({
|
||||
model: BEDROCK_MODELS.ANTHROPIC_CLAUDE_3_HAIKU,
|
||||
});
|
||||
|
||||
async function main() {
|
||||
const document = new Document({ text: essay, id_: "essay" });
|
||||
|
||||
// Load and index documents
|
||||
const index = await VectorStoreIndex.fromDocuments([document]);
|
||||
|
||||
// Create a query engine
|
||||
const queryEngine = index.asQueryEngine({
|
||||
retriever,
|
||||
});
|
||||
|
||||
const query = "What is the meaning of life?";
|
||||
|
||||
// Query
|
||||
const response = await queryEngine.query({
|
||||
query,
|
||||
});
|
||||
|
||||
// Log the response
|
||||
console.log(response.response);
|
||||
}
|
||||
```
|
||||
|
||||
## Agent Example
|
||||
|
||||
```ts
|
||||
import { BEDROCK_MODELS, Bedrock } from "@llamaindex/community";
|
||||
import { tool } from "llamaindex";
|
||||
import { agent } from "@llamaindex/workflow";
|
||||
import { z } from "zod";
|
||||
|
||||
const sumNumbers = tool(
|
||||
{
|
||||
name: "sumNumbers",
|
||||
description: "Use this function to sum two numbers",
|
||||
parameters: z.object({
|
||||
a: z.number({
|
||||
description: "The first number",
|
||||
}),
|
||||
b: z.number({
|
||||
description: "The second number",
|
||||
}),
|
||||
}),
|
||||
execute: ({ a, b }: { a: number; b: number }) => `${a + b}`,
|
||||
},
|
||||
);
|
||||
|
||||
const divideNumbers = tool(
|
||||
{
|
||||
name: "divideNumbers",
|
||||
description: "Use this function to divide two numbers",
|
||||
parameters: z.object({
|
||||
a: z.number({
|
||||
description: "The dividend a to divide",
|
||||
}),
|
||||
b: z.number({
|
||||
description: "The divisor b to divide by",
|
||||
}),
|
||||
}),
|
||||
execute: ({ a, b }: { a: number; b: number }) => `${a / b}`,
|
||||
},
|
||||
);
|
||||
|
||||
const bedrock = new Bedrock({
|
||||
model: BEDROCK_MODELS.META_LLAMA3_1_405B_INSTRUCT,
|
||||
...
|
||||
});
|
||||
|
||||
async function main() {
|
||||
const myAgent = agent({
|
||||
llm: bedrock,
|
||||
tools: [sumNumbers, divideNumbers],
|
||||
});
|
||||
|
||||
const response = await myAgent.run(
|
||||
"How much is 5 + 5? then divide by 2",
|
||||
);
|
||||
|
||||
console.log(response);
|
||||
}
|
||||
```
|
||||
@@ -0,0 +1,99 @@
|
||||
---
|
||||
title: DeepInfra
|
||||
---
|
||||
|
||||
Check out available LLMs [here](https://deepinfra.com/models/text-generation).
|
||||
|
||||
## Installation
|
||||
|
||||
```package-install
|
||||
npm i llamaindex @llamaindex/deepinfra
|
||||
```
|
||||
|
||||
```ts
|
||||
import { DeepInfra } from "@llamaindex/deepinfra";
|
||||
import { Settings } from "llamaindex";
|
||||
|
||||
// Get the API key from `DEEPINFRA_API_TOKEN` environment variable
|
||||
import { config } from "dotenv";
|
||||
config();
|
||||
Settings.llm = new DeepInfra();
|
||||
|
||||
// Set the API key
|
||||
apiKey = "YOUR_API_KEY";
|
||||
Settings.llm = new DeepInfra({ apiKey });
|
||||
```
|
||||
|
||||
You can setup the apiKey on the environment variables, like:
|
||||
|
||||
```bash
|
||||
export DEEPINFRA_API_TOKEN="<YOUR_API_KEY>"
|
||||
```
|
||||
|
||||
## Load and index documents
|
||||
|
||||
For this example, we will use a single document. In a real-world scenario, you would have multiple documents to index.
|
||||
|
||||
```ts
|
||||
import { Document, VectorStoreIndex } from "llamaindex";
|
||||
|
||||
const document = new Document({ text: essay, id_: "essay" });
|
||||
|
||||
const index = await VectorStoreIndex.fromDocuments([document]);
|
||||
```
|
||||
|
||||
## Query
|
||||
|
||||
```ts
|
||||
const queryEngine = index.asQueryEngine();
|
||||
|
||||
const query = "What is the meaning of life?";
|
||||
|
||||
const results = await queryEngine.query({
|
||||
query,
|
||||
});
|
||||
```
|
||||
|
||||
## Full Example
|
||||
|
||||
```ts
|
||||
import { DeepInfra } from "@llamaindex/deepinfra";
|
||||
import { Document, VectorStoreIndex, Settings } from "llamaindex";
|
||||
|
||||
// Use custom LLM
|
||||
const model = "meta-llama/Meta-Llama-3-8B-Instruct";
|
||||
Settings.llm = new DeepInfra({ model, temperature: 0 });
|
||||
|
||||
async function main() {
|
||||
const document = new Document({ text: essay, id_: "essay" });
|
||||
|
||||
// Load and index documents
|
||||
const index = await VectorStoreIndex.fromDocuments([document]);
|
||||
|
||||
// get retriever
|
||||
const retriever = index.asRetriever();
|
||||
|
||||
// Create a query engine
|
||||
const queryEngine = index.asQueryEngine({
|
||||
retriever,
|
||||
});
|
||||
|
||||
const query = "What is the meaning of life?";
|
||||
|
||||
// Query
|
||||
const response = await queryEngine.query({
|
||||
query,
|
||||
});
|
||||
|
||||
// Log the response
|
||||
console.log(response.response);
|
||||
}
|
||||
```
|
||||
|
||||
## Feedback
|
||||
|
||||
If you have any feedback, please reach out to us at [feedback@deepinfra.com](mailto:feedback@deepinfra.com)
|
||||
|
||||
## API Reference
|
||||
|
||||
- [DeepInfra](/docs/api/classes/DeepInfra)
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user