| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
|
|
| from training_data import TRAINING_EXAMPLES |
| from .tools import cluster_sentences, label_clusters |
|
|
|
|
| def pattern_detection_node(state): |
| sentences = [e["sentence"] for e in TRAINING_EXAMPLES] |
| true_labels = [e["label"] for e in TRAINING_EXAMPLES] |
|
|
| cluster_result = cluster_sentences( |
| sentences=sentences, |
| similarity_threshold=state["similarity_threshold"], |
| min_cluster_size=state["min_cluster_size"], |
| n_nearest=state["n_nearest"], |
| ) |
|
|
| |
| |
| reps_for_llm = { |
| str(cid): [sentences[i] for i, _d in reps] |
| for cid, reps in cluster_result["representatives"].items() |
| } |
|
|
| cluster_labels = label_clusters( |
| cluster_representatives=reps_for_llm, |
| llm_provider=state["llm_provider"], |
| llm_key=state["llm_key"], |
| ) |
|
|
| |
| |
| sentence_rows = [ |
| { |
| "idx": idx, |
| "sentence": sentences[idx], |
| "true_label": true_labels[idx], |
| "cluster_id": str(cluster_result["cluster_ids"][idx]), |
| "cluster_label": cluster_labels.get( |
| str(cluster_result["cluster_ids"][idx]), "" |
| ), |
| "dist_to_centroid": cluster_result["distances_to_centroid"][idx], |
| } |
| for idx in range(len(sentences)) |
| ] |
|
|
| detection_result = { |
| "n_clusters_found": cluster_result["n_clusters_found"], |
| "n_noise_points": cluster_result["n_noise_points"], |
| "cluster_labels": cluster_labels, |
| "similarity_threshold": state["similarity_threshold"], |
| "min_cluster_size": state["min_cluster_size"], |
| "n_nearest": state["n_nearest"], |
| "sentence_rows": sentence_rows, |
| } |
|
|
| return { |
| "detection_result": detection_result, |
| "steps": [{ |
| "step": state.get("iteration", 0), |
| "node": "pattern_detection", |
| "action": "cluster + label (one LLM call per cluster)", |
| "detail": ( |
| f"{cluster_result['n_clusters_found']} clusters, " |
| f"{cluster_result['n_noise_points']} noise" |
| ), |
| }], |
| } |
|
|