从 0 搭一个 SERP API + LLM Agent 端到端实战(2026年7月)

我之前做的 AI Agent 跑生产 6 个月,现在把完整搭建过程复盘一遍。

从环境到部署,5 步搭起来一个能问实时问题的 AI Agent。

1. 技术选型

组件 选择 理由
LLM gpt-4o / claude-sonnet-4-5 综合能力
SERP API serpbase 价格低 + 数据完整 + AI 集成好
后端 Python FastAPI 异步支持好
前端 Gradio 快速 demo
部署 Docker + Vercel 简单

成本结构:gpt-4o 输入 2.5/1M+serpbase2.5/1M + serpbase 2.5/1M+serpbase0.30/1k = 一次问答 $0.012。

2. Step 1:申请 SERP API key

去 serpbase.dev 注册,送 100 次免费调用,不用绑卡。

拿 API key 后存环境变量:

ini 复制代码
export SERPBASE_API_KEY=your-key
export OPENAI_API_KEY=sk-...

3. Step 2:核心代码

完整代码 80 行:

python 复制代码
import os
import requests
from openai import OpenAI

class SearchAgent:
    def __init__(self):
        self.serp_key = os.environ['SERPBASE_API_KEY']
        self.openai = OpenAI()

    def search(self, query: str) -> dict:
        r = requests.post(
            'https://api.serpbase.dev/google/search',
            headers={'X-API-Key': self.serp_key},
            json={'q': query, 'hl': 'zh-CN', 'gl': 'cn', 'num': 10},
            timeout=(2, 5)
        )
        r.raise_for_status()
        return r.json()

    def format_context(self, serp: dict) -> str:
        lines = ['## 搜索结果']
        for i, item in enumerate(serp.get('organic', [])[:5], 1):
            lines.append(f"[{i}] {item['title']}\n{item['snippet'][:80]}\n来源: {item['link']}")
        return '\n'.join(lines)

    def ask(self, question: str) -> str:
        serp = self.search(question)
        if not serp.get('organic'):
            return "暂未找到相关信息"

        context = self.format_context(serp)
        prompt = f"""基于以下搜索结果回答问题,只引用事实。

{context}

问题: {question}"""

        r = self.openai.chat.completions.create(
            model='gpt-4o',
            messages=[{'role': 'user', 'content': prompt}],
            temperature=0,
            timeout=15
        )
        return r.choices[0].message.content

if __name__ == '__main__':
    agent = SearchAgent()
    print(agent.ask('2026 年 Q2 上海 GDP'))

4. Step 3:Web UI(Gradio)

10 行加 UI:

python 复制代码
import gradio as gr

def chat(question):
    return SearchAgent().ask(question)

demo = gr.Interface(
    fn=chat,
    inputs=gr.Textbox(label="问题"),
    outputs=gr.Textbox(label="答案"),
    title="实时搜索 AI Agent"
)
demo.launch()

跑起来:python app.py,浏览器开 http://localhost:7860。

5. Step 4:错误处理

直接跑会发现 3 个常见错误,加上去:

python 复制代码
def search(self, query):
    try:
        r = requests.post(..., timeout=(2, 5))
        r.raise_for_status()
        return r.json()
    except requests.Timeout:
        # 降级 1: stale cache
        cached = get_stale_cache(query)
        return cached or {'organic': []}
    except requests.HTTPError as e:
        if e.response.status_code == 429:
            # 降级 2: 等待 Retry-After
            time.sleep(int(e.response.headers.get('Retry-After', 1)))
            return self.search(query)  # 重试 1 次
        raise

def ask(self, question):
    serp = self.search(question)
    if not serp.get('organic'):
        return "暂未找到相关信息,你可以:\n1. 加时间词(如 '2026')\n2. 加地域词\n3. 换个说法"
    # ... LLM 调用

6. Step 5:部署

Docker 化:

dockerfile 复制代码
FROM python:3.11-slim
WORKDIR /app
COPY requirements.txt .
RUN pip install -r requirements.txt
COPY . .
CMD ["python", "app.py"]

部署到 Vercel / Railway / 自己的 VPS。

7. 性能优化

跑起来后,几个常见优化:

缓存。同 query 5 分钟内复用:

python 复制代码
import redis
r = redis.Redis()

def cached_search(query):
    key = hashlib.md5(query.encode()).hexdigest()
    cached = r.get(key)
    if cached:
        return json.loads(cached)
    data = search(query)
    r.setex(key, 300, json.dumps(data))
    return data

并发。多用户同时问,用 asyncio:

python 复制代码
async def ask_async(question):
    serp = await search_async(question)
    return await llm_async(question, serp)

token 压缩。SERP JSON 太大,只取前 5 条 + 截 snippet 80 字符。

8. 测试

写几个测试 query 验证:

python 复制代码
test_queries = [
    ('2026 年 Q2 上海 GDP', '2026'),
    ('BTC 实时价格', 'BTC'),
    ('今日新闻头条', None),  # 模糊 query
]

for q, expected in test_queries:
    answer = agent.ask(q)
    print(f"Q: {q}\nA: {answer}\n")

9. 监控

跑生产后,盯 3 个指标:

python 复制代码
from prometheus_client import Counter, Histogram

requests_total = Counter('agent_requests_total', 'Total requests')
latency = Histogram('agent_latency_seconds', 'Latency')

@latency.time()
def ask(question):
    requests_total.inc()
    return agent.ask(question)

Grafana 看板,3 个面板:请求量 / 延迟 / 错误率。

10. 30 天数据

跑下来:

  • 平均问答延迟 3.2s
  • 月成本 serpbase 1.5+OpenAI1.5 + OpenAI 1.5+OpenAI75 = $76.5
  • 答案准确率 91%(人工评估 200 条)
  • 0 故障

整套从 0 到生产,1 个工程师 1 天搭完。

11. 进阶方向

跑起来后,可以扩展:

  • 多轮对话:加 memory 模块
  • 工具调用:Agent 决定要不要搜(ReAct)
  • 多模态:支持图片搜索(Lens 端点)
  • 本地 SEO:加 Maps 端点
  • 企业版:加用户系统 + 配额管理

我下一步上 ReAct 多轮搜索,预计准确率能到 94%。

12. 完整代码

完整代码 + 部署文档放 GitHub,clone 就能跑。serpbase 注册后 5 分钟接好,1 小时搭完整个 Agent。

相关推荐
众人皆醒我独醉16 小时前
TGI:HuggingFace 的官方推理服务——不止 PagedAttention,更懂模型生态
面试·llm·ai编程
众人皆醒我独醉16 小时前
vLLM:PagedAttention 如何让 LLM 推理吞吐提升 24 倍
面试·llm·ai编程
张彦峰ZYF16 小时前
全球开源大模型生态-从开放权重到开放智能系统:发展、进展、主力模型成就与方向分析
人工智能·开源·llm·agent
网易云信20 小时前
AI 时代如何为“数字员工”划清身份边界?
人工智能·后端·agent
HIT_Weston20 小时前
161、【Agent】【OpenCode】TuiThreadCmd(联合类型)
人工智能·agent·opencode
武子康21 小时前
GitHub Code Quality GA 后,100 名开发者真的只要每月 1000 美元吗?
人工智能·agent·github copilot
安逸sgr1 天前
ReAct 是什么?Thought、Action、Observation 分别代表什么?
人工智能·ai·大模型·agent·智能体