diff --git a/admin.py b/admin.py index 75aeb38..d3cb1d7 100644 --- a/admin.py +++ b/admin.py @@ -52,6 +52,7 @@ DEFAULT_CONFIG = { ], ensure_ascii=False), "footer_text": "NBA球迷大全 · 数据为模拟演示数据(2025-26 赛季) · LLM: DeepSeek · 向量: Chroma + bge-large-zh", "admin_password": "admin123", + "entity_mark_mode": "first", # 实体标记:first=只标记首次出现 / all=全部标记 } SEARCHABLE = { # 每个表可搜索的 TEXT 字段 diff --git a/api.py b/api.py index 6ab8523..03d93f8 100644 --- a/api.py +++ b/api.py @@ -78,7 +78,8 @@ def api_chat(): game_refs = [it for s in sources if s.get("tool") in ("search_games", "get_game_detail") for it in s.get("items", [])] - spans, cards = entity_linker.link_entities(reply, game_refs=game_refs) + mark_mode = admin_mod.get_config().get("entity_mark_mode", "first") + spans, cards = entity_linker.link_entities(reply, game_refs=game_refs, mark_mode=mark_mode) return jsonify({"reply": reply, "sources": sources, "used_tools": used_tools, "news_refs": news_refs, "entities": spans, "cards": cards}) except Exception as e: diff --git a/entity_linker.py b/entity_linker.py index 80d5208..bbb987f 100644 --- a/entity_linker.py +++ b/entity_linker.py @@ -164,13 +164,23 @@ def _match_games(text, game_refs): return cards -def link_entities(text, game_refs=None): +def link_entities(text, game_refs=None, mark_mode="first"): """主入口:扫描回答文本。 返回 (spans, cards) spans: 实体命中区间(前端高亮标记用),按 start 升序、互不重叠 + mark_mode="first" 时同一实体(type,id)只保留首次出现;"all" 时全部标记 cards: 快速查看卡片数据(每类限量,避免刷屏) """ spans = _find_spans(text or "") + if mark_mode == "first": + seen, kept = set(), [] + for sp in spans: # spans 已按 start 升序 → 保留首次 + key = (sp["type"], sp["id"]) + if key in seen: + continue + seen.add(key) + kept.append(sp) + spans = kept cards = [] seen_cards = set() for sp in spans: diff --git a/static/admin.html b/static/admin.html index 4bb6b51..1fc47af 100644 --- a/static/admin.html +++ b/static/admin.html @@ -159,6 +159,11 @@ td.num { text-align:center; }