victor34593993 commited on
Commit
e74dda2
·
verified ·
1 Parent(s): 42c144d

trust: proactive real-source citation in bot replies

Browse files
app/tools/knowledge_tool.py CHANGED
@@ -98,8 +98,15 @@ async def run(args: dict[str, Any], ctx: ToolContext) -> dict[str, Any]:
98
  out: dict[str, Any] = {"context": "\n\n".join(blocks), "sources": sources}
99
  if links:
100
  out["links"] = links
 
 
 
 
101
  out["hint"] = (
102
- "Si el cliente pide un enlace, usa EXACTAMENTE una de estas URLs (no "
103
- "inventes ni modifiques rutas)."
 
 
 
104
  )
105
  return out
 
98
  out: dict[str, Any] = {"context": "\n\n".join(blocks), "sources": sources}
99
  if links:
100
  out["links"] = links
101
+ # Proactive citation builds real trust (the customer can verify a policy
102
+ # claim themselves) instead of just asking the shopper to take the bot's
103
+ # word for it -- especially for concrete/checkable facts (returns,
104
+ # shipping windows, warranty, prices). Not every trivial reply needs one.
105
  out["hint"] = (
106
+ "Cuando cites una política o un dato concreto y verificable "
107
+ "(devoluciones, envíos, garantía, precios, plazos), añade el enlace "
108
+ "real al final en formato [nombre](url) para que el cliente pueda "
109
+ "comprobarlo — genera confianza. Usa EXACTAMENTE una de estas URLs, "
110
+ "nunca inventes ni modifiques rutas."
111
  )
112
  return out
tests/tools/test_tools.py CHANGED
@@ -133,6 +133,41 @@ async def test_dispatch_knowledge_returns_context(db_session, monkeypatch):
133
  assert out["sources"] == ["FAQ"]
134
 
135
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
136
  async def test_dispatch_products_surfaces_cards_and_add_url(db_session):
137
  payload = {
138
  "products": {
 
133
  assert out["sources"] == ["FAQ"]
134
 
135
 
136
+ async def test_knowledge_tool_nudges_proactive_citation_with_real_link(db_session, monkeypatch):
137
+ """Trust: when the KB match has a real, verified URL, the model is told to
138
+ proactively CITE it for concrete/checkable claims (returns, shipping, price)
139
+ -- not just when the shopper explicitly asks for a link. The widget already
140
+ renders [name](url) as a real clickable link."""
141
+ from app import embeddings as emb
142
+
143
+ async def fake_query(q):
144
+ return [1.0, 0.0]
145
+
146
+ async def fake_texts(texts, *, kind="passage"):
147
+ return [[1.0, 0.0] for _ in texts]
148
+
149
+ monkeypatch.setattr(emb, "embed_query", fake_query)
150
+ monkeypatch.setattr(emb, "embed_texts", fake_texts)
151
+
152
+ src = KnowledgeSource(kind="url", name="Política de envíos", location="https://tienda.example/envios")
153
+ db_session.add(src)
154
+ await db_session.flush()
155
+ db_session.add(
156
+ KnowledgeChunk(
157
+ source_id=src.id, ordinal=0, text="Envíos gratis desde 199€", embedding=[1.0, 0.0],
158
+ meta={"source_name": "Política de envíos"},
159
+ )
160
+ )
161
+ await db_session.flush()
162
+
163
+ ctx = ToolContext(db=db_session, session=await _session(db_session))
164
+ out = await registry.dispatch("search_knowledge", {"query": "envíos"}, ctx)
165
+ assert out["links"] == [{"name": "Política de envíos", "url": "https://tienda.example/envios"}]
166
+ assert "[nombre](url)" in out["hint"] # tells the model the exact citable format
167
+ assert "verificable" in out["hint"] # nudges WHEN to cite (concrete/checkable claims)
168
+ assert "EXACTAMENTE una de estas URLs" in out["hint"] # still forbids inventing routes
169
+
170
+
171
  async def test_dispatch_products_surfaces_cards_and_add_url(db_session):
172
  payload = {
173
  "products": {