From 2332db55f026ccad6437d8cbeb882be614a6ab22 Mon Sep 17 00:00:00 2001 From: Akash Guha Thakurata <39858727+akashgt@users.noreply.github.com> Date: Mon, 15 Jun 2026 00:36:52 +0530 Subject: [PATCH 1/2] Update prompt to prevent LLM-generated sources section Updated rules for response formatting by removing sources section and modifying return instructions. --- src/completions/prompts.py | 13 +++---------- 1 file changed, 3 insertions(+), 10 deletions(-) diff --git a/src/completions/prompts.py b/src/completions/prompts.py index 8e24760..8a7c056 100644 --- a/src/completions/prompts.py +++ b/src/completions/prompts.py @@ -4,7 +4,9 @@ 1. Answer using ONLY the information in the provided sources below. Do not use any other knowledge. 2. If the sources do not contain enough information to answer, say so directly. Do not guess or make up answers. 3. Be concise and direct. Students want clear answers, not long essays. -4. At the end of your answer, list the source URLs you used under a "Sources:" header. +4. Do not include a "Sources:" section. +5. Do not list source URLs in your answer. +6. Return only the answer text. Sources are handled separately by the application. Sources will be provided in this format: --- @@ -15,12 +17,3 @@ content of chunk 2 --- """ - - -def build_messages(question: str, context: str) -> list[dict[str, str]]: - """Build the message list for the LLM chat call.""" - user_content = f"{context}\n\nQuestion: {question}" - return [ - {"role": "system", "content": SYSTEM_PROMPT}, - {"role": "user", "content": user_content}, - ] From 7f36abb4059fe48c9b59777f9c8b442898c8972a Mon Sep 17 00:00:00 2001 From: Akash Guha Thakurata <39858727+akashgt@users.noreply.github.com> Date: Mon, 15 Jun 2026 01:01:46 +0530 Subject: [PATCH 2/2] Implement strip_trailing_sources_block function Added a function to strip trailing sources from response text. --- src/completions/services/completion_service.py | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/src/completions/services/completion_service.py b/src/completions/services/completion_service.py index c269f38..ca31fcb 100644 --- a/src/completions/services/completion_service.py +++ b/src/completions/services/completion_service.py @@ -1,3 +1,5 @@ +import re + from src.completions.prompts import build_messages from src.config.logger import get_logger from src.domain.types import Answer, RetrievedChunk, Source @@ -23,6 +25,16 @@ def _extract_sources(chunks: list[RetrievedChunk]) -> list[Source]: return list(seen.values()) +def strip_trailing_sources_block(text: str) -> str: + matches = list(re.finditer(r"(?m)^Sources:\s*$", text)) + + if not matches: + return text + + last_match = matches[-1] + return text[: last_match.start()].rstrip() + + async def ask(question: str) -> Answer: """Answer a question using retrieved chunks. Returns abstain Answer if nothing matched.""" log.info("ask_started", question_len=len(question)) @@ -42,6 +54,7 @@ async def ask(question: str) -> Answer: try: response_text = await llm.chat(messages) + response_text = strip_trailing_sources_block(response_text) except Exception as e: log.error("llm_call_failed", error=str(e)) raise