fix(analyze): drop transcript timestamp headings from LLM prompt
render_prompt prefixed each recording with a '## <recorded_at>' heading. No system prompt consumes that timestamp, and the LLM occasionally echoed it into the final document as a heading. Join recordings with the bare '\n\n---\n\n' separator instead; chronology is carried by recording order. Adds a regression test pinning that no RFC3339 timestamp or '##' reaches the prompt. closes #8
This commit is contained in:
@@ -4,6 +4,13 @@ use super::AnalysisInput;
|
||||
/// JSON input. Recordings with blank text are skipped — they carry no signal
|
||||
/// for the LLM and only add noise. Chronological order is taken as given;
|
||||
/// callers must sort `recordings` before passing in (the handler does).
|
||||
///
|
||||
/// Recordings are concatenated with a `\n\n---\n\n` separator and nothing
|
||||
/// else: no per-recording heading or timestamp. The `recorded_at` value is
|
||||
/// deliberately omitted — no system prompt consumes it, and feeding it as a
|
||||
/// Markdown heading caused the LLM to occasionally echo transcript timestamps
|
||||
/// into the final document (issue #8). Chronology is carried by the order of
|
||||
/// `recordings` alone.
|
||||
pub fn render_prompt(input: &AnalysisInput) -> String {
|
||||
let mut out = String::new();
|
||||
let mut first = true;
|
||||
@@ -15,9 +22,6 @@ pub fn render_prompt(input: &AnalysisInput) -> String {
|
||||
out.push_str("\n\n---\n\n");
|
||||
}
|
||||
first = false;
|
||||
out.push_str("## ");
|
||||
out.push_str(&r.recorded_at);
|
||||
out.push_str("\n\n");
|
||||
out.push_str(r.text.trim());
|
||||
}
|
||||
out
|
||||
@@ -48,7 +52,7 @@ mod tests {
|
||||
"2026-04-15T10:32:00Z",
|
||||
"Patient klagt über Knie.",
|
||||
)]));
|
||||
assert_eq!(out, "## 2026-04-15T10:32:00Z\n\nPatient klagt über Knie.");
|
||||
assert_eq!(out, "Patient klagt über Knie.");
|
||||
}
|
||||
|
||||
#[test]
|
||||
@@ -57,9 +61,20 @@ mod tests {
|
||||
("2026-04-15T10:32:00Z", "Erste Aufnahme."),
|
||||
("2026-04-15T10:38:15Z", "Zweite Aufnahme."),
|
||||
]));
|
||||
assert!(out.contains("\n\n---\n\n"));
|
||||
assert!(out.starts_with("## 2026-04-15T10:32:00Z"));
|
||||
assert!(out.contains("## 2026-04-15T10:38:15Z"));
|
||||
assert_eq!(out, "Erste Aufnahme.\n\n---\n\nZweite Aufnahme.");
|
||||
}
|
||||
|
||||
/// Regression guard for issue #8: transcript timestamps must never reach
|
||||
/// the LLM prompt — they leaked into the final document as headings.
|
||||
#[test]
|
||||
fn omits_recording_timestamps() {
|
||||
let out = render_prompt(&mk(vec![
|
||||
("2026-04-15T10:32:00Z", "Erste Aufnahme."),
|
||||
("2026-04-15T10:38:15Z", "Zweite Aufnahme."),
|
||||
]));
|
||||
assert!(!out.contains("2026-04-15T10:32:00Z"));
|
||||
assert!(!out.contains("2026-04-15T10:38:15Z"));
|
||||
assert!(!out.contains("##"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
||||
Reference in New Issue
Block a user