Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
44 changes: 21 additions & 23 deletions modules/ROOT/pages/embeddings.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -35,8 +35,7 @@ The embeddings on this page are generated using the link:https://platform.openai
[.include-with-Store-embedding-as-a-vector]
======

`genai.vector.encode()` returns a `LIST<FLOAT>`.
To convert and store this value as a link:https://neo4j.com/docs/cypher-manual/25/values-and-types/vector/[`VECTOR`], use the link:https://neo4j.com/docs/cypher-manual/25/functions/vector/#functions-vector[`vector()`] function.
`ai.text.embed()` returns a `VECTOR`.
Storing `VECTOR` values on self-managed instances requires Enterprise Edition and link:{neo4j-docs-base-uri}/operations-manual/current/database-internals/store-formats/#store-format-overview[block format].

.Create a `VECTOR` embedding property for the Godfather
Expand All @@ -45,8 +44,8 @@ Storing `VECTOR` values on self-managed instances requires Enterprise Edition an
MATCH (m:Movie {title:'Godfather, The'})
WHERE m.plot IS NOT NULL AND m.title IS NOT NULL
WITH m, m.title || ' ' || m.plot AS titleAndPlot // <1>
WITH m, genai.vector.encode(titleAndPlot, 'OpenAI', { token: $openaiToken }) AS vector // <2>
SET m.embedding = vector(vector, 1536, FLOAT32) // <3>
WITH m, ai.text.embed(titleAndPlot, 'OpenAI', { token: $openaiToken }) AS vector // <2>
SET m.embedding = vector // <3>
RETURN m.embedding AS embedding
----

Expand Down Expand Up @@ -98,8 +97,8 @@ The embeddings are stored as properties on nodes or relationships with the type
MATCH (m:Movie {title:'Godfather, The'})
WHERE m.plot IS NOT NULL AND m.title IS NOT NULL
WITH m, m.title || ' ' || m.plot AS titleAndPlot // <1>
WITH m, genai.vector.encode(titleAndPlot, 'OpenAI', { token: $openaiToken }) AS vector // <2>
CALL db.create.setNodeVectorProperty(m, 'embedding', vector) // <3>
WITH m, ai.text.embed(titleAndPlot, 'OpenAI', { token: $openaiToken }) AS vector // <2>
CALL db.create.setNodeVectorProperty(m, 'embedding', toFloatList(vector)) // <3>
RETURN m.embedding AS embedding
----

Expand All @@ -124,7 +123,7 @@ RETURN m.embedding AS embedding
[[multiple-embeddings]]
== Generate a batch of embeddings and store them

Use the `genai.vector.encodeBatch` procedure to generate many vector embeddings with a single API request.
Use the `ai.text.embedBatch` procedure to generate many vector embeddings with a single API request.
This procedure takes a list of resources as an input, and returns the same number of result rows.

[IMPORTANT]
Expand All @@ -133,10 +132,10 @@ This procedure attempts to generate embeddings for all supplied resources in a s
Check the respective provider's documentation for details on, for example, the maximum number of embeddings that can be generated per request.
====

.Signature for `genai.vector.encodeBatch` label:procedure[]
.Signature for `ai.text.embedBatch` label:procedure[]
[source,syntax]
----
genai.vector.encodeBatch(resources :: LIST<STRING>, provider :: STRING, configuration :: MAP = {}) :: (index :: INTEGER, resource :: STRING, vector :: LIST<FLOAT>)
ai.text.embedBatch(resources :: LIST<STRING>, provider :: STRING, configuration :: MAP = {}) :: (index :: INTEGER, resource :: STRING, vector :: VECTOR)
----

* The `resources` (a `LIST<STRING>`) parameter is the list of objects to transform into embeddings, such as chunks of text.
Expand All @@ -150,16 +149,15 @@ However, if the function call is misspelled or the query is otherwise malformed,
Each returned row contains the following columns:

* The `index` (an `INTEGER`) is the index of the corresponding element in the input list, to aid in correlating results back to inputs.
* The `resource` (a `STRING`) is the name of the input resource.
* The `vector` (a `LIST<FLOAT>`) is the generated vector embedding for this resource.
* The `resource` (a `STRING`) is the given input resource.
* The `vector` (a `VECTOR`) is the generated vector embedding for this resource.

[.tabbed-example]
====
[.include-with-Store-embeddings-as-vectors]
======

`genai.vector.encode()` returns a `LIST<FLOAT>`.
To convert and store this value as a link:https://neo4j.com/docs/cypher-manual/25/values-and-types/vector/[`VECTOR`], use the link:https://neo4j.com/docs/cypher-manual/25/functions/vector/#functions-vector[`vector()`] function.
`ai.text.embed()` returns a `VECTOR`.
Storing `VECTOR` values on an on-prem instance requires Enterprise Edition and link:{neo4j-docs-base-uri}/operations-manual/current/database-internals/store-formats/#store-format-overview[block format].

.Create embeddings from a limited number of properties and store them as `VECTOR` properties
Expand All @@ -170,15 +168,15 @@ WITH m
LIMIT 20
WITH collect(m) AS moviesList // <1>
WITH moviesList, [movie IN moviesList | movie.title || ': ' || movie.plot] AS batch // <2>
CALL genai.vector.encodeBatch(batch, 'OpenAI', { token: $openaiToken }) YIELD index, vector
CALL ai.text.embedBatch(batch, 'OpenAI', { token: $openaiToken }) YIELD index, vector
WITH moviesList, index, vector
MATCH (toUpdate:Movie {title: moviesList[index]['title']})
SET toUpdate.embedding = vector(vector, 1536, FLOAT32) // <3>
SET toUpdate.embedding = vector // <3>
----

<1> link:https://neo4j.com/docs/cypher-manual/25/functions/aggregating/#functions-collect[Collect] all 20 `Movie` nodes into a `LIST<NODE>`.
<2> A link:https://neo4j.com/docs/cypher-manual/25/expressions/list-expressions/#list-comprehension[list comprehension] (`[]`) extracts the `title` and `plot` properties of the movies in `moviesList` into a new `LIST<STRING>`.
<3> `db.create.setNodeVectorProperty` is run for each `vector` returned by `genai.vector.encodeBatch()`, and stores that vector as a property named `embedding` on the corresponding node.
<3> `SET` is run for each `vector` returned by `ai.text.embedBatch()`, and stores that vector as a property named `embedding` on the corresponding node.

.Create embeddings from a large number properties and store them as `VECTOR` properties
[source, cypher]
Expand All @@ -190,9 +188,9 @@ WITH collect(m) AS moviesList, // <1>
UNWIND range(0, total-1, batchSize) AS batchStart // <3>
CALL (moviesList, batchStart, batchSize) { // <4>
WITH [movie IN moviesList[batchStart .. batchStart + batchSize] | movie.title || ': ' || movie.plot] AS batch // <5>
CALL genai.vector.encodeBatch(batch, 'OpenAI', { token: $openaiToken }) YIELD index, vector
CALL ai.text.embedBatch(batch, 'OpenAI', { token: $openaiToken }) YIELD index, vector
MATCH (toUpdate:Movie {title: moviesList[batchStart + index]['title']})
SET toUpdate.embedding = vector(vector, 1536, FLOAT32) // <6>
SET toUpdate.embedding = vector // <6>
} IN CONCURRENT TRANSACTIONS OF 1 ROW // <7>
----

Expand Down Expand Up @@ -249,14 +247,14 @@ WITH m
LIMIT 20
WITH collect(m) AS moviesList // <1>
WITH moviesList, [movie IN moviesList | movie.title || ': ' || movie.plot] AS batch // <2>
CALL genai.vector.encodeBatch(batch, 'OpenAI', { token: $openaiToken }) YIELD index, vector
CALL ai.text.embedBatch(batch, 'OpenAI', { token: $openaiToken }) YIELD index, vector
WITH moviesList, index, vector
CALL db.create.setNodeVectorProperty(moviesList[index], 'embedding', vector) // <3>
CALL db.create.setNodeVectorProperty(moviesList[index], 'embedding', toFloatList(vector)) // <3>
----

<1> link:https://neo4j.com/docs/cypher-manual/25/functions/aggregating/#functions-collect[Collect] all 20 `Movie` nodes into a `LIST<NODE>`.
<2> A link:https://neo4j.com/docs/cypher-manual/25/expressions/list-expressions/#list-comprehension[list comprehension] (`[]`) extracts the `title` and `plot` properties of the movies in `moviesList` into a new `LIST<STRING>`.
<3> `db.create.setNodeVectorProperty` is run for each `vector` returned by `genai.vector.encodeBatch()`, and stores that vector as a property named `embedding` on the corresponding node.
<3> `db.create.setNodeVectorProperty` is run for each `vector` returned by `ai.text.embedBatch()`, and stores that vector as a property named `embedding` on the corresponding node.

.Create embeddings from a large number properties and store them as `LIST<FLOAT>` values
[source, cypher]
Expand All @@ -268,8 +266,8 @@ WITH collect(m) AS moviesList, // <1>
UNWIND range(0, total-1, batchSize) AS batchStart // <3>
CALL (moviesList, batchStart, batchSize) { // <4>
WITH [movie IN moviesList[batchStart .. batchStart + batchSize] | movie.title || ': ' || movie.plot] AS batch // <5>
CALL genai.vector.encodeBatch(batch, 'OpenAI', { token: $openaiToken }) YIELD index, vector
CALL db.create.setNodeVectorProperty(moviesList[batchStart + index], 'embedding', vector) // <6>
CALL ai.text.embedBatch(batch, 'OpenAI', { token: $openaiToken }) YIELD index, vector
CALL db.create.setNodeVectorProperty(moviesList[batchStart + index], 'embedding', toFloatList(vector)) // <6>
} IN CONCURRENT TRANSACTIONS OF 1 ROW // <7>
----

Expand Down
216 changes: 212 additions & 4 deletions modules/ROOT/pages/reference/ai-providers.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,217 @@
This page lists the supported AI providers.
Each provider has its own configuration map that can be passed to Neo4j's GenAI function/procedures.

[[text-embedding-ai-providers]]
== Text Embedding AI Providers

The following provider configurations are for the `ai.text.embed` function and the `ai.text.embedBatch` procedure.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
The following provider configurations are for the `ai.text.embed` function and the `ai.text.embedBatch` procedure.
The following provider configurations are for the `ai.text.embed` function and the `ai.text.embedBatch` procedure.
TODO: Add link to function+procedure.


The text embedding callables currently support the following providers:

- OpenAI (`openai`)
- Azure OpenAI (`azure-openai`)
- Google Vertex AI (`vertexai`)
- Amazon Bedrock Titan Models (`bedrock-titan`)

You can use the query `CALL ai.text.embed.providers()` to retrieve a list of the providers supported in your version of the plugin.

.ai.text.embed.providers() label:procedure[]
|===
| *Syntax* 3+m| ai.text.embed.providers() :: (name :: STRING, requiredConfigType :: STRING, optionalConfigType :: STRING, defaultConfig :: MAP)
| *Description* 3+a| Lists the available vector embedding providers.
.5+| *Return arguments* | *Name* | *Type* | *Description*
| `name` | `STRING` | The name of the GenAI provider.
| `requiredConfigType` | `STRING` | The signature of the required config map.
| `optionalConfigType` | `STRING` | "The signature of the optional config map.
| `defaultConfig` | `MAP` | The default values for the GenAI provider.
|===

=== OpenAI

.OpenAI configuration parameters
[opts=header, cols="1,1,1,3"]
|===
| *Name* | *Type* | *Default* | *Description*
| `model` | `STRING` | - | Model id (see https://platform.openai.com/docs/models[OpenAI -> Models]).
| `token` | `STRING` | - | OpenAI API key (see https://platform.openai.com/api-keys[OpenAI -> API Keys]).
| `vendorOptions` | `MAP` | `{}` | Optional vendor options that will be passed on as-is in the request to Open AI (see https://platform.openai.com/docs/api-reference/embeddings/create[OpenAI -> Create embeddings]).
|===

==== Usage example
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think these extra titles clog the UI unnecessarily. I would remove them and put the heading content Usage example as title of the example, instead of Query. Or, even better, give a meaningful title to the example (ex. "Embed the string Hello world").


.Query
[source, cypher, indent=0]
----
WITH
{
token: $openAiApiKey,
model: 'text-embedding-ada-002',
vendorOptions: {
dimensions: 1024,
user: 'testBot'
}
} AS conf
RETURN ai.text.embed('Hello World!', 'openai', conf) AS result
----

.Result
[role="queryresult",options="header,footer",cols="1*<m"]
|===

| result
| [0.0023064255, -0.009327292, .... (1024 coordinates total as requested), -0.0028842222]
1+d|Rows: 1

|===


=== Azure OpenAI

This provider can be used with Azure OpenAI.

.OpenAI configuration parameters
[opts=header, cols="1,1,1,3"]
|===
| *Name* | *Type* | *Default* | *Description*
| `model` | `STRING` | - | Model id (see https://learn.microsoft.com/en-us/azure/ai-foundry/openai/overview[Azure -> Azure OpenAI in Foundry Models]).
| `resource` | `STRING` | - | Azure resource name.
| `token` | `STRING` | - | Azure OAuth2 bearer token.
| `vendorOptions` | `MAP` | `{}` | Optional vendor options that will be passed on as-is in the request to Azure.
|===

==== Usage example

.Query
[source, cypher, indent=0]
----
WITH
{
token: $azureToken,
resource: 'my-azure-openai-resource',
model: 'text-embedding-3-small',
vendorOptions: {
dimensions: 1024,
user: 'testBot'
}
} AS conf
RETURN ai.text.embed('Hello World!', 'azure-openai', conf) AS result
----

.Result
[role="queryresult",options="header,footer",cols="1*<m"]
|===

| result
| [0.0023064255, -0.009327292, .... (1024 coordinates total as requested), -0.0028842222]
1+d|Rows: 1

|===

=== Google Vertex AI

.Vertex configuration parameters
[opts=header, cols="1,1,1,3"]
|===
| *Name* | *Type* | *Default* | *Description*
| `model` | `STRING` | - | Model resource name (see https://console.cloud.google.com/vertex-ai/model-garden[Vertex AI -> Model Garden]).
| `project` | `STRING` | - | Google cloud project ID.
| `region` | `STRING` | - | Google cloud region (see https://cloud.google.com/vertex-ai/docs/general/locations[Vertex AI -> Locations]).
| `publisher` | `STRING` | 'google' | Model publisher.
| `token` | `STRING` | - | Vertex API access token.
| `vendorOptions` | `MAP` | `{}` | Optional vendor options that will be passed on as-is in the request to Vertex (see https://cloud.google.com/vertex-ai/generative-ai/docs/reference/rest/v1/projects.locations.publishers.models/predict[Vertex AI -> Method: models.predict]).
|===

==== Usage example

.Query
[source, cypher, indent=0]
----
WITH
{
token: $vertexApiAccessKey,
model: 'gemini-embedding-001',
publisher: 'google',
project: 'my-google-cloud-project',
region: 'asia-northeast1',
vendorOptions: {
title: 'Test Title',
taskType: 'QUESTION_ANSWERING',
outputDimensionality: 1024,
autoTruncate: true
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there a value to all these options here? Not all of them are obvious as to what they do, and people would need to consult 3rd-party docs to find out. I get that we want to display the shape of a full request, but outputDimensionality would be enough, no?

}
} AS conf
RETURN ai.text.complete('Hello World!', 'vertexai', conf) AS result
----

.Result
[role="queryresult",options="header,footer",cols="1*<m"]
|===

| result
| [0.0023064255, -0.009327292, .... (1024 coordinates total as requested), -0.0028842222]
1+d|Rows: 1

|===

[[amazon-bedrock-titan]]
=== Amazon Bedrock Titan Models

This provider gives support for all models that uses the same request parameters and response fields as the Titan text models.

.Amazon Bedrock Titan Configuration
[opts=header, cols="1,1,1,3"]
|===
| *Name* | *Type* | *Default* | *Description*
| `model` | `STRING` | - | Model ID or its ARN.
| `region` | `STRING` | - | Amazon region (see https://docs.aws.amazon.com/bedrock/latest/userguide/models-regions.html[Amazon Bedrock -> Model Support]).
| `accessKeyId` | `STRING` | - | Amazon access key id.
| `secretAccessKey` | `STRING` | - | Amazon secret access key.
| `vendorOptions` | `MAP` | `{}` | Optional vendor options that will be passed on as-is in the request to Bedrock (see https://docs.aws.amazon.com/bedrock/latest/userguide/model-parameters.html[Amazon Bedrock -> Inference request parameters and response fields]).
|===

==== Usage example

.Query
[source, cypher, indent=0]
----
WITH
{
accessKeyId: $awsAccessKeyId,
secretAccessKey: $secretAccessKey,
model: 'amazon.titan-embed-text-v1',
region: 'eu-west-2',
vendorOptions: {
dimensions: 1024,
normalize: true
}
} AS conf
RETURN ai.text.embed('Hello World!', 'bedrock-titan', conf) AS result
----

.Result
[role="queryresult",options="header,footer",cols="1*<m"]
|===

| result
| [0.0023064255, -0.009327292, .... (1024 coordinates total as requested), -0.0028842222]
1+d|Rows: 1

|===

[[vector-encoding-ai-providers]]
== Vector Encoding AI Providers

The following provider configurations are for the `genai.vector.encode` function and the `genai.vector.encodeBatch` procedure.

The text embedding callables currently support the following providers:

- OpenAI (`openai`)
- Azure OpenAI (`azure-openai`)
- Google Vertex AI (`vertexai`)
- Amazon Bedrock Models (`bedrock`)

[[openai]]
== OpenAI
=== OpenAI

* Identifier (`provider` argument): `"OpenAI"`
* https://platform.openai.com/docs/guides/embeddings[Official OpenAI documentation]
Expand Down Expand Up @@ -33,7 +241,7 @@ Each provider has its own configuration map that can be passed to Neo4j's GenAI


[[vertex-ai]]
== Vertex AI
=== Vertex AI

* Identifier (`provider` argument): `"VertexAI"`
* https://cloud.google.com/vertex-ai/generative-ai/docs/embeddings/get-text-embeddings[Official Vertex AI documentation]
Expand Down Expand Up @@ -123,7 +331,7 @@ Supported values: +


[[azure-openai]]
== Azure OpenAI
=== Azure OpenAI

* Identifier (`provider` argument): `"AzureOpenAI"`
* https://learn.microsoft.com/en-us/azure/ai-foundry/[Official Azure OpenAI documentation]
Expand Down Expand Up @@ -159,7 +367,7 @@ Unlike the other providers, the model is configured when creating the deployment


[[amazon-bedrock]]
== Amazon Bedrock
=== Amazon Bedrock

* Identifier (`provider` argument): `"Bedrock"`
* https://docs.aws.amazon.com/bedrock/latest/APIReference/welcome.html[Official Bedrock documentation]
Expand Down
Loading