修复网页对话并接入 SearXNG 搜索
This commit is contained in:
@@ -0,0 +1,77 @@
|
||||
#!/usr/bin/env python3
|
||||
"""真实 DeepSeek → SearXNG → DeepSeek 联网闭环验收。
|
||||
|
||||
需要服务器密钥与已启动的 SearXNG,不属于日常离线回归测试。
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import asyncio
|
||||
import sys
|
||||
from pathlib import Path
|
||||
|
||||
ROOT = Path(__file__).resolve().parent.parent.parent
|
||||
sys.path.insert(0, str(ROOT))
|
||||
|
||||
from app.config import AppConfig # noqa: E402
|
||||
from app.llm import create_provider # noqa: E402
|
||||
from app.search import ( # noqa: E402
|
||||
WEB_SEARCH_PROMPT,
|
||||
WEB_SEARCH_TOOL,
|
||||
SearXNGSearchClient,
|
||||
)
|
||||
|
||||
|
||||
async def main() -> int:
|
||||
cfg = AppConfig.load()
|
||||
if not cfg.search.enabled:
|
||||
raise RuntimeError("请先设置 SEARCH_ENABLED=true")
|
||||
|
||||
llm = create_provider(cfg.llm)
|
||||
search = SearXNGSearchClient(cfg.search)
|
||||
messages = [
|
||||
{"role": "system", "content": WEB_SEARCH_PROMPT},
|
||||
{"role": "user", "content": "请搜索 DeepSeek 最近有什么消息,用一句话概括。"},
|
||||
]
|
||||
try:
|
||||
first = await llm.complete(messages, tools=[WEB_SEARCH_TOOL])
|
||||
if not first.tool_calls:
|
||||
raise AssertionError(f"模型没有调用搜索工具,直接回答:{first.content!r}")
|
||||
call = first.tool_calls[0]
|
||||
query = call.parsed_arguments().get("query")
|
||||
if not isinstance(query, str) or not query.strip():
|
||||
raise AssertionError(f"搜索参数无效:{call.arguments!r}")
|
||||
|
||||
results = await search.search(query)
|
||||
if not results:
|
||||
raise AssertionError(f"SearXNG 对 {query!r} 没有返回结果")
|
||||
messages.extend([
|
||||
{
|
||||
"role": "assistant",
|
||||
"content": first.content or None,
|
||||
"tool_calls": [{
|
||||
"id": call.id,
|
||||
"type": "function",
|
||||
"function": {"name": call.name, "arguments": call.arguments},
|
||||
}],
|
||||
},
|
||||
{
|
||||
"role": "tool",
|
||||
"tool_call_id": call.id,
|
||||
"content": search.for_model(query, results),
|
||||
},
|
||||
])
|
||||
final = await llm.complete(messages, max_tokens=250)
|
||||
if not final.content.strip():
|
||||
raise AssertionError("搜索回灌后模型没有生成回答")
|
||||
print(f"工具调用: {call.name}({query!r})")
|
||||
print(f"搜索结果: {len(results)} 条;首条={results[0].title!r}")
|
||||
print(f"最终回答: {final.content.strip()}")
|
||||
print("真实联网闭环:PASS")
|
||||
return 0
|
||||
finally:
|
||||
await llm.aclose()
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
raise SystemExit(asyncio.run(main()))
|
||||
Reference in New Issue
Block a user