Files
2026Technology-Competition/tests/test_impact_agent_rag.py
T

86 lines
3.3 KiB
Python

"""ImpactAgent RAG 上下文注入测试(RAG 迭代 Task 4)。
验证:
- use_rag=True 时,run_impact 发送给 LLM 的 prompt 文本包含 RAG 检索命中片段与明确小节标题。
- use_rag=False(或默认)时,prompt 文本不含 RAG 小节标题(向后兼容)。
"""
from genesis.impact.impact_agent import ImpactAgent
from genesis.rag.embeddings import FakeEmbedder
from genesis.rag.impact_rag import ImpactRAG
from genesis.rag.store import RagStore
_RAG_SECTION_TITLE = "# 既有系统关联上下文(RAG 检索,辅助判断影响范围)"
class FakeEngine:
"""捕获真实 LLM 方法(chat_structured)收到的 prompt 文本。
方法名与签名刻意复用本仓库 InferenceEngine.chat_structured 的形参风格,
以保证 mock 的是真实接口(key=session_id/prompt/variables/schema/retry_count)。
"""
def __init__(self) -> None:
self.last_prompt: str | None = None
self.calls = 0
def chat_structured(self, *, session_id, prompt, variables, schema, retry_count=2):
self.last_prompt = prompt
self.calls += 1
# 返回结构兼容 ChatResult 的最小占位(测试仅校验 prompt 注入)
return {"session_id": session_id, "prompt": prompt}
def _make_rag(session_id: str, sources):
store = RagStore(":memory:")
rag = ImpactRAG(store, FakeEmbedder())
rag.index(session_id, sources)
return store, rag
def test_run_impact_with_rag_injects_context():
session_id = "sess-rag"
store, rag = _make_rag(session_id, [("TradeApplication.java", "订单创建调用 MyBatis")])
try:
engine = FakeEngine()
agent = ImpactAgent(engine=engine, rag=rag, use_rag=True)
agent.run_impact(session_id, requirements_text="创建订单的影响", k=5)
prompt = engine.last_prompt
assert prompt is not None
# 命中片段(含文件名 TradeApplication.java)被注入
assert "TradeApplication" in prompt
# 明确小节标题被注入
assert _RAG_SECTION_TITLE in prompt
finally:
store.close()
def test_run_impact_without_rag_no_context():
session_id = "sess-no-rag"
store, rag = _make_rag(session_id, [("TradeApplication.java", "订单创建调用 MyBatis")])
try:
engine = FakeEngine()
agent = ImpactAgent(engine=engine, rag=rag, use_rag=False)
agent.run_impact(session_id, requirements_text="创建订单的影响", k=5)
prompt = engine.last_prompt
# 显式关闭 RAG:不含小节标题,也不含检索片段
assert _RAG_SECTION_TITLE not in prompt
assert "TradeApplication" not in prompt
finally:
store.close()
def test_run_impact_default_no_rag_no_context():
# 默认 use_rag 为 False(未显式开启),行为与关闭一致
session_id = "sess-default"
store, rag = _make_rag(session_id, [("TradeApplication.java", "订单创建调用 MyBatis")])
try:
engine = FakeEngine()
agent = ImpactAgent(engine=engine, rag=rag) # 不传 use_rag
agent.run_impact(session_id, requirements_text="创建订单的影响", k=5)
prompt = engine.last_prompt
assert _RAG_SECTION_TITLE not in prompt
assert "TradeApplication" not in prompt
finally:
store.close()