Skip to content

Instantly share code, notes, and snippets.

@kentcdodds
Created October 13, 2023 06:13
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save kentcdodds/57eb495fae47f200b5f1e9278fbe26e4 to your computer and use it in GitHub Desktop.
Save kentcdodds/57eb495fae47f200b5f1e9278fbe26e4 to your computer and use it in GitHub Desktop.
import 'dotenv/config.js'
import chromadb from 'chromadb'
import { RetrievalQAChain } from 'langchain/chains'
import { ChatOpenAI } from 'langchain/chat_models/openai'
import { OpenAIEmbeddings } from 'langchain/embeddings/openai'
import { Chroma } from 'langchain/vectorstores/chroma'
const { OpenAIEmbeddingFunction, ChromaClient } = chromadb
const COLLECTION_NAME = 'test-collection'
const DB_URL = 'https://epic-chromadb.fly.dev'
if (!process.env.CHROMA_SERVER_AUTH_CREDENTIALS) {
throw new Error('CHROMA_SERVER_AUTH_CREDENTIALS is not set')
}
if (!process.env.OPENAI_API_KEY) {
throw new Error('OPENAI_API_KEY is not set')
}
export const client = new ChromaClient({
path: DB_URL,
auth: {
provider: 'token',
credentials: process.env.CHROMA_SERVER_AUTH_CREDENTIALS,
},
})
const embedder = new OpenAIEmbeddingFunction({
openai_api_key: process.env.OPENAI_API_KEY,
})
await client.deleteCollection({ name: COLLECTION_NAME })
const collection = await client.createCollection({
name: COLLECTION_NAME,
embeddingFunction: embedder,
})
collection.add({
ids: ['mary', 'spiderman'],
documents: [
`Mary had a little lamb, it's fleece was white as snow, and everywhere that Mary went, the lamb was sure to go`,
`Spiderman is a superhero who lives in New York City. His real name is Peter Parker and he was bitten by a radioactive spider.`,
],
metadatas: [{ name: 'mary' }, { name: 'spiderman' }],
})
const vectorStore = await Chroma.fromExistingCollection(
new OpenAIEmbeddings({ openAIApiKey: process.env.OPENAI_API_KEY }),
{ collectionName: COLLECTION_NAME, url: DB_URL, index: client }
)
const model = new ChatOpenAI({ modelName: 'gpt-3.5-turbo' })
const chain = RetrievalQAChain.fromLLM(model, vectorStore.asRetriever())
const response = await chain.call({
query: `What color was the lamb?`,
})
console.log(response) // <-- gives something like:
// { text: "I'm sorry, but I don't have enough information to answer that question." }
@kentcdodds
Copy link
Author

With verbose mode enabled:

[chain/start] [1:chain:RetrievalQAChain] Entering Chain run with input: {
  "query": "What color was the lamb?"
}
[retriever/start] [1:chain:RetrievalQAChain > 2:retriever:VectorStoreRetriever] Entering Retriever run with input: {
  "query": "What color was the lamb?"
}
[retriever/end] [1:chain:RetrievalQAChain > 2:retriever:VectorStoreRetriever] [930ms] Exiting Retriever run with output: {
  "documents": []
}
[chain/start] [1:chain:RetrievalQAChain > 3:chain:StuffDocumentsChain] Entering Chain run with input: {
  "question": "What color was the lamb?",
  "input_documents": [],
  "query": "What color was the lamb?"
}
[chain/start] [1:chain:RetrievalQAChain > 3:chain:StuffDocumentsChain > 4:chain:LLMChain] Entering Chain run with input: {
  "question": "What color was the lamb?",
  "query": "What color was the lamb?",
  "context": ""
}
[llm/start] [1:chain:RetrievalQAChain > 3:chain:StuffDocumentsChain > 4:chain:LLMChain > 5:llm:ChatOpenAI] Entering LLM run with input: {
  "messages": [
    [
      {
        "lc": 1,
        "type": "constructor",
        "id": [
          "langchain",
          "schema",
          "SystemMessage"
        ],
        "kwargs": {
          "content": "Use the following pieces of context to answer the users question. \nIf you don't know the answer, just say that you don't know, don't try to make up an answer.\n----------------\n",
          "additional_kwargs": {}
        }
      },
      {
        "lc": 1,
        "type": "constructor",
        "id": [
          "langchain",
          "schema",
          "HumanMessage"
        ],
        "kwargs": {
          "content": "What color was the lamb?",
          "additional_kwargs": {}
        }
      }
    ]
  ]
}
[llm/end] [1:chain:RetrievalQAChain > 3:chain:StuffDocumentsChain > 4:chain:LLMChain > 5:llm:ChatOpenAI] [2.48s] Exiting LLM run with output: {
  "generations": [
    [
      {
        "text": "I don't know what color the lamb was.",
        "message": {
          "lc": 1,
          "type": "constructor",
          "id": [
            "langchain",
            "schema",
            "AIMessage"
          ],
          "kwargs": {
            "content": "I don't know what color the lamb was.",
            "additional_kwargs": {}
          }
        },
        "generationInfo": {
          "finish_reason": "stop"
        }
      }
    ]
  ],
  "llmOutput": {
    "tokenUsage": {
      "completionTokens": 10,
      "promptTokens": 57,
      "totalTokens": 67
    }
  }
}
[chain/end] [1:chain:RetrievalQAChain > 3:chain:StuffDocumentsChain > 4:chain:LLMChain] [2.48s] Exiting Chain run with output: {
  "text": "I don't know what color the lamb was."
}
[chain/end] [1:chain:RetrievalQAChain > 3:chain:StuffDocumentsChain] [2.48s] Exiting Chain run with output: {
  "text": "I don't know what color the lamb was."
}
[chain/end] [1:chain:RetrievalQAChain] [3.42s] Exiting Chain run with output: {
  "text": "I don't know what color the lamb was."
}

@kentcdodds
Copy link
Author

I forgot to add an await to collection.add 🤦‍♂️

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment