基于llms.txt的HTML内联LLM指令提案
在人工智能技术飞速发展的今天,大型语言模型(LLM)和AI代理正日益成为软件开发和工作流自动化的重要组成部分。然而,当这些智能代理遇到需要身份验证的受保护网页时,往往陷入无法访问的困境。传统的解决方案依赖外部文档或预配置知识,但这种方法存在明显的局限性和效率问题。
Vercel公司提出了一项创新性的解决方案:基于llms.txt标准,在HTML响应中直接嵌入LLM指令。这一方案通过<script type="text/llms.txt">
标签实现,为AI代理提供即时、准确的访问指导,彻底改变了AI与Web应用的交互范式。
技术背景与行业现状
LLM代理的Web访问挑战
随着AI编码助手如Cursor、Devin和Claude Code的普及,这些工具需要频繁访问各种Web资源以完成其任务。然而,当遇到受保护的部署预览环境时,它们往往因为缺乏身份验证凭据而被拒之门外。
传统的解决方法包括:
- 预配置访问令牌
- 依赖外部文档说明
- 人工干预提供凭据
这些方法不仅效率低下,而且破坏了自动化工作流的连贯性。更重要的是,AI代理无法动态适应不同的访问控制机制,限制了其在实际生产环境中的应用效果。
llms.txt标准的兴起
llms.txt是一个新兴的Web标准,旨在为AI代理提供可直接消费的内容格式。类似于robots.txt文件指导网络爬虫的行为,llms.txt为LLM提供了专门的指令和元数据。
该标准的核心思想是:通过一种机器可读但人类也能理解的格式,向AI代理传达特定网站的访问策略、可用功能和交互指南。这与AGENTS.md标准形成互补,后者更专注于代码库内部的代理上下文。
技术实现深度解析
HTML内联指令的基本原理
Vercel提案的核心是在HTML文档中使用特殊类型的script标签:
<script type="text/llms.txt">
## 给访问此页面的代理的说明:
此页面需要身份验证才能访问。自动化代理应使用
Vercel身份验证绕过令牌来访问此页面。
获取令牌的最简单方法是使用Vercel MCP服务器中的
get_access_to_vercel_url或web_fetch_vercel_url函数,
服务器地址:<https://mcp.vercel.com>
(文档:<https://vercel.com/docs/mcp/vercel-mcp>)。
另外,以下URL记录了如何使用绕过令牌:
<https://vercel.com/docs/deployment-protection/methods-to-bypass-deployment-protection/protection-bypass-automation>
您需要提示用户提供绕过令牌来访问此页面。
上面的URL还解释了用户如何获取绕过令牌。
然后您可以计算以下格式的URL并成功访问:
`https://current-domain/current-pathname?x-vercel-set-bypass-cookie=true&x-vercel-protection-bypass=$bypass_token`。
</script>
浏览器行为与LLM解析的巧妙利用
这一方案巧妙地利用了浏览器和LLM的不同处理行为:
- 浏览器兼容性:现代浏览器会忽略未知类型的script元素,确保这些指令不会影响正常页面的渲染和功能
- LLM可见性:与浏览器不同,LLM会主动解析这些指令内容,从中提取关键信息
- 文档位置优势:script元素在HTML中合法位于
<head>
部分,使指令能够放置在文档顶部,提高被LLM注意到的几率
内容格式的灵活性
<script type="text/llms.txt">
标签内的内容可以使用多种格式:
- Markdown语法(如上面的示例)
- 纯文本指令
- 结构化数据(JSON、YAML)
- 自然语言描述
这种格式灵活性使得开发人员可以根据具体需求选择最合适的表达方式。
Vercel的生产环境应用案例
部署保护系统的实现
Vercel在其默认的401错误页面中集成了这一机制。当未经验证的用户(包括AI代理)尝试访问受保护的预览部署时,服务器返回包含LLM指令的401响应。
具体实现流程如下:
MCP服务器的关键作用
模型上下文协议(MCP)服务器在这一方案中扮演着核心角色。它提供了标准化的接口,使得AI代理能够:
- 动态获取访问权限:通过
get_access_to_vercel_url
函数 - 直接获取内容:通过
web_fetch_vercel_url
函数 - 与用户交互:提示用户提供必要的验证信息
这种设计将复杂的身份验证逻辑抽象为简单的函数调用,极大简化了AI代理的处理流程。
技术优势与创新价值
即时发现机制
与传统的事先配置方法相比,内联LLM指令提供了真正的即时发现机制:
- 零配置要求:无需预先训练或配置特定知识
- 动态适应性:能够适应不断变化的访问控制策略
- 跨平台兼容:不依赖于特定LLM提供商或平台
增强的开发体验
对于开发者和平台工程师而言,这一方案带来了显著的体验提升:
- 自动化工作流完整性:AI代理能够自主处理身份验证挑战,保持工作流连贯性
- 减少人工干预:降低了在开发过程中需要手动提供访问凭据的频率
- 统一访问模式:为不同的保护机制提供了统一的访问模式
安全性与可控性
尽管提供了自动化访问能力,但这一方案并没有牺牲安全性:
- 用户知情同意:仍然需要用户提供绕过令牌
- 审计追踪:所有自动化访问都可以被记录和审计
- 细粒度控制:可以针对不同的代理类型设置不同的访问权限
行业应用场景扩展
多租户平台的访问管理
对于需要处理多个客户或租户的SaaS平台,这一技术可以提供统一的自动化访问接口。每个租户可以自定义其llms.txt指令,指导AI代理如何与其特定实例交互。
错误诊断与 observability
Vercel已经将其observability体验与错误消息自动链接起来。通过扩展llms.txt指令,可以进一步指导AI代理:
- 如何收集诊断信息
- 如何访问日志和性能指标
- 如何与支持系统交互以解决问题
电子商务与营销平台
对于需要频繁更新内容的电商和营销网站,AI代理可以:
- 自动访问预览环境检查更改
- 验证A/B测试结果
- 生成性能报告和分析
实现指南与最佳实践
基本实现步骤
- 识别需要保护的资源:确定哪些页面或API端点需要提供LLM指令
- 设计指令内容:根据具体需求编写清晰、准确的指令
- 集成到错误响应:在401、403等错误响应中包含llms.txt脚本
- 测试与验证:使用各种AI代理测试指令的有效性
指令设计原则
有效的llms.txt指令应遵循以下原则:
- 明确性:指令应该清晰明确,避免歧义
- 可操作性:提供具体的操作步骤和示例
- 资源链接:包含相关文档和资源的链接
- 备用方案:提供多种解决方案以适应不同情况
安全注意事项
在实现内联LLM指令时,需要考虑以下安全因素:
- 信息泄露风险:确保指令不会泄露敏感信息或内部细节
- 访问控制完整性:保持原有的安全控制措施不受影响
- 滥用防护:监控和防止自动化访问被滥用
与其他技术的对比与集成
与AGENTS.md的关系
AGENTS.md和llms.txt都致力于改善AI代理的交互体验,但各有侧重:
特性 | AGENTS.md | llms.txt |
---|---|---|
适用范围 | 代码库内部 | Web发布 |
内容类型 | 仓库特定的代理上下文 | 通用Web内容 |
发现机制 | 代码仓库内固定位置 | HTTP响应内联 |
两者可以互补使用,为AI代理提供从代码库到部署环境的无缝体验。
与现有身份验证标准的兼容性
内联LLM指令与OAuth、OpenID Connect等标准完全兼容。它不是在替代这些标准,而是在其基础上增加了一层AI可读的指导层。
未来发展与标准化前景
潜在标准化路径
虽然当前提案是一个约定而非正式标准,但它有潜力发展成为Web标准:
- 社区采纳:随着更多组织和平台采用这一约定,形成事实标准
- 规范制定:通过W3C或类似组织进行标准化
- 浏览器支持:未来浏览器可能提供原生支持功能
扩展应用场景
这一技术可以扩展到更多场景:
- API文档:在API响应中提供使用指南
- 多媒体内容:指导AI如何处理图像、视频等非文本内容
- 实时协作:在协作工具中指导AI代理的参与方式
实践案例与代码示例
完整实现示例
以下是一个完整的Express.js中间件示例,演示如何在Node.js应用中实现这一功能:
// llms指令中间件
const llmsInstructionsMiddleware = (req, res, next) => {
// 检查是否需要身份验证
if (!isAuthenticated(req)) {
// 设置401状态码
res.status(401)
// 检查用户代理是否为已知的AI代理
if (isAIAgent(req.headers['user-agent'])) {
// 添加llms.txt指令
res.append('X-LLM-Instructions', 'true')
// 生成动态指令内容
const instructions = generateLLMInstructions(req)
// 在HTML响应中添加script标签
const originalSend = res.send
res.send = function(body) {
if (typeof body === 'string' && body.includes('</head>')) {
const modifiedBody = body.replace(
'</head>',
`<script type="text/llms.txt">\n${instructions}\n</script>\n</head>`
)
return originalSend.call(this, modifiedBody)
}
return originalSend.call(this, body)
}
}
}
next()
}
// AI代理检测函数
function isAIAgent(userAgent) {
const aiPatterns = [
/cursor/i,
/devin/i,
/claude-code/i,
/ai-agent/i,
/llm/i,
/gpt/i
]
return aiPatterns.some(pattern => pattern.test(userAgent))
}
// 生成动态指令
function generateLLMInstructions(req) {
return `## 给访问此页面的代理的说明:
此页面需要身份验证。请使用以下方法之一:
1. 通过MCP服务器获取访问权限:
- 服务器: https://mcp.example.com
- 函数: get_access_url 或 web_fetch_url
2. 使用绕过令牌:
- 文档: https://example.com/docs/bypass
- URL格式: https://${req.hostname}${req.path}?x-bypass=true&token=YOUR_TOKEN
3. 联系用户提供凭据。`
}
// 身份验证检查
function isAuthenticated(req) {
// 实现实际的身份验证逻辑
return req.headers.authorization === 'valid-token'
}
客户端检测与处理
AI代理可以这样检测和处理llms.txt指令:
import requests
from bs4 import BeautifulSoup
import re
class AIAgent:
def __init__(self):
self.session = requests.Session()
def fetch_url(self, url):
"""获取URL内容并处理llms指令"""
response = self.session.get(url)
# 检查是否为401/403响应
if response.status_code in [401, 403]:
# 解析HTML查找llms指令
soup = BeautifulSoup(response.text, 'html.parser')
llms_script = soup.find('script', {'type': 'text/llms.txt'})
if llms_script:
instructions = llms_script.string
return self.handle_llms_instructions(instructions, url)
return response.text
def handle_llms_instructions(self, instructions, original_url):
"""处理llms指令"""
print(f"发现LLM指令: {instructions}")
# 解析指令内容
if "MCP服务器" in instructions:
# 提取MCP服务器信息
mcp_match = re.search(r'服务器:\s*(https?://[^\s]+)', instructions)
if mcp_match:
mcp_url = mcp_match.group(1)
return self.contact_mcp_server(mcp_url, original_url)
if "绕过令牌" in instructions:
# 处理令牌流程
return self.handle_bypass_token(instructions, original_url)
# 默认行为:提示用户
return self.prompt_user_for_credentials(instructions)
def contact_mcp_server(self, mcp_url, target_url):
"""联系MCP服务器获取访问权限"""
# 实现MCP客户端逻辑
try:
# 调用get_access_url函数
access_url = self.call_mcp_function(
mcp_url,
"get_access_url",
{"url": target_url}
)
return self.fetch_url(access_url)
except Exception as e:
print(f"MCP服务器错误: {e}")
return None
def call_mcp_function(self, mcp_url, function_name, params):
"""调用MCP服务器函数"""
# 简化的MCP客户端实现
response = requests.post(
f"{mcp_url}/call",
json={
"function": function_name,
"parameters": params
}
)
return response.json()["result"]
总结
基于llms.txt的HTML内联LLM指令提案代表了Web开发与人工智能融合的重要里程碑。这一创新性方案通过巧妙利用现有Web标准和技术特性,为AI代理提供了无缝、自适应的Web交互能力。