Skip to content

Commit add4900

Browse files
authored
fix(sdk): manually report VectorDB spans (#174)
1 parent 86d4f4d commit add4900

File tree

3 files changed

+112
-20
lines changed

3 files changed

+112
-20
lines changed

packages/ai-semantic-conventions/src/SemanticAttributes.ts

+36-20
Original file line numberDiff line numberDiff line change
@@ -33,8 +33,8 @@ export const SpanAttributes = {
3333
LLM_CHAT_STOP_SEQUENCES: "llm.chat.stop_sequences",
3434

3535
// Vector DB
36-
VECTOR_DB_VENDOR: "vector_db.vendor",
37-
VECTOR_DB_QUERY_TOP_K: "vector_db.query.top_k",
36+
VECTOR_DB_VENDOR: "db.system",
37+
VECTOR_DB_QUERY_TOP_K: "db.vector.query.top_k",
3838

3939
// LLM Workflows
4040
TRACELOOP_SPAN_KIND: "traceloop.span.kind",
@@ -45,31 +45,47 @@ export const SpanAttributes = {
4545
TRACELOOP_ENTITY_OUTPUT: "traceloop.entity.output",
4646
};
4747

48+
export const Events = {
49+
DB_QUERY_EMBEDDINGS: "db.query.embeddings",
50+
DB_QUERY_RESULT: "db.query.result",
51+
};
52+
4853
export const EventAttributes = {
49-
// Vector DB Query Request
50-
VECTOR_DB_QUERY_TOP_K: "vector_db.query.top_k",
51-
VECTOR_DB_QUERY_INCLUDE_VALUES: "vector_db.query.include_values",
52-
VECTOR_DB_QUERY_INCLUDE_METADATA: "vector_db.query.include_metadata",
53-
VECTOR_DB_QUERY_ID: "vector_db.query.id",
54-
VECTOR_DB_QUERY_EMBEDDINGS_VECTOR: "vector_db.query.embeddings.vector",
55-
VECTOR_DB_QUERY_METADATA_FILTER: "vector_db.query.metadata_filter",
54+
// Query Embeddings
55+
DB_QUERY_EMBEDDINGS_VECTOR: "db.query.embeddings.vector",
56+
57+
// Query Result (canonical format)
58+
DB_QUERY_RESULT_ID: "db.query.result.id",
59+
DB_QUERY_RESULT_SCORE: "db.query.result.score",
60+
DB_QUERY_RESULT_DISTANCE: "db.query.result.distance",
61+
DB_QUERY_RESULT_METADATA: "db.query.result.metadata",
62+
DB_QUERY_RESULT_VECTOR: "db.query.result.vector",
63+
DB_QUERY_RESULT_DOCUMENT: "db.query.result.document",
64+
65+
// DEPRECATED: Vector DB Query Request
66+
VECTOR_DB_QUERY_TOP_K: "db.vector.query.top_k",
67+
VECTOR_DB_QUERY_INCLUDE_VALUES: "db.vector.query.include_values",
68+
VECTOR_DB_QUERY_INCLUDE_METADATA: "db.vector.query.include_metadata",
69+
VECTOR_DB_QUERY_ID: "db.vector.query.id",
70+
VECTOR_DB_QUERY_EMBEDDINGS_VECTOR: "db.vector.query.embeddings.vector",
71+
VECTOR_DB_QUERY_METADATA_FILTER: "db.vector.query.metadata_filter",
5672

57-
// Vector DB Query Response
58-
VECTOR_DB_QUERY_RESULT_NAMESPACE: "vector_db.query.result.namespace",
73+
// DEPRECATED: Vector DB Query Response
74+
VECTOR_DB_QUERY_RESULT_NAMESPACE: "db.vector.query.result.namespace",
5975
VECTOR_DB_QUERY_RESULT_READ_UNITS_CONSUMED:
60-
"vector_db.query.result.read_units",
76+
"db.vector.query.result.read_units",
6177
VECTOR_DB_QUERY_RESULT_MATCHES_LENGTH:
62-
"vector_db.query.result.matches_length",
78+
"db.vector.query.result.matches_length",
6379

64-
// Vector DB Query Response of each result
65-
VECTOR_DB_QUERY_RESULT_SCORE: "vector_db.query.result.{i}.score",
66-
VECTOR_DB_QUERY_RESULT_ID: "vector_db.query.result.{i}.id",
67-
VECTOR_DB_QUERY_RESULT_VALUES: "vector_db.query.result.{i}.values",
80+
// DEPRECATED: Vector DB Query Response of each result
81+
VECTOR_DB_QUERY_RESULT_SCORE: "db.vector.query.result.{i}.score",
82+
VECTOR_DB_QUERY_RESULT_ID: "db.vector.query.result.{i}.id",
83+
VECTOR_DB_QUERY_RESULT_VALUES: "db.vector.query.result.{i}.values",
6884
VECTOR_DB_QUERY_RESULT_SPARSE_INDICES:
69-
"vector_db.query.result.{i}.sparse.indices",
85+
"db.vector.query.result.{i}.sparse.indices",
7086
VECTOR_DB_QUERY_RESULT_SPARSE_VALUES:
71-
"vector_db.query.result.{i}.sparse.values",
72-
VECTOR_DB_QUERY_RESULT_METADATA: "vector_db.query.result.{i}.metadata",
87+
"db.vector.query.result.{i}.sparse.values",
88+
VECTOR_DB_QUERY_RESULT_METADATA: "db.vector.query.result.{i}.metadata",
7389
};
7490

7591
export enum LLMRequestTypeValues {

packages/traceloop-sdk/src/lib/node-server-sdk.ts

+1
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ export { InitializeOptions } from "./interfaces";
55
export { initialize } from "./configuration";
66
export { forceFlush } from "./tracing";
77
export * from "./tracing/decorators";
8+
export * from "./tracing/manual";
89
export * from "./tracing/association";
910
export * from "./tracing/score";
1011
export * from "./prompts";
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
import { Span, context } from "@opentelemetry/api";
2+
import { getTracer } from "./tracing";
3+
import { Events, EventAttributes } from "@traceloop/ai-semantic-conventions";
4+
import { shouldSendTraces } from ".";
5+
6+
type VectorDBCallConfig = {
7+
vendor: string;
8+
type: "query" | "upsert" | "delete";
9+
};
10+
11+
export class VectorSpan {
12+
private span: Span;
13+
14+
constructor(span: Span) {
15+
this.span = span;
16+
}
17+
18+
reportQuery({ queryVector }: { queryVector: number[] }) {
19+
if (!shouldSendTraces()) {
20+
this.span.addEvent(Events.DB_QUERY_EMBEDDINGS);
21+
}
22+
23+
this.span.addEvent(Events.DB_QUERY_EMBEDDINGS, {
24+
[EventAttributes.DB_QUERY_EMBEDDINGS_VECTOR]: JSON.stringify(queryVector),
25+
});
26+
}
27+
28+
reportResults({
29+
results,
30+
}: {
31+
results: {
32+
ids?: string;
33+
scores?: number;
34+
distances?: number;
35+
metadata?: Record<string, unknown>;
36+
vectors?: number[];
37+
documents?: string;
38+
}[];
39+
}) {
40+
for (let i = 0; i < results.length; i++) {
41+
this.span.addEvent(Events.DB_QUERY_RESULT, {
42+
[EventAttributes.DB_QUERY_RESULT_ID]: results[i].ids,
43+
[EventAttributes.DB_QUERY_RESULT_SCORE]: results[i].scores,
44+
[EventAttributes.DB_QUERY_RESULT_DISTANCE]: results[i].distances,
45+
[EventAttributes.DB_QUERY_RESULT_METADATA]: JSON.stringify(
46+
results[i].metadata,
47+
),
48+
[EventAttributes.DB_QUERY_RESULT_VECTOR]: results[i].vectors,
49+
[EventAttributes.DB_QUERY_RESULT_DOCUMENT]: results[i].documents,
50+
});
51+
}
52+
}
53+
}
54+
55+
export function withVectorDBCall<
56+
F extends ({ span }: { span: VectorSpan }) => ReturnType<F>,
57+
>({ vendor, type }: VectorDBCallConfig, fn: F, thisArg?: ThisParameterType<F>) {
58+
const entityContext = context.active();
59+
60+
getTracer().startActiveSpan(
61+
`${vendor}.${type}`,
62+
{},
63+
entityContext,
64+
async (span: Span) => {
65+
const res = fn.apply(thisArg, [{ span: new VectorSpan(span) }]);
66+
if (res instanceof Promise) {
67+
return res.then(() => {
68+
span.end();
69+
});
70+
}
71+
72+
span.end();
73+
},
74+
);
75+
}

0 commit comments

Comments
 (0)