2121 AnswerGenerationChain ,
2222)
2323from rag_core_api .impl .answer_generation_chains .rephrasing_chain import RephrasingChain
24- from rag_core_api .impl .answer_generation_chains .evaluation_chain import EvaluationChain
2524from rag_core_api .impl .graph .graph_state .graph_state import AnswerGraphState
2625from rag_core_api .impl .retriever .no_or_empty_collection_error import (
2726 NoOrEmptyCollectionError ,
@@ -59,7 +58,6 @@ class GraphNodeNames(StrEnum):
5958 REPHRASE = "rephrase"
6059 RETRIEVE = "retrieve"
6160 GENERATE = "generate"
62- EVALUATE = "evaluate"
6361 ERROR_NODE = "error_node"
6462
6563
@@ -75,7 +73,6 @@ def __init__(
7573 answer_generation_chain : AnswerGenerationChain ,
7674 rephrasing_chain : RephrasingChain ,
7775 composed_retriever : Retriever ,
78- evaluation_chain : EvaluationChain ,
7976 mapper : InformationPieceMapper ,
8077 error_messages : ErrorMessages ,
8178 chat_history_settings : ChatHistorySettings ,
@@ -104,7 +101,6 @@ def __init__(
104101 self ._mapper = mapper
105102 self ._chat_history_settings = chat_history_settings
106103 self ._rephrasing_chain = rephrasing_chain
107- self ._evaluation_chain = evaluation_chain
108104 self ._error_messages = error_messages
109105 self ._rephrase_node_builder = partial (self ._rephrase_node )
110106 self ._generate_node_builder = partial (self ._generate_node )
@@ -264,55 +260,6 @@ async def _generate_node(self, state: dict, config: Optional[RunnableConfig] = N
264260 )
265261 return {"answer_text" : answer_text , "response" : chat_response }
266262
267- async def _evaluate_node (self , state : dict , config : Optional [RunnableConfig ] = None ) -> dict :
268- """LLM-based helpfulness check. Decides whether to accept the answer or re-retrieve from LBO.
269-
270- Input to the evaluator includes: question, answer, rephrased_question and a short context summary.
271- """
272- evaluator_input = {
273- "question" : state .get ("question" , "" ),
274- "rephrased_question" : state .get ("rephrased_question" , "" ),
275- "answer" : state .get ("answer_text" , "" ),
276- # Keep the evaluator prompt lean: feed the first 3 snippet heads
277- "context" : "\n \n " .join ([doc .page_content [:500 ] for doc in state .get ("langchain_documents" , [])][:3 ]),
278- "instruction" : (
279- "Bewerte, ob die Antwort hilfreich ist, um die Nutzerfrage zu beantworten. "
280- "Antworte ausschließlich mit 'yes' oder 'no'."
281- ),
282- }
283- helpful = await self ._evaluation_chain .ainvoke (evaluator_input , config = config )
284-
285- update : dict [str , Any ] = {"additional_info" : {"helpful" : bool (helpful )}}
286- # If the answer is not helpful, create a concise, proper fallback answer for B-Plan questions
287- if not helpful :
288- language = state .get ("language" , "de" )
289- question = state .get ("question" , "" )
290- # Small, safe fallback tailored to Bebauungspläne/Festsetzungen
291- if language .startswith ("de" ):
292- fallback = (
293- "Ich konnte aus dem bereitgestellten Kontext keine verlässliche Antwort ableiten. "
294- "Für Fragen zu Bebauungsplänen (B-Plan) und deren Festsetzungen gilt: Innerhalb des Plangebiets "
295- "haben die textlichen und zeichnerischen Festsetzungen des B-Plans Vorrang; die Landesbauordnung (LBO) "
296- "gilt subsidiär, soweit der B‑Plan nichts Abweichendes bestimmt. Bitte geben Sie – wenn möglich – eine konkrete "
297- "Bezeichnung des Bebauungsplans (z. B. Plan‑Name/Nummer) oder Adresse/Flurstück an. Typische Festsetzungen sind u. a.: "
298- "Bauweise/GRZ/GFZ, Baugrenzen/Baulinien, Dachform/Dachneigung, Nutzung und textliche Festsetzungen."
299- )
300- else :
301- fallback = (
302- "I couldn't derive a reliable answer from the provided context. For German local development plans (Bebauungsplan), "
303- "the plan’s textual and graphical stipulations have priority within the plan area; the state building code (LBO) applies "
304- "only where the plan is silent. Please provide the exact plan name/ID or an address/parcel if possible. Typical stipulations "
305- "include e.g. building type, site coverage (GRZ), floor area ratio (GFZ), building lines, roof form/slope, usage, and textual rules."
306- )
307- chat_response = ChatResponse (
308- answer = fallback ,
309- citations = state .get ("information_pieces" , []) or [],
310- finish_reason = "unhelpful_answer_fallback" ,
311- )
312- update ["answer_text" ] = fallback
313- update ["response" ] = chat_response
314- return update
315-
316263 async def _retrieve_node (self , state : dict , config : Optional [RunnableConfig ] = None ) -> dict :
317264 try :
318265 # Retrieve across all documents; if client provided filters, map to file_name stem list
@@ -400,7 +347,6 @@ def is_lbo(doc: Any) -> bool:
400347 response ["langchain_documents" ] = retrieved_documents
401348 response ["bplan_documents" ] = bplan_docs
402349 response ["lbo_documents" ] = lbo_docs
403- response ["skip_evaluate" ] = False
404350
405351 return response
406352
@@ -422,7 +368,6 @@ def _add_nodes(self):
422368 self ._state_graph .add_node (GraphNodeNames .REPHRASE , self ._rephrase_node_builder )
423369 self ._state_graph .add_node (GraphNodeNames .RETRIEVE , self ._retrieve_node )
424370 self ._state_graph .add_node (GraphNodeNames .GENERATE , self ._generate_node_builder )
425- self ._state_graph .add_node (GraphNodeNames .EVALUATE , self ._evaluate_node )
426371 self ._state_graph .add_node (GraphNodeNames .ERROR_NODE , self ._error_node )
427372
428373 def _wire_graph (self ):
@@ -436,17 +381,7 @@ def _wire_graph(self):
436381 self ._docs_retrieved_edge ,
437382 [GraphNodeNames .GENERATE , GraphNodeNames .ERROR_NODE ],
438383 )
439- # After generation, always evaluate; on unhelpful answer we generate a proper fallback and end
440- def evaluate_edge (state : dict ) -> str :
441- return END
442-
443- # If we marked to skip evaluation (not used anymore), end after GENERATE; otherwise go to EVALUATE
444- def after_generate_edge (state : dict ) -> str :
445- return END if state .get ("skip_evaluate" ) else GraphNodeNames .EVALUATE
446-
447- self ._state_graph .add_conditional_edges (
448- GraphNodeNames .GENERATE , after_generate_edge , [END , GraphNodeNames .EVALUATE ]
449- )
450- self ._state_graph .add_conditional_edges (GraphNodeNames .EVALUATE , evaluate_edge , [END ])
384+ # After generation, end the graph
385+ self ._state_graph .add_edge (GraphNodeNames .GENERATE , END )
451386 self ._state_graph .add_edge (GraphNodeNames .ERROR_NODE , END )
452387 # END wiring complete
0 commit comments