test_reme.py 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112
  1. from types import SimpleNamespace
  2. import pytest
  3. import app.adapters.reme as module
  4. from app.adapters.reme import ReMeAgent
  5. def test_reme_heuristic_query_expands_deployment_question():
  6. queries = ReMeAgent._heuristic_queries("上次部署遇到什么问题?")
  7. assert queries[0] == "上次部署遇到什么问题?"
  8. assert "部署" in queries
  9. assert "索引构建" in queries
  10. assert "批次" in queries
  11. assert "超时" in queries
  12. def test_reme_merge_search_results_deduplicates_documents():
  13. first = "========== daily/2026-07-15.md:5-8 [score=0.4] ==========\n向量索引构建超时"
  14. second = "========== daily/2026-07-15.md:5-8 [score=0.8] ==========\n向量索引构建超时"
  15. merged = ReMeAgent._merge_search_results([first, second])
  16. assert merged.count("daily/2026-07-15.md") == 1
  17. assert "向量索引构建超时" in merged
  18. @pytest.mark.asyncio
  19. async def test_reme_search_memory_uses_multiple_queries():
  20. class FakeService:
  21. def __init__(self):
  22. self.queries: list[str] = []
  23. async def run_job(self, job: str, *, query: str, limit: int):
  24. assert job == "search"
  25. assert limit == 5
  26. self.queries.append(query)
  27. if query == "索引":
  28. return SimpleNamespace(
  29. answer="========== note.md:1 [score=1.0] ==========\n向量索引构建超时"
  30. )
  31. return SimpleNamespace(answer="")
  32. service = FakeService()
  33. agent = ReMeAgent()
  34. result, used_queries = await agent._search_memory(service, ["原始问题", "索引"])
  35. assert service.queries == ["原始问题", "索引"]
  36. assert used_queries == ["索引"]
  37. assert "向量索引构建超时" in result
  38. def test_reme_write_classifier_separates_statements_from_queries():
  39. assert ReMeAgent._should_memorize(
  40. "上次部署测试环境时遇到向量索引构建超时。"
  41. ) is True
  42. assert ReMeAgent._should_memorize(
  43. "以后修复代码时按这个流程:先复现,再定位,最后验证。"
  44. ) is True
  45. assert ReMeAgent._should_memorize("上次部署遇到了什么问题?") is False
  46. def test_reme_disables_automatic_background_and_dream_jobs():
  47. assert set(ReMeAgent._PASSIVE_JOB_OVERRIDES) == {
  48. "index_update_loop",
  49. "resource_watch_loop",
  50. "digest_watch_loop",
  51. "dream_cron",
  52. }
  53. assert all(
  54. config == {"backend": "base", "enable_serve": False}
  55. for config in ReMeAgent._PASSIVE_JOB_OVERRIDES.values()
  56. )
  57. @pytest.mark.asyncio
  58. async def test_reme_semantic_search_filters_low_similarity(monkeypatch):
  59. class FakeEmbedding:
  60. configured = True
  61. async def embed(self, _texts):
  62. return [[1.0, 0.0]]
  63. class FakeRepo:
  64. async def search_embeddings(self, _system, _query_vector, limit):
  65. assert limit == 5
  66. return [
  67. {
  68. "memory_id": "relevant",
  69. "source": "daily/relevant.md",
  70. "content": "向量索引构建超时,通过分批导入解决。",
  71. "score": 0.40,
  72. },
  73. {
  74. "memory_id": "irrelevant",
  75. "source": "daily/irrelevant.md",
  76. "content": "前端按钮颜色是蓝色。",
  77. "score": 0.20,
  78. },
  79. ]
  80. monkeypatch.setattr(module, "embedding_client", FakeEmbedding())
  81. agent = ReMeAgent()
  82. agent.repo = FakeRepo()
  83. evidence, count = await agent._semantic_search("上次部署遇到了什么问题?")
  84. assert count == 1
  85. assert "向量索引构建超时" in evidence
  86. assert "按钮颜色" not in evidence