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’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(ai-help): log message metadata #424

Merged
merged 27 commits into from
Mar 26, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
b5be667
feat(ai-help): log message metadata
fiji-flo Feb 20, 2024
631ca37
fixes
fiji-flo Feb 21, 2024
eb3ca5b
remove dead code
fiji-flo Feb 21, 2024
fae4dec
Merge branch 'main' into MP-813-message-metadata
caugner Feb 23, 2024
c258a44
add model
fiji-flo Feb 23, 2024
aadc3f2
Merge remote-tracking branch 'upstream/main' into MP-813-message-meta…
fiji-flo Feb 27, 2024
7013e45
fix(ai-help): record {query,context}_len
caugner Feb 27, 2024
4572cd4
chore(ai-help): rename message status
caugner Feb 29, 2024
44eefc6
fix(ai-help): record context_len in bytes
caugner Feb 29, 2024
69243f9
chore(ai-help): document meta message fields
caugner Feb 29, 2024
85d5215
Merge branch 'main' into MP-813-message-metadata
caugner Mar 1, 2024
88ba56e
fix(ai-help): record metadata for AI response without finish_reason
caugner Mar 1, 2024
a4fc0ff
refactor(ai-help): merge Err() matchers
caugner Mar 1, 2024
e5f816c
revert(ai-help): extract perf fix
caugner Mar 4, 2024
6af96c5
Merge remote-tracking branch 'upstream/main' into MP-813-message-meta…
fiji-flo Mar 25, 2024
dd64849
add finish reason
fiji-flo Mar 25, 2024
711d351
Merge remote-tracking branch 'upstream/MP-813-message-metadata' into …
fiji-flo Mar 25, 2024
80dcad8
fixes
fiji-flo Mar 25, 2024
79e5734
less indent
fiji-flo Mar 25, 2024
ba22ffa
fmt
fiji-flo Mar 25, 2024
6c79961
make data nullable
fiji-flo Mar 26, 2024
c8a97e8
fix(ai-help): reuse search_duration/query_len/context_len for error
caugner Mar 26, 2024
ad0cf5a
fix test
fiji-flo Mar 26, 2024
4090413
chore(ai-help): record response duration on error
caugner Mar 26, 2024
039fece
chore(ai-help): record model/sources on error
caugner Mar 26, 2024
e851bac
Revert "chore(ai-help): record response duration on error"
caugner Mar 26, 2024
92d4e1f
Merge branch 'main' into MP-813-message-metadata
caugner Mar 26, 2024
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
28 changes: 16 additions & 12 deletions ai-test/src/ai_help.rs
Original file line number Diff line number Diff line change
Expand Up @@ -96,18 +96,22 @@ pub async fn ai_help_all(
function_call: None,
})
.collect();
if let Some(req) =
prepare_ai_help_req(openai_client, supabase_pool, !no_subscription, messages)
.await?
{
let mut res = openai_client.chat().create(req.req.clone()).await?;
let res = res.choices.pop().map(|res| res.message);
let storage = Storage { req, res };
println!("writing: {}", json_out.display());
fs::write(json_out, serde_json::to_vec_pretty(&storage)?).await?;
println!("writing: {}", md_out.display());
fs::write(md_out, storage.to_md().as_bytes()).await?;
}
let mut meta = Default::default();
let req = prepare_ai_help_req(
openai_client,
supabase_pool,
!no_subscription,
messages,
&mut meta,
)
.await?;
let mut res = openai_client.chat().create(req.req.clone()).await?;
let res = res.choices.pop().map(|res| res.message);
let storage = Storage { req, res };
println!("writing: {}", json_out.display());
fs::write(json_out, serde_json::to_vec_pretty(&storage)?).await?;
println!("writing: {}", md_out.display());
fs::write(md_out, storage.to_md().as_bytes()).await?;
Ok(())
})
.await?;
Expand Down
2 changes: 2 additions & 0 deletions migrations/2024-02-20-093804_ai_help_metadata/down.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
DROP TABLE ai_help_message_meta;
DROP TYPE ai_help_message_status;
34 changes: 34 additions & 0 deletions migrations/2024-02-20-093804_ai_help_metadata/up.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
CREATE TYPE ai_help_message_status AS ENUM (
'success',
'search_error',
'ai_api_error',
'completion_error',
'moderation_error',
'no_user_prompt_error',
'token_limit_error',
'timeout',
'finished_too_long',
'finished_content_filter',
'finished_no_reason',
'user_stopped',
'user_timeout',
'unknown'
);

CREATE TABLE ai_help_message_meta (
id BIGSERIAL PRIMARY KEY,
user_id BIGSERIAL REFERENCES users (id) ON DELETE CASCADE,
chat_id UUID NOT NULL,
message_id UUID NOT NULL,
parent_id UUID DEFAULT NULL,
created_at TIMESTAMP NOT NULL DEFAULT now(),
search_duration BIGINT DEFAULT NULL,
response_duration BIGINT DEFAULT NULL,
query_len BIGINT DEFAULT NULL,
context_len BIGINT DEFAULT NULL,
response_len BIGINT DEFAULT NULL,
model text NOT NULL,
status ai_help_message_status NOT NULL DEFAULT 'unknown',
sources JSONB NOT NULL DEFAULT '[]'::jsonb,
UNIQUE(message_id)
);
35 changes: 28 additions & 7 deletions src/ai/help.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
use std::time::{Duration, Instant};

use async_openai::{
config::OpenAIConfig,
types::{
Expand Down Expand Up @@ -33,12 +35,22 @@ pub struct AIHelpRequest {
pub refs: Vec<RefDoc>,
}

#[derive(Default)]
pub struct AIHelpRequestMeta {
pub query_len: Option<usize>,
pub context_len: Option<usize>,
pub search_duration: Option<Duration>,
pub model: Option<&'static str>,
pub sources: Option<Vec<RefDoc>>,
}

pub async fn prepare_ai_help_req(
client: &Client<OpenAIConfig>,
pool: &SupaPool,
is_subscriber: bool,
messages: Vec<ChatCompletionRequestMessage>,
) -> Result<Option<AIHelpRequest>, AIError> {
request_meta: &mut AIHelpRequestMeta,
) -> Result<AIHelpRequest, AIError> {
let config = if is_subscriber {
AI_HELP_GPT4_FULL_DOC_NEW_PROMPT
} else {
Expand Down Expand Up @@ -81,24 +93,29 @@ pub async fn prepare_ai_help_req(
.last()
.and_then(|msg| msg.content.as_ref())
.ok_or(AIError::NoUserPrompt)?;
request_meta.query_len = Some(last_user_message.len());

let start = Instant::now();
let related_docs = if config.full_doc {
get_related_macro_docs(client, pool, last_user_message.replace('\n', " ")).await?
} else {
get_related_docs(client, pool, last_user_message.replace('\n', " ")).await?
};
request_meta.search_duration = Some(start.elapsed());

let mut context = vec![];
let mut refs = vec![];
let mut token_len = 0;
let mut context_len = 0;
let mut context_token_len = 0;
for doc in related_docs.into_iter() {
debug!("url: {}", doc.url);
context_len += doc.content.len();
let bpe = tiktoken_rs::r50k_base().unwrap();
let tokens = bpe.encode_with_special_tokens(&doc.content).len();
token_len += tokens;
debug!("tokens: {}, token_len: {}", tokens, token_len);
if token_len >= config.context_limit {
token_len -= tokens;
context_token_len += tokens;
debug!("tokens: {}, token_len: {}", tokens, context_token_len);
if context_token_len >= config.context_limit {
context_token_len -= tokens;
continue;
}
if !refs.iter().any(|r: &RefDoc| r.url == doc.url) {
Expand All @@ -109,6 +126,9 @@ pub async fn prepare_ai_help_req(
}
context.push(doc);
}
request_meta.sources = Some(refs.clone());
request_meta.context_len = Some(context_len);

let system_message = ChatCompletionRequestMessageArgs::default()
.role(Role::System)
.content(config.system_prompt)
Expand Down Expand Up @@ -143,8 +163,9 @@ pub async fn prepare_ai_help_req(
.messages(messages)
.temperature(0.0)
.build()?;
request_meta.model = Some(config.model);

Ok(Some(AIHelpRequest { req, refs }))
Ok(AIHelpRequest { req, refs })
}

pub fn prepare_ai_help_summary_req(
Expand Down
Loading
Loading