写提示词像写类型签名:SEO Master Agent 把 LLM 变成"类型化函数"

SEO Master Agent 以「提示词即类型签名」强制 LLM 返回固定键 JSON,把模型调用变成可依赖的函数。
文章解析开源项目 SEO Master Agent 的核心设计:把提示词当作类型签名来写,通过 get_system_prompt() 强制每条 SEO 工作流(onpage、offpage、gmb、content、geo)返回固定键名的纯 JSON,配合输入校验(缺失即 422)形成双重契约,让 LLM 调用具备函数的可依赖特性。项目经 LiteLLM 前缀路由支持 OpenAI、Anthropic、Gemini、GLM、Ollama,单次请求密钥优先且不持久化,README 坦诚说明密钥存储的局限。任务链路为异步队列加状态机,抓取器带 SSRF 防护、认证 fail-closed。冒烟测试自举 uvicorn 并在剥离密钥的封闭环境中断言接口契约。作者还主动标出排名追踪缺失、GMB 只生成不发布两处未完成项。
大语言模型的输出天然是自由文本,这既是它的灵活之处,也是工程化落地的最大障碍。GitHub 项目 SEO Master Agent 用一个简单却关键的设计解决这个问题:把提示词当作类型签名来写,强制模型返回固定键的纯 JSON 对象。

问题:当 LLM 还是个"聊天机器人"
大多数 LLM 应用的输出是一段文本。对聊天场景无所谓,但在需要往下游传数据的系统里,文本就是负担——你得写解析器、容错、回退。SEO Master Agent 的设计者意识到,只要提示词不断输出结构化数据,后续代码和前端就能把每个工作流的产出渲染成真正的 UI 组件,而不是把一段对话记录丢到屏幕上。
这个项目跑五条 SEO 工作流:页面内优化(onpage)、外链拓展(offpage)、Google Business Profile 文案(gmb)、内容再利用(content)和本地 GEO 优化(geo)。它通过一个多 LLM 网关同时支持 OpenAI、Anthropic、Gemini、GLM 和 Ollama,后端是 FastAPI,前端是 Next.js,任务异步执行。
核心设计:提示词即类型签名
项目的关键代码在 get_system_prompt()。每个任务类型都被强制要求只返回一个原始 JSON 对象,键名固定,不允许 markdown 代码围栏。用作者的话说,这就是"把提示词当作类型签名来写"。
代码里定义得极其直白:
TASK_TYPES = ("onpage", "offpage", "gmb", "content", "geo")
REQUIRED_INPUTS = {
"onpage": ("url", "keyword"),
"offpage": ("niche",),
"gmb": ("business_name", "services"),
"content": ("blog_url",),
"geo": ("city", "service"),
}
缺输入直接返回 422,而不是让模型去猜。每个任务的系统提示词则钉死输出形状。比如 geo 提示词要求返回 geo_title、geo_meta_description、local_landmarks_to_mention、localized_body_copy;onpage 要求 optimized_title、optimized_meta_description、h1_suggestion、keyword_density_analysis、content_recommendations。
这里的洞察不只是格式约束。当输入校验和输出契约同时被写死在提示词层,LLM 的调用就变成了一个真正的函数:输入有前置条件,输出有类型,调用方可以依赖它。这是 LLM 应用从"演示"走向"系统"的分水岭。
关于 JSON Schema 与结构化输出
把提示词当作类型签名来写,本质上是用自然语言模拟 JSON Schema 的约束能力。JSON Schema 是一种用 JSON 描述的、用于校验 JSON 文档结构与类型的规范,可以声明对象必须包含哪些属性、属性是什么类型、哪些是必填项。在 LLM 工程中,OpenAI 的 Structured Outputs、Anthropic 的 tool use、以及部分框架支持的 response_format 参数,都以 JSON Schema 作为契约输入。SEO Master Agent 出于兼容多家模型(GLM、Ollama 等的支持度不一)的考虑,选择了在系统提示词中硬编码键名,而不是依赖各厂商的 Schema 特性。这条路径的取舍是:通用性更好、可移植性强,但缺少服务端强校验,模型偶尔仍可能加字段或套代码围栏,因此调用侧需要保留一层宽松解析与重试兜底。
多 LLM 路由与诚实的密钥处理
resolve_llm_config() 函数处理模型选择逻辑:单次请求头里的密钥优先,环境变量作为兜底;单次请求的密钥只在内存中使用,绝不持久化。路由本身基于模型名前缀,通过 LiteLLM 分发到 gpt、claude、gemini、zhipu/glm 或 ollama。
值得单独提的是项目在文档里的坦白。README 明说 POST /api/settings/keys 会把密钥存到本地 SQLite,这只是一个自托管便利功能,不是密钥管理器,生产环境建议用环境变量。这种把局限写在明处的做法,在开源项目里比想象中稀少。
LiteLLM 与模型前缀路由
LiteLLM 是一个把上百家模型提供方的 API 统一成 OpenAI 兼容调用格式的 Python 库,输入模型名(如 claude-3-5-sonnet、gemini-1.5-pro、ollama/llama3)即可自动分发到对应 SDK 或 HTTP 端点,并统一处理重试、超时、用量统计等横切关注点。SEO Master Agent 的路由策略正是利用这种命名约定:解析模型名前缀,判断该走哪家提供方,再交给 LiteLLM 完成实际调用。这样一来,业务代码无需为每家的鉴权头、请求体格式写分支,新增一家模型也只需确认前缀映射。需要注意的坑是:不同模型对 system prompt 的遵循度、JSON 忠实度、max_tokens 语义并不一致,切模型时输出契约的稳定性要重新验证。
任务生命周期与安全边界
一次调用走完整链路:POST /api/execute 校验入参后入队,返回 202 和 task_id;后台 worker 抓取站点(onpage 和 content 任务需要)、构建任务提示词、调用 LLM;ExecutionLog 状态从 pending 走到 running,再到 success 或 error;GET /api/tasks/{task_id} 返回结构化结果。
安全上有几处值得注意的实现:抓取器带 SSRF 防护;X-API-Key 认证是 fail-closed 的——没有 SEO_API_KEY 服务器直接拒绝启动;错误返回结构化 JSON,不暴露堆栈信息。
SSRF 防护与 fail-closed 认证
SSRF(服务端请求伪造)是指攻击者通过让服务器发起请求,去访问内网地址或云元数据端点(如 169.254.169.254),从而绕过网络边界。由于 onpage 和 content 任务需要抓取用户提供的 URL,抓取器必须做防护:解析目标域名、拒绝私有网段与回环地址、限制重定向跳数与协议。fail-closed 则是认证设计的取向——未配置 SEO_API_KEY 时服务器直接拒绝启动,而不是默认放行所有请求。与之相对的 fail-open 看似方便开发,却极易在配置遗漏时把接口裸奔到公网。两者叠加,构成了这类自托管工具最基本的安全底线。
冒烟测试自己启动服务器
tests/smoke_test.py 的设计相当少见。它自己在 18099 端口拉起 uvicorn,在一个剥离了继承 LLM 密钥的封闭环境里运行,等 /health 就绪后逐条断言契约:无密钥返回 401,错误的任务类型、输入或 URL 返回 422,合法请求拿到 task_id,任务可查询,错误结构化。运行 python tests/smoke_test.py,退出码为 0 就是通过,无需手动准备环境。
把测试环境完全隔离并自举,意味着任何人都能在自己的机器上验证接口契约,而不只是相信 README 的描述。
跑起来
cp .env.example .env # 把 SEO_API_KEY 设成一个生成的密钥
pip install -r backend/requirements.txt
uvicorn backend.server:app --port 8000
# 触发一个任务:
curl -X POST localhost:8000/api/execute -H "X-API-Key: $SEO_API_KEY" \
-d '{"task_type":"geo","inputs":{"city":"Chennai","service":"Dentist"},"model_id":"gpt-4o"}'
两个诚实的遗漏
作者在代码审读中大方列出了两点:仓库描述里的"排名追踪"(rank tracking)目前还没有对应的工作流;GMB 任务只生成文案,不会真的发布到 Google。两处都被写了出来,而不是藏起来。
对想构建 LLM 应用的开发者来说,这个项目最值得学的不是 SEO 功能本身,而是"提示词即契约"的思路——先把输入输出定义清楚,再让模型填空,而不是先让模型自由发挥再想办法接住。工作流可运行、可自托管,值得一看。
相关推荐

3分钟看懂DeepSeek:从量化私募到开源AI领跑者的崛起之路
3分钟看懂DeepSeek发展史:从幻方量化的算力积累,到V2的MLA推理降本、V3的557.6万美元训练账单、R1开源引爆全球,再到V4与70亿美元A轮融资,梳理深度求索的关键节点与技术路线。

本地文学创作模型PK:Qwen3.8 27B微调版胜出,DeepSeek v4.1表现平淡
B站UP主横向测评七款本地文学创作模型:海明威、HumanLike Chat基于Qwen3.8 27B微调表现最佳,DeepSeek v4.1叙事平淡,东方朔角色混乱垫底。附三道测试题评分与使用建议。

梁文锋的三次豪赌:DeepSeek为何将82%毛利开源?
DeepSeek为何把82%毛利的推理框架DeepInfer开源,又启动千亿融资?从技术路线、国产芯片到组织纯粹性,解析梁文锋的三次豪赌与开源战略背后的商业与理想逻辑。