Skip to content

Commit 16ee7a0

Browse files
committed
Added OpenAI example [skip ci]
1 parent eaa9e9f commit 16ee7a0

File tree

4 files changed

+102
-1
lines changed

4 files changed

+102
-1
lines changed

.gitignore

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
1-
/build/
1+
build
22
/test/pqxx

README.md

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,10 @@ And follow the instructions for your database library:
2222

2323
- [libpqxx](#libpqxx)
2424

25+
Or check out an example:
26+
27+
- [Embeddings](examples/openai/example.cpp) with OpenAI
28+
2529
## libpqxx
2630

2731
Include the header
@@ -94,3 +98,13 @@ createdb pgvector_cpp_test
9498
g++ -std=c++17 -Wall -Wextra -Wno-unknown-attributes -Werror -o test/pqxx test/pqxx_test.cpp -lpqxx -lpq
9599
test/pqxx
96100
```
101+
102+
To run an example:
103+
104+
```sh
105+
cd examples/openai
106+
createdb pgvector_example
107+
cmake -S . -B build
108+
cmake --build build
109+
build/example
110+
```

examples/openai/CMakeLists.txt

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
cmake_minimum_required(VERSION 3.18)
2+
3+
project(example)
4+
5+
set(CMAKE_CXX_STANDARD 17)
6+
set(CMAKE_CXX_FLAGS "-Wno-unknown-attributes")
7+
8+
include(FetchContent)
9+
10+
FetchContent_Declare(cpr GIT_REPOSITORY https://github.com/libcpr/cpr.git GIT_TAG 1.11.1)
11+
FetchContent_Declare(json GIT_REPOSITORY https://github.com/nlohmann/json.git GIT_TAG v3.11.3)
12+
FetchContent_Declare(libpqxx GIT_REPOSITORY https://github.com/jtv/libpqxx.git GIT_TAG 7.10.0)
13+
FetchContent_MakeAvailable(cpr json libpqxx)
14+
15+
add_executable(example example.cpp)
16+
target_include_directories(example PRIVATE ${CMAKE_SOURCE_DIR}/../../include)
17+
target_link_libraries(example PRIVATE cpr::cpr nlohmann_json::nlohmann_json pqxx)

examples/openai/example.cpp

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
#include <cstdint>
2+
#include <iostream>
3+
4+
#include <cpr/cpr.h>
5+
#include <nlohmann/json.hpp>
6+
// TODO make <pgvector/pqxx.hpp>
7+
#include <pqxx.hpp>
8+
#include <pqxx/pqxx>
9+
10+
using json = nlohmann::json;
11+
12+
// https://platform.openai.com/docs/guides/embeddings/how-to-get-embeddings
13+
// input can be an array with 2048 elements
14+
std::vector<std::vector<float>> fetch_embeddings(const std::vector<std::string>& input, char *api_key) {
15+
std::string url = "https://api.openai.com/v1/embeddings";
16+
json data = {
17+
{"input", input},
18+
{"model", "text-embedding-3-small"}
19+
};
20+
21+
cpr::Response r = cpr::Post(
22+
cpr::Url{url},
23+
cpr::Body{data.dump()},
24+
cpr::Bearer{api_key},
25+
cpr::Header{{"Content-Type", "application/json"}}
26+
);
27+
json response = json::parse(r.text);
28+
29+
std::vector<std::vector<float>> embeddings;
30+
for (auto& v: response["data"]) {
31+
embeddings.emplace_back(v["embedding"]);
32+
}
33+
return embeddings;
34+
}
35+
36+
int main() {
37+
char *api_key = std::getenv("OPENAI_API_KEY");
38+
if (!api_key) {
39+
std::cout << "Set OPENAI_API_KEY" << std::endl;
40+
return 1;
41+
}
42+
43+
pqxx::connection conn("dbname=pgvector_example");
44+
45+
pqxx::work tx(conn);
46+
tx.exec("CREATE EXTENSION IF NOT EXISTS vector");
47+
tx.exec("DROP TABLE IF EXISTS documents");
48+
tx.exec("CREATE TABLE documents (id bigserial PRIMARY KEY, content text, embedding vector(1536))");
49+
tx.commit();
50+
51+
std::vector<std::string> input = {
52+
"The dog is barking",
53+
"The cat is purring",
54+
"The bear is growling"
55+
};
56+
auto embeddings = fetch_embeddings(input, api_key);
57+
58+
for (size_t i = 0; i < input.size(); i++) {
59+
tx.exec("INSERT INTO documents (content, embedding) VALUES ($1, $2)", {input[i], pgvector::Vector(embeddings[i])});
60+
}
61+
tx.commit();
62+
63+
int64_t document_id = 1;
64+
pqxx::result result = tx.exec("SELECT content FROM documents WHERE id != $1 ORDER BY embedding <=> (SELECT embedding FROM documents WHERE id = $1) LIMIT 5", {document_id});
65+
for (auto const& row : result) {
66+
std::cout << row[0].c_str() << std::endl;
67+
}
68+
69+
return 0;
70+
}

0 commit comments

Comments
 (0)