jaczad Claude Haiku 4.5 commited on
Commit
c657f22
·
1 Parent(s): 5c9813c

Optimize performance: lazy file handle, configurable LLM params, lancedb 0.30.2

Browse files

- agent/a11y_agent.py: open qa_dataset.jsonl once in __init__ (buffering=1)
instead of open/close on every request; move json/datetime imports to
module level; add llm_temperature/max_tokens/top_p from settings;
pre-cache system prompts for both languages in __init__
- config.py: add llm_temperature, llm_max_tokens, llm_top_p fields
- database/vector_store_client.py: upgrade to lancedb 0.30.2 API —
list_tables().tables instead of table_names(); to_list() instead of
to_df().to_dict(); count_rows() instead of len(); remove unused asyncio
- requirements.txt: pin lancedb==0.30.2

Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>

agent/a11y_agent.py CHANGED
@@ -1,5 +1,7 @@
1
  """A11y Expert - Main accessibility question-answering agent."""
2
 
 
 
3
  from typing import Optional, Generator
4
  from openai import OpenAI
5
  from langdetect import detect, LangDetectException
@@ -37,7 +39,14 @@ class A11yExpertAgent:
37
 
38
  settings = get_settings()
39
  self.model = settings.llm_model
40
- self.system_prompt = get_system_prompt(language, expertise)
 
 
 
 
 
 
 
41
 
42
  logger.info(f"A11yExpertAgent initialized (lang={language}, expertise={expertise}, stateless=True)")
43
 
@@ -48,6 +57,8 @@ class A11yExpertAgent:
48
  self.vector_store.close()
49
  if hasattr(self.llm_client, 'close'):
50
  self.llm_client.close()
 
 
51
  logger.info("A11yExpertAgent resources closed")
52
  except Exception as e:
53
  logger.warning(f"Error closing A11yExpertAgent: {e}")
@@ -72,9 +83,8 @@ class A11yExpertAgent:
72
 
73
  logger.info(f"Detected language: {language}")
74
 
75
- # Dynamically update system prompt based on detected language
76
- current_system_prompt = get_system_prompt(language, self.expertise)
77
-
78
  logger.info("Searching knowledge base...")
79
  context, sources = search_knowledge_base(question, self.vector_store, language=language)
80
 
@@ -89,9 +99,9 @@ class A11yExpertAgent:
89
  response_stream = self.llm_client.chat.completions.create(
90
  model=self.model,
91
  messages=messages,
92
- temperature=0.3,
93
- max_tokens=1500,
94
- top_p=0.9,
95
  stream=True
96
  )
97
 
@@ -185,9 +195,6 @@ Remember to:
185
  language: Language of the conversation
186
  """
187
  try:
188
- import json
189
- from datetime import datetime
190
-
191
  qa_entry = {
192
  "timestamp": datetime.now().isoformat(),
193
  "question": question,
@@ -203,9 +210,7 @@ Remember to:
203
  "model": self.model
204
  }
205
 
206
- # Append to JSONL file (one JSON per line)
207
- with open("qa_dataset.jsonl", "a", encoding="utf-8") as f:
208
- f.write(json.dumps(qa_entry, ensure_ascii=False) + "\n")
209
 
210
  logger.debug(f"Logged Q&A pair to qa_dataset.jsonl")
211
 
 
1
  """A11y Expert - Main accessibility question-answering agent."""
2
 
3
+ import json
4
+ from datetime import datetime
5
  from typing import Optional, Generator
6
  from openai import OpenAI
7
  from langdetect import detect, LangDetectException
 
39
 
40
  settings = get_settings()
41
  self.model = settings.llm_model
42
+ self.temperature = settings.llm_temperature
43
+ self.max_tokens = settings.llm_max_tokens
44
+ self.top_p = settings.llm_top_p
45
+ self._prompts = {
46
+ "pl": get_system_prompt("pl", expertise),
47
+ "en": get_system_prompt("en", expertise),
48
+ }
49
+ self._log_file = open("qa_dataset.jsonl", "a", encoding="utf-8", buffering=1)
50
 
51
  logger.info(f"A11yExpertAgent initialized (lang={language}, expertise={expertise}, stateless=True)")
52
 
 
57
  self.vector_store.close()
58
  if hasattr(self.llm_client, 'close'):
59
  self.llm_client.close()
60
+ if self._log_file and not self._log_file.closed:
61
+ self._log_file.close()
62
  logger.info("A11yExpertAgent resources closed")
63
  except Exception as e:
64
  logger.warning(f"Error closing A11yExpertAgent: {e}")
 
83
 
84
  logger.info(f"Detected language: {language}")
85
 
86
+ current_system_prompt = self._prompts.get(language, self._prompts["en"])
87
+
 
88
  logger.info("Searching knowledge base...")
89
  context, sources = search_knowledge_base(question, self.vector_store, language=language)
90
 
 
99
  response_stream = self.llm_client.chat.completions.create(
100
  model=self.model,
101
  messages=messages,
102
+ temperature=self.temperature,
103
+ max_tokens=self.max_tokens,
104
+ top_p=self.top_p,
105
  stream=True
106
  )
107
 
 
195
  language: Language of the conversation
196
  """
197
  try:
 
 
 
198
  qa_entry = {
199
  "timestamp": datetime.now().isoformat(),
200
  "question": question,
 
210
  "model": self.model
211
  }
212
 
213
+ self._log_file.write(json.dumps(qa_entry, ensure_ascii=False) + "\n")
 
 
214
 
215
  logger.debug(f"Logged Q&A pair to qa_dataset.jsonl")
216
 
config.py CHANGED
@@ -54,6 +54,24 @@ class Settings(BaseSettings):
54
  default=None,
55
  description="Base URL for OpenAI-compatible API (optional)"
56
  )
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
57
 
58
  # Embeddings Configuration
59
  embedding_model: str = Field(
 
54
  default=None,
55
  description="Base URL for OpenAI-compatible API (optional)"
56
  )
57
+ llm_temperature: float = Field(
58
+ default=0.3,
59
+ ge=0.0,
60
+ le=2.0,
61
+ description="Sampling temperature for chat completions"
62
+ )
63
+ llm_max_tokens: int = Field(
64
+ default=1500,
65
+ ge=1,
66
+ le=16000,
67
+ description="Maximum tokens in chat completion response"
68
+ )
69
+ llm_top_p: float = Field(
70
+ default=0.9,
71
+ ge=0.0,
72
+ le=1.0,
73
+ description="Top-p nucleus sampling for chat completions"
74
+ )
75
 
76
  # Embeddings Configuration
77
  embedding_model: str = Field(
database/vector_store_client.py CHANGED
@@ -6,7 +6,6 @@ connection management and lazy table initialization.
6
  """
7
 
8
  import lancedb
9
- import asyncio
10
  from typing import List, Dict, Any, Optional
11
  from datetime import datetime
12
  from loguru import logger
@@ -89,7 +88,7 @@ class VectorStoreClient:
89
  LanceDB table or None if table doesn't exist yet
90
  """
91
  if self._table is None:
92
- if self.table_name in self.db.table_names():
93
  logger.debug(f"Opening existing table: '{self.table_name}'")
94
  self._table = self.db.open_table(self.table_name)
95
  else:
@@ -170,7 +169,7 @@ class VectorStoreClient:
170
  logger.info(f"Adding {len(valid_docs)} documents to '{self.table_name}'")
171
 
172
  # Create table on first insert or open existing
173
- if self.table_name not in self.db.table_names():
174
  self._table = self.db.create_table(self.table_name, data=valid_docs)
175
  logger.info(f"✅ Created table '{self.table_name}' with {len(valid_docs)} docs")
176
  else:
@@ -220,9 +219,9 @@ class VectorStoreClient:
220
  if where:
221
  query = query.where(where)
222
 
223
- results = query.limit(top_k).to_df()
224
  logger.debug(f"Found {len(results)} documents")
225
- return results.to_dict("records")
226
  except Exception as e:
227
  logger.error(f"Search failed: {e}")
228
  return []
@@ -236,14 +235,14 @@ class VectorStoreClient:
236
  """
237
  if self.table is None:
238
  return 0
239
- return len(self.table)
240
 
241
  def get_statistics(self) -> Dict[str, Any]:
242
  """Get database statistics."""
243
  if self._db is None:
244
  self.connect()
245
 
246
- if self.table_name not in self._db.table_names():
247
  logger.warning(f"Table '{self.table_name}' does not exist yet")
248
  return {
249
  "total_documents": 0,
@@ -350,9 +349,9 @@ class VectorStoreClient:
350
  if where_clause:
351
  query = query.where(where_clause)
352
 
353
- results = query.limit(top_k).to_df()
354
  logger.debug(f"Found {len(results)} documents with filters")
355
- return results.to_dict("records")
356
  except Exception as e:
357
  logger.error(f"Search with filters failed: {e}")
358
  return []
 
6
  """
7
 
8
  import lancedb
 
9
  from typing import List, Dict, Any, Optional
10
  from datetime import datetime
11
  from loguru import logger
 
88
  LanceDB table or None if table doesn't exist yet
89
  """
90
  if self._table is None:
91
+ if self.table_name in self.db.list_tables().tables:
92
  logger.debug(f"Opening existing table: '{self.table_name}'")
93
  self._table = self.db.open_table(self.table_name)
94
  else:
 
169
  logger.info(f"Adding {len(valid_docs)} documents to '{self.table_name}'")
170
 
171
  # Create table on first insert or open existing
172
+ if self.table_name not in self.db.list_tables().tables:
173
  self._table = self.db.create_table(self.table_name, data=valid_docs)
174
  logger.info(f"✅ Created table '{self.table_name}' with {len(valid_docs)} docs")
175
  else:
 
219
  if where:
220
  query = query.where(where)
221
 
222
+ results = query.limit(top_k).to_list()
223
  logger.debug(f"Found {len(results)} documents")
224
+ return results
225
  except Exception as e:
226
  logger.error(f"Search failed: {e}")
227
  return []
 
235
  """
236
  if self.table is None:
237
  return 0
238
+ return self.table.count_rows()
239
 
240
  def get_statistics(self) -> Dict[str, Any]:
241
  """Get database statistics."""
242
  if self._db is None:
243
  self.connect()
244
 
245
+ if self.table_name not in self._db.list_tables().tables:
246
  logger.warning(f"Table '{self.table_name}' does not exist yet")
247
  return {
248
  "total_documents": 0,
 
349
  if where_clause:
350
  query = query.where(where_clause)
351
 
352
+ results = query.limit(top_k).to_list()
353
  logger.debug(f"Found {len(results)} documents with filters")
354
+ return results
355
  except Exception as e:
356
  logger.error(f"Search with filters failed: {e}")
357
  return []
requirements.txt CHANGED
@@ -1,7 +1,7 @@
1
  gradio==6.1.0
2
  huggingface-hub>=0.26.0
3
  openai
4
- lancedb
5
  loguru
6
  langdetect
7
  diskcache
 
1
  gradio==6.1.0
2
  huggingface-hub>=0.26.0
3
  openai
4
+ lancedb==0.30.2
5
  loguru
6
  langdetect
7
  diskcache