Skip to content

Commit

Permalink
Implement Inference API (#67)
Browse files Browse the repository at this point in the history
## Problem
The `2024-07` release of the Pinecone API included [Inference
operations](https://docs.pinecone.io/reference/api/2024-07/inference/generate-embeddings).
Currently `pinecone-ts-client`, `pinecone-python-client`, and
`pinecone-rust-client` support Inference.

We'd like to expose the `Embed` operation in the Go SDK.

## Solution
I followed a similar approach to how we've addressed adding inference in
other SDKs. Specifically, after discussing things internally I've opted
to add an `Inference` namespace to the `Client` struct to add separation
between existing index management operations, and inference-related
operations such as `Embed`. This approach is similar to the
implementation in Python and TypeScript.

- Add new structs: `EmbedRequest`, `EmbedParameters`, and
`InferenceService`. Add a new `Inference` field to `Client` which holds
an `*InferenceService` value allowing users to interact with the
Inference API.
- Attach new `Embed` method to `InferenceService` which wraps the
underlying `Embed` call on `*control.Client`, and handles massaging the
input and output to match the generated types.
- Add new integration tests to cover `Embed` in `client_test.go`.
- Add doc comments to new code, update README to include an Inference
section.

## Type of Change
- [ ] Bug fix (non-breaking change which fixes an issue)
- [X] New feature (non-breaking change which adds functionality)
- [ ] Breaking change (fix or feature that would cause existing
functionality to not work as expected)
- [ ] This change requires a documentation update
- [ ] Infrastructure change (CI configs, etc)
- [ ] Non-code change (docs, etc)
- [ ] None of the above: (explain here)

## Test Plan
Added integration tests to validate calling the new
`client.Inference.Embed()` function.

In order to test yourself you'll need to consume this branch as a
dependency locally, and then call the `Embed` operation:

`go get` the branch for this PR:
```bash
go get github.com/pinecone-io/go-pinecone@adenoble/implement-inference
```
In your Go code:
```go
ctx := context.Background()

pc, err := pinecone.NewClient(pinecone.NewClientParams{
    ApiKey: "YOUR_API_KEY",
})
if err !=  nil {
    log.Fatalf("Failed to create Client: %v", err)
}

embeddingModel := "multilingual-e5-large"
documents := []string{
    "Turkey is a classic meat to eat at American Thanksgiving."
    "Many people enjoy the beautiful mosques in Turkey."
}
docParameters := pinecone.EmbedParameters{
    InputType: "passage",
    Truncate: "END",
}

docEmbeddingsResponse, err := pc.Inference.Embed(ctx, &pinecone.EmbedRequest{
    Model: embeddingModel,
    TextInputs: documents,
    Parameters: docParameters,
})
if err != nil {
    log.Fatalf("Failed to embed documents: %v", err)
}
fmt.Printf("docs embedding response: %+v", docEmbeddingsResponse)
```
  • Loading branch information
austin-denoble authored Aug 22, 2024
1 parent b1754c6 commit cf879fb
Show file tree
Hide file tree
Showing 4 changed files with 305 additions and 66 deletions.
85 changes: 76 additions & 9 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -403,7 +403,7 @@ func main() {

The following examlpe describes the statistics of an index by name.

```Go
```go
package main

import (
Expand Down Expand Up @@ -781,7 +781,7 @@ func main() {
The following example deletes a vector by its ID value from `example-index` and `example-namespace`. You can pass a
slice of vector IDs to `DeleteVectorsById`.

```Go
```go
package main

import (
Expand Down Expand Up @@ -829,7 +829,7 @@ func main() {

The following example deletes vectors from `example-index` using a metadata filter.

```Go
```go
package main

import (
Expand Down Expand Up @@ -884,7 +884,7 @@ func main() {

The following example deletes all vectors from `example-index` and `example-namespace`.

```Go
```go
package main

import (
Expand Down Expand Up @@ -1012,7 +1012,7 @@ func main() {

The following example updates vectors by ID in `example-index` and `example-namespace`.

```Go
```go
package main

import (
Expand Down Expand Up @@ -1145,7 +1145,7 @@ Collections are only available for pod-based indexes.

The following example creates a collection from a source index.

```Go
```go
package main

import (
Expand Down Expand Up @@ -1186,7 +1186,7 @@ func main() {

The following example lists all collections in your Pinecone project.

```Go
```go
package main

import (
Expand Down Expand Up @@ -1231,7 +1231,7 @@ func main() {

The following example describes a collection by name.

```Go
```go
package main

import (
Expand Down Expand Up @@ -1269,7 +1269,7 @@ func main() {

The following example deletes a collection by name.

```Go
```go
package main

import (
Expand Down Expand Up @@ -1305,6 +1305,73 @@ func main() {
}
```

## Inference

The `Client` object has an `Inference` namespace which allows interacting with Pinecone's [Inference API](https://docs.pinecone.io/reference/api/2024-07/inference/generate-embeddings). The Inference API is a service that gives you access to embedding models hosted on Pinecone's infrastructure. Read more at [Understanding Pinecone Inference](https://docs.pinecone.io/guides/inference/understanding-inference).

**Notes:**

Models currently supported:

- [multilingual-e5-large](https://docs.pinecone.io/guides/inference/understanding-inference#embedding-models)

### Create Embeddings

Send text to Pinecone's inference API to generate embeddings for documents and queries.

```go
ctx := context.Background()

pc, err := pinecone.NewClient(pinecone.NewClientParams{
ApiKey: "YOUR_API_KEY",
})
if err != nil {
log.Fatalf("Failed to create Client: %v", err)
}

embeddingModel := "multilingual-e5-large"
documents := []string{
"Turkey is a classic meat to eat at American Thanksgiving."
"Many people enjoy the beautiful mosques in Turkey."
}
docParameters := pinecone.EmbedParameters{
InputType: "passage",
Truncate: "END",
}

docEmbeddingsResponse, err := pc.Inference.Embed(ctx, &pinecone.EmbedRequest{
Model: embeddingModel,
TextInputs: documents,
Parameters: docParameters,
})
if err != nil {
log.Fatalf("Failed to embed documents: %v", err)
}
fmt.Printf("docs embedding response: %+v", docEmbeddingsResponse)

// << Upsert documents into Pinecone >>

userQuery := []string{
"How should I prepare my turkey?"
}
queryParameters := pinecone.EmbedParameters{
InputType: "query",
Truncate: "END",
}
queryEmbeddingsResponse, err := pc.Inference.Embed(ctx, &pinecone.EmbedRequest{
Model: embeddingModel,
TextInputs: userQuery,
Parameters: queryParameters
})
if err != nil {
log.Fatalf("Failed to embed query: %v", err)
}
fmt.Printf("query embedding response: %+v", queryEmbeddingsResponse)

// << Send query to Pinecone to retrieve similar documents >>

```

## Support

To get help using go-pinecone you can file an issue on [GitHub](https://github.com/pinecone-io/go-pinecone/issues), visit the [community forum](https://community.pinecone.io/),
Expand Down
Loading

0 comments on commit cf879fb

Please sign in to comment.