Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We鈥檒l occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(prompts): add table to compare metrics across prompt versions, [promptName]/metrics #1991

Merged
merged 29 commits into from
May 14, 2024
Merged
Show file tree
Hide file tree
Changes from 9 commits
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
cf122ab
feat: add tabs on prompt page to switch editor vs table view
marliessophie May 6, 2024
ea8bf87
feat: add `metrics` prompt procedure
marliessophie May 7, 2024
8b49963
feat: add `verison-table` page incl. all but score data
marliessophie May 7, 2024
fd1025c
feat: add linked cell for prompt version
marliessophie May 7, 2024
8be092a
refactor: adjust label cell styling
marliessophie May 7, 2024
b220b43
feat: add average observation score to table
marliessophie May 8, 2024
a0c585d
feat: add average trace score to table
marliessophie May 8, 2024
bc7ab4f
docs: add comment to observation schema
marliessophie May 8, 2024
c6ad847
Merge branch 'main' into marlies/lfe-975
marliessophie May 8, 2024
5efa0d9
fix: metrics query
marliessophie May 8, 2024
5cc3afe
Merge branch 'main' into marlies/lfe-975
maxdeichmann May 9, 2024
0968ee4
fix: observation scores query and display on UI
marliessophie May 10, 2024
13cf680
fix: only check `generations` type
marliessophie May 10, 2024
7a86e73
feat: add traces query
marliessophie May 10, 2024
e98a0ae
fix: using wrong variable bc of typo
marliessophie May 10, 2024
a704079
fix: format latency with 3 decimals
marliessophie May 10, 2024
b5b9b7b
query update
marcklingen May 10, 2024
6783f46
feat: add toggle columns to show/hide cols
marliessophie May 10, 2024
4677394
fix: add gap between labels
marliessophie May 10, 2024
e8a3531
feat: add pagination for `prompts.metrics`
marliessophie May 10, 2024
7fbc25d
feat: add optional pagination for `prompts.allVersions`
marliessophie May 10, 2024
b6801c3
feat: set default version table pagination to 50
marliessophie May 10, 2024
991b9f6
fix: pagination
marliessophie May 10, 2024
3ddadb0
skip batch
marliessophie May 10, 2024
762197a
feat: add cell loading skeleton
marliessophie May 10, 2024
821ef3d
Merge branch 'main' into marlies/lfe-975
marliessophie May 10, 2024
a299611
rename table
marcklingen May 14, 2024
7918d20
Merge branch 'main' into marlies/lfe-975
marcklingen May 14, 2024
773a59d
rename to metrics
marcklingen May 14, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
2 changes: 2 additions & 0 deletions packages/shared/prisma/schema.prisma
Original file line number Diff line number Diff line change
Expand Up @@ -276,6 +276,8 @@ view TraceView {
}

// Update ObservationView below when making changes to this model!
// traceId is optional only due to timing during data injestion
// (traceId is not necessarily known at the time of observation creation)
model Observation {
id String @id @default(cuid())
traceId String? @map("trace_id")
Expand Down
13 changes: 13 additions & 0 deletions web/src/features/prompts/components/prompt-detail.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import {
ChatMlArraySchema,
OpenAiMessageView,
} from "@/src/components/trace/IOPreview";
import { Tabs, TabsList, TabsTrigger } from "@/src/components/ui/tabs";
import { Badge } from "@/src/components/ui/badge";
import { Button } from "@/src/components/ui/button";
import { CodeView, JSONView } from "@/src/components/ui/CodeJsonViewer";
Expand Down Expand Up @@ -151,6 +152,18 @@ export const PromptDetail = () => {
path={(name) => `/project/${projectId}/prompts/${name}`}
listKey="prompts"
/>
<Tabs value="editor">
<TabsList>
<TabsTrigger value="editor">Editor</TabsTrigger>
<TabsTrigger value="table" asChild>
<Link
href={`/project/${projectId}/prompts/${encodeURIComponent(promptName)}/version-table`}
>
Table
</Link>
</TabsTrigger>
</TabsList>
</Tabs>
</>
}
/>
Expand Down
100 changes: 100 additions & 0 deletions web/src/features/prompts/server/routers/promptRouter.ts
marliessophie marked this conversation as resolved.
Show resolved Hide resolved
Original file line number Diff line number Diff line change
Expand Up @@ -507,6 +507,106 @@ export const promptRouter = createTRPCRouter({
});
return joinedPromptAndUsers;
}),
metrics: protectedProjectProcedure
.input(z.object({ projectId: z.string(), promptIds: z.array(z.string()) }))
.query(async ({ input, ctx }) => {
throwIfNoAccess({
session: ctx.session,
projectId: input.projectId,
scope: "prompts:read",
});

const metrics = await ctx.prisma.$queryRaw<
Array<{
id: string;
observationCount: number;
firstUsed: Date | null;
lastUsed: Date | null;
averageObservationScore: number | null;
medianOutputTokens: number | null;
medianInputTokens: number | null;
medianTotalCost: number | null;
medianLatency: number | null;
}>
>(
Prisma.sql`
SELECT
prompt_id AS "id",
count(*) AS "observationCount",
MIN(start_time) AS "firstUsed",
MAX(start_time) AS "lastUsed",
AVG(value) AS "averageObservationScore",
PERCENTILE_CONT(0.5) WITHIN GROUP(ORDER BY completion_tokens) AS "medianOutputTokens",
PERCENTILE_CONT(0.5) WITHIN GROUP(ORDER BY prompt_tokens) AS "medianInputTokens",
PERCENTILE_CONT(0.5) WITHIN GROUP(ORDER BY calculated_total_cost) AS "medianTotalCost",
PERCENTILE_CONT(0.5) WITHIN GROUP(ORDER BY latency) AS "medianLatency"
FROM
(
SELECT s.id AS "scoreId", s.value, os.* from scores s
LEFT JOIN LATERAL (
SELECT
*
FROM
"observations_view" ov
WHERE
s.observation_id IS NOT NULL
AND ov.id = s.observation_id
AND "type" = 'GENERATION'
AND "project_id" = ${input.projectId}
) AS os ON true
RIGHT JOIN prompts p ON p.id = os.prompt_id
WHERE prompt_id IS NOT NULL
AND p.id in (${Prisma.join(input.promptIds)})
AND os.project_id = ${input.projectId}
) GROUP BY "prompt_id"
`,
);

const averageTraceObservationScore = await ctx.prisma.$queryRaw<
Array<{
id: string;
averageTraceObservationScore: number;
}>
>(
Prisma.sql`
SELECT
os.prompt_id AS "id",
AVG(value) AS "averageTraceObservationScore"
FROM
(
SELECT
s.id,
s.value,
ov.trace_id,
ov.prompt_id,
ROW_NUMBER() OVER (PARTITION BY ov.prompt_id, ov.trace_id ORDER BY s.id) AS row_num
FROM
scores s
LEFT JOIN "observations_view" ov ON ov.trace_id = s.trace_id
WHERE
s.observation_id IS NULL
AND ov."type" = 'GENERATION'
AND ov."project_id" = ${input.projectId}
) AS os
WHERE
os.row_num = 1
AND os.prompt_id IN (${Prisma.join(input.promptIds)})
GROUP BY os.prompt_id`,
);
marliessophie marked this conversation as resolved.
Show resolved Hide resolved

const averageTraceScoreMap = averageTraceObservationScore.reduce(
(acc, { id, averageTraceObservationScore }) => {
acc[id] = averageTraceObservationScore;
return acc;
},
{} as Record<string, number>,
);

return metrics.map((metric) => ({
...metric,
averageTraceScore: averageTraceScoreMap[metric.id] ?? null,
}));
}),
});

const generatePromptQuery = (
Expand Down