Spaces:
Running
Running
Commit ·
2789a91
1
Parent(s): 9257463
fix(llm): guard Groq fallback against 8000 TPM limit with prompt compaction and context trimming
Browse files- app/services/llm_service.py +29 -2
app/services/llm_service.py
CHANGED
|
@@ -662,9 +662,29 @@ If there is insufficient evidence:
|
|
| 662 |
app_logger.info(
|
| 663 |
f"[FALLBACK] Executing tree search via Groq ({self.groq_retrieval_model})"
|
| 664 |
)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 665 |
groq_resp = await self.groq_client.chat.completions.create(
|
| 666 |
model=self.groq_retrieval_model,
|
| 667 |
-
messages=[{"role": "user", "content":
|
| 668 |
temperature=0.1,
|
| 669 |
max_tokens=300,
|
| 670 |
)
|
|
@@ -1236,9 +1256,16 @@ Return only the final user-facing answer."""
|
|
| 1236 |
if (self.hf_exhausted or hf_stream_failed) and self.groq_client:
|
| 1237 |
try:
|
| 1238 |
app_logger.info(f"[FALLBACK] Generating answer stream via Groq ({self.groq_chat_model})")
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1239 |
groq_stream = await self.groq_client.chat.completions.create(
|
| 1240 |
model=self.groq_chat_model,
|
| 1241 |
-
messages=
|
| 1242 |
temperature=0.2,
|
| 1243 |
max_tokens=max_out_tokens,
|
| 1244 |
stream=True,
|
|
|
|
| 662 |
app_logger.info(
|
| 663 |
f"[FALLBACK] Executing tree search via Groq ({self.groq_retrieval_model})"
|
| 664 |
)
|
| 665 |
+
groq_prompt = prompt
|
| 666 |
+
# Groq on-demand models have an 8000 TPM limit. If prompt exceeds 18,000 chars,
|
| 667 |
+
# compact all_nodes_data (omitting full summaries) so it fits safely within ~3,500 tokens.
|
| 668 |
+
if len(prompt) > 18000:
|
| 669 |
+
compact_nodes = [
|
| 670 |
+
{"node_id": n.get("node_id"), "title": n.get("title", ""), "page": n.get("page_index")}
|
| 671 |
+
for n in all_nodes_data
|
| 672 |
+
]
|
| 673 |
+
groq_prompt = f"""You are a specialized Document Tree Search Engine.
|
| 674 |
+
Select between 1 and 4 most relevant nodes for the query.
|
| 675 |
+
|
| 676 |
+
AVAILABLE DOCUMENT SECTIONS:
|
| 677 |
+
{json.dumps(compact_nodes, separators=(',', ':'))}
|
| 678 |
+
|
| 679 |
+
USER QUERY:
|
| 680 |
+
{query}
|
| 681 |
+
|
| 682 |
+
Return ONLY valid JSON:
|
| 683 |
+
{{"node_list": ["node_id1", "node_id2"]}}
|
| 684 |
+
"""
|
| 685 |
groq_resp = await self.groq_client.chat.completions.create(
|
| 686 |
model=self.groq_retrieval_model,
|
| 687 |
+
messages=[{"role": "user", "content": groq_prompt}],
|
| 688 |
temperature=0.1,
|
| 689 |
max_tokens=300,
|
| 690 |
)
|
|
|
|
| 1256 |
if (self.hf_exhausted or hf_stream_failed) and self.groq_client:
|
| 1257 |
try:
|
| 1258 |
app_logger.info(f"[FALLBACK] Generating answer stream via Groq ({self.groq_chat_model})")
|
| 1259 |
+
groq_messages = []
|
| 1260 |
+
for m in messages:
|
| 1261 |
+
c = m.get("content", "")
|
| 1262 |
+
if len(c) > 18000:
|
| 1263 |
+
c = c[:18000] + "\n\n... [Evidence truncated to fit Groq 8000 TPM limit] ..."
|
| 1264 |
+
groq_messages.append({"role": m["role"], "content": c})
|
| 1265 |
+
|
| 1266 |
groq_stream = await self.groq_client.chat.completions.create(
|
| 1267 |
model=self.groq_chat_model,
|
| 1268 |
+
messages=groq_messages,
|
| 1269 |
temperature=0.2,
|
| 1270 |
max_tokens=max_out_tokens,
|
| 1271 |
stream=True,
|