让人工智能代理访问整个网络会产生嘈杂的结果。代理将代币浪费在不相关的数据上,并且幻觉率增加。确定代理可以访问的平台和结果类型的范围可以提高答案质量、减少延迟并降低成本。本教程构建了一个范围搜索层,该层根据任务类型限制代理数据访问。产品比较代理只看到亚马逊和沃尔玛。情绪代理只能看到 Reddit。新闻代理只能看到 Google 新闻。
前置条件
- 已安装 Python 3.9+
- 请求已安装库
- 来自 scavio.dev 的 Scavio API 密钥
- AI代理工具调用的基本了解
操作指南
步骤 1: 为不同的代理任务定义范围配置文件
创建预定义的范围配置,限制代理可以访问的平台和结果类型。每个配置文件都针对特定用例进行了调整。
import os, requests
SCAVIO_KEY = os.environ['SCAVIO_API_KEY']
URL = 'https://api.scavio.dev/api/v1/search'
H = {'x-api-key': SCAVIO_KEY, 'Content-Type': 'application/json'}
SCOPE_PROFILES = {
'product_research': {
'platforms': ['amazon', 'walmart'],
'max_results': 5,
'description': 'Product pricing and availability'
},
'sentiment': {
'platforms': ['reddit'],
'max_results': 10,
'description': 'Community opinions and discussions'
},
'news': {
'platforms': ['google'],
'query_suffix': ' news 2026',
'max_results': 5,
'description': 'Current news and events'
},
'technical': {
'platforms': ['google'],
'site_restrict': ['stackoverflow.com', 'github.com', 'docs.python.org'],
'max_results': 5,
'description': 'Technical documentation and Q&A'
},
'video': {
'platforms': ['youtube'],
'max_results': 5,
'description': 'Video tutorials and reviews'
}
}
for name, profile in SCOPE_PROFILES.items():
print(f'{name}: {profile["description"]} ({profile["platforms"]})')步骤 2: 构建范围搜索功能
强制执行范围配置文件的搜索功能。它拒绝搜索允许列表之外的平台并应用任何查询限制。
def scoped_search(query: str, scope: str, override_num: int = None) -> list:
"""Search within a defined scope profile."""
profile = SCOPE_PROFILES.get(scope)
if not profile:
return [{'error': f'Unknown scope: {scope}. Available: {list(SCOPE_PROFILES.keys())}'}]
num = override_num or profile['max_results']
all_results = []
for platform in profile['platforms']:
q = query
# Apply query suffix if defined
if 'query_suffix' in profile:
q += profile['query_suffix']
# Apply site restrictions
if 'site_restrict' in profile:
for site in profile['site_restrict']:
site_q = f'site:{site} {q}'
resp = requests.post(URL, headers=H,
json={'query': site_q, 'country_code': 'us', 'num_results': 2})
for r in resp.json().get('organic_results', []):
all_results.append({'title': r['title'], 'url': r['link'],
'snippet': r.get('snippet', ''), 'platform': platform, 'scope': scope})
continue
# Platform-specific site prefix
site_map = {'amazon': 'amazon.com', 'youtube': 'youtube.com',
'walmart': 'walmart.com', 'reddit': 'reddit.com'}
if platform in site_map:
q = f'site:{site_map[platform]} {q}'
resp = requests.post(URL, headers=H,
json={'query': q, 'country_code': 'us', 'num_results': num})
for r in resp.json().get('organic_results', []):
all_results.append({'title': r['title'], 'url': r['link'],
'snippet': r.get('snippet', ''), 'platform': platform, 'scope': scope})
return all_results[:num]
results = scoped_search('noise cancelling headphones', scope='product_research')
print(f'Product scope: {len(results)} results')
for r in results:
print(f' [{r["platform"]}] {r["title"][:60]}')步骤 3: 为代理创建范围感知工具定义
根据活动范围动态生成工具定义。代理只能看到其指定范围内的工具,从而防止超出范围的搜索。
def make_scoped_tool(scope: str) -> dict:
"""Generate a tool definition locked to a specific scope."""
profile = SCOPE_PROFILES[scope]
return {
'type': 'function',
'function': {
'name': f'search_{scope}',
'description': f'Search for {profile["description"]}. '
f'Platforms: {", ".join(profile["platforms"])}. '
f'Max {profile["max_results"]} results.',
'parameters': {
'type': 'object',
'properties': {
'query': {'type': 'string', 'description': 'Search query'}
},
'required': ['query']
}
}
}
def make_agent_tools(scopes: list[str]) -> list:
"""Create tool set for an agent with specific scopes."""
return [make_scoped_tool(s) for s in scopes]
# Product comparison agent: only Amazon + Walmart
product_tools = make_agent_tools(['product_research'])
print('Product agent tools:', [t['function']['name'] for t in product_tools])
# Research agent: news + technical + sentiment
research_tools = make_agent_tools(['news', 'technical', 'sentiment'])
print('Research agent tools:', [t['function']['name'] for t in research_tools])步骤 4: 添加范围验证和成本跟踪
验证每个搜索请求是否都在范围内。跟踪每个范围的成本以确定哪些访问模式成本最高。
class ScopedSearchManager:
def __init__(self, allowed_scopes: list[str]):
self.allowed_scopes = set(allowed_scopes)
self.usage = {s: {'calls': 0, 'results': 0} for s in allowed_scopes}
def search(self, query: str, scope: str) -> list:
if scope not in self.allowed_scopes:
raise PermissionError(
f'Scope "{scope}" not allowed. Allowed: {self.allowed_scopes}')
results = scoped_search(query, scope)
self.usage[scope]['calls'] += 1
self.usage[scope]['results'] += len(results)
return results
def report(self) -> str:
lines = ['Scope Usage Report:', '-' * 40]
total_cost = 0
for scope, stats in self.usage.items():
cost = stats['calls'] * 0.005
total_cost += cost
lines.append(f'{scope}: {stats["calls"]} calls, '
f'{stats["results"]} results, ${cost:.3f}')
lines.append(f'Total cost: ${total_cost:.3f}')
return '\n'.join(lines)
# Product comparison agent: restricted scope
agent = ScopedSearchManager(['product_research', 'sentiment'])
results = agent.search('Sony WH-1000XM6', 'product_research')
results = agent.search('Sony WH-1000XM6 review', 'sentiment')
print(agent.report())
# This would raise PermissionError:
# agent.search('sony stock price', 'news')步骤 5: 实施动态范围升级
有时代理需要更广泛的范围。添加受控升级机制,记录范围更改并需要明确批准。
class EscalatableScopedSearch(ScopedSearchManager):
def __init__(self, allowed_scopes, escalation_scopes=None):
super().__init__(allowed_scopes)
self.escalation_scopes = set(escalation_scopes or [])
self.escalation_log = []
def request_escalation(self, scope: str, reason: str) -> bool:
"""Request access to a scope outside the default set."""
if scope not in self.escalation_scopes:
print(f'Escalation denied: {scope} not in escalation list')
return False
self.allowed_scopes.add(scope)
self.usage[scope] = {'calls': 0, 'results': 0}
self.escalation_log.append({'scope': scope, 'reason': reason})
print(f'Escalation approved: {scope} ({reason})')
return True
# Agent starts with product scope only
agent = EscalatableScopedSearch(
allowed_scopes=['product_research'],
escalation_scopes=['sentiment', 'news']
)
# Normal search works
results = agent.search('laptop 2026', 'product_research')
print(f'Product search: {len(results)} results')
# Escalate to sentiment when needed
agent.request_escalation('sentiment', 'User asked about community opinions')
results = agent.search('laptop 2026 reddit opinions', 'sentiment')
print(f'Sentiment search: {len(results)} results')
print(f'Escalations: {agent.escalation_log}')Python 示例
import os, requests
SCAVIO_KEY = os.environ['SCAVIO_API_KEY']
URL = 'https://api.scavio.dev/api/v1/search'
H = {'x-api-key': SCAVIO_KEY, 'Content-Type': 'application/json'}
SCOPES = {
'product': {'sites': ['amazon.com', 'walmart.com'], 'num': 5},
'opinion': {'sites': ['reddit.com'], 'num': 8},
'tech': {'sites': ['stackoverflow.com', 'github.com'], 'num': 5},
}
def scoped_search(query, scope='product'):
cfg = SCOPES[scope]
results = []
for site in cfg['sites']:
resp = requests.post(URL, headers=H,
json={'query': f'site:{site} {query}', 'country_code': 'us', 'num_results': 3})
results.extend(resp.json().get('organic_results', []))
return [{'title': r['title'], 'url': r['link']} for r in results[:cfg['num']]]
for scope in ['product', 'opinion']:
results = scoped_search('mechanical keyboard', scope)
print(f'{scope}: {len(results)} results')JavaScript 示例
const SCAVIO_KEY = process.env.SCAVIO_API_KEY;
const URL = 'https://api.scavio.dev/api/v1/search';
const SCOPES = {
product: { sites: ['amazon.com', 'walmart.com'], num: 5 },
opinion: { sites: ['reddit.com'], num: 8 },
tech: { sites: ['stackoverflow.com', 'github.com'], num: 5 },
};
async function scopedSearch(query, scope = 'product') {
const cfg = SCOPES[scope];
const results = [];
for (const site of cfg.sites) {
const resp = await fetch(URL, {
method: 'POST',
headers: { 'x-api-key': SCAVIO_KEY, 'Content-Type': 'application/json' },
body: JSON.stringify({ query: `site:${site} ${query}`, country_code: 'us', num_results: 3 })
});
results.push(...((await resp.json()).organic_results || []));
}
return results.slice(0, cfg.num).map(r => ({ title: r.title, url: r.link }));
}
(async () => {
for (const scope of ['product', 'opinion']) {
const results = await scopedSearch('mechanical keyboard', scope);
console.log(`${scope}: ${results.length} results`);
}
})();预期输出
Product scope: 5 results
[amazon] Sony WH-1000XM6 Wireless Noise Cancelling Headphones
[walmart] Sony WH-1000XM6 - Best Price Guarantee
Scope Usage Report:
----------------------------------------
product_research: 1 calls, 5 results, $0.005
sentiment: 1 calls, 8 results, $0.005
Total cost: $0.010
Escalation approved: sentiment (User asked about community opinions)