跳转到主要内容
通过 Olostep 的 /v1/monitors 端点,你可以创建在固定时间表上运行的持久监控器,检测页面变化,并通过电子邮件、Slack、短信或专用的 webhook 通知你。
  • 从自然语言 query 创建监控器
  • 使用 source_policy 限制来源
  • 在自然语言时间表上运行检查(最小每 10 分钟一次,UTC)
  • 配置 notification.channels 和可选的 webhook 传递
  • 使用服务器发送事件(?stream=1)流式传输配置进度
  • 列出、检查、更新、暂停、恢复和删除监控器
  • 读取快照事件、计划工件、运行日志和实时代理日志
默认情况下,每次监控器运行都会捕获被监控页面的完整快照——即该时刻其当前状态的完整图景。如果你希望监控器仅显示运行之间的新内容或变化(增量)而不是完整状态,请在 query 中表达这一意图。

安装

# pip install requests

import requests

创建监控器

使用 POST /v1/monitors 创建监控器。API 验证你的输入,保留一个监控器记录,配置一个影子代理,生成一个工作流规范,排队 DAG 计划,并创建一个重复的时间表。
  • query 是必需的——用自然语言描述要监控的内容。
  • frequency 是可选的,默认为 every hour。使用诸如 every day at 9am 的调度短语(调度在 UTC 中运行;最小间隔为 10 分钟)。
  • source_policy 可选地限制 include_urlsexclude_urlsinclude_domainsexclude_domains
  • notification 配置何时以及如何提醒(events + channels)。频道传递在运行时由监控器管道解析——你无需将接收者传递到 DAG。
  • webhook 是一个单独的对象({ "url": "https://…" }),用于 HTTP 回调,除了 notification.channels 之外。
  • output_schema 可选地强制执行结构化提取(有效的 JSON Schema)。
创建响应为 HTTP 202,状态为 provisioning。监控器在计划解决 tracked 目标后转为 active。轮询 GET /v1/monitors/:monitor_id 或传递 ?stream=1(或 Accept: text/event-stream)以通过 SSE 跟踪配置阶段和规范推理令牌。

示例请求

你只需要 queryfrequency。通知频道和 webhooks 可以稍后通过 POST /v1/monitors/:monitor_id 添加。
import requests
import json

API_KEY = "<YOUR_API_KEY>"
API_URL = "https://api.olostep.com/v1"

payload = {
    "query": "当 Y Combinator Launches 上有新创业公司发布时通知我",
    "frequency": "every 20 minutes",
}

headers = {
    "Authorization": f"Bearer {API_KEY}",
    "Content-Type": "application/json",
}

response = requests.post(f"{API_URL}/monitors", headers=headers, json=payload)
print(response.status_code)
print(json.dumps(response.json(), indent=2))

响应

成功创建(非流式)返回 HTTP 202 和一个监控器对象。在计划完成之前,tracked 是空的;轮询 GET /v1/monitors/:monitor_id 直到 statusactive 并且 tracked.urls 被填充。
{
  "id": "monitor_biglavgvq3",
  "object": "monitor",
  "query": "当 Y Combinator Launches 上有新创业公司发布时通知我",
  "tracked": {
    "type": null,
    "urls": [],
    "web_query": null
  },
  "source_policy": {},
  "schedule": {
    "frequency": "every 20 minutes",
    "cron": "7/20 * * * ? *",
    "timezone": "UTC",
    "next_run_at": null
  },
  "notification": {
    "events": [],
    "channels": []
  },
  "webhook": null,
  "output_schema": {},
  "status": "provisioning",
  "error_message": null,
  "last_run": null,
  "agent": {
    "id": "agent_forward_deployed_0_fda_nlkxhr5kto"
  },
  "metadata": {},
  "created": 1780063068,
  "updated": 1780063071
}

结构化监控器输出

当你希望提取结果遵循特定的 JSON 结构时,设置 output_schema。该模式必须是有效的 JSON Schema。

配置流

添加 ?stream=1 或发送 Accept: text/event-stream 以在创建监控器时接收 SSE 事件:
事件描述
phase配置步骤(runningdonefailed
reasoning_token增量规范设计文本
reasoning_reset在 LLM 尝试失败后截断缓冲的推理
complete最终监控器对象(与 202 响应相同的形状)
error终端失败

通知和 webhooks

警报在监控器记录上配置,并在运行时解析——不要在监控 query 中嵌入频道目标。

notification

字段描述
events哪些运行结果应触发传递。请参阅下面的通知事件。如果你设置了 channels 并省略了 events,则默认为 changedfirst_snapshot
channels{ "type", "target", "events"? } 对象列表

通知事件

使用 events 来说明你希望何时收到通知。允许的值:
事件含义
changed当监控器检测到与前一个快照相比的变化时通知(例如新内容、更新价格或管道分类为已更改的差异)。
first_snapshot当监控器拍摄其第一次快照时通知——存储当前内容的初始基线运行,以便以后进行比较。
你可以包含一个或两个。例如,["changed"] 仅在基线之后的更新时提醒;["first_snapshot"] 确认设置而无需等待差异;["changed", "first_snapshot"] 覆盖两者。 频道对象上的每个频道 events 使用相同的值,并仅为该频道覆盖顶级列表。 支持的频道类型:
typetarget 格式
email有效的电子邮件地址
slackSlack 入站 webhook URL
smsE.164 电话号码(例如 +14155552671

webhook

notification.channels 分开,webhook.url 在监控器触发你的回调 URL 时接收 HTTP POST 负载。你可以在同一个监控器上同时使用 webhook 和频道通知。

示例

仅电子邮件:
{
  "query": "监控 https://example.com/terms 上的变化",
  "frequency": "every day at 10am",
  "notification": {
    "events": ["changed"],
    "channels": [
      { "type": "email", "target": "legal@example.com" }
    ]
  }
}
Webhook 回调:
{
  "query": "监控 https://example.com/terms 上的变化",
  "frequency": "every day at 10am",
  "webhook": {
    "url": "https://hooks.example.com/olostep-monitor"
  }
}
短信:
{
  "query": "当 https://status.example.com 显示事件时提醒我",
  "frequency": "every hour",
  "notification": {
    "channels": [
      { "type": "sms", "target": "+14155552671" }
    ]
  }
}

来源策略

使用 source_policy 来限制计划者可以使用的 URL 和域。
{
  "source_policy": {
    "include_urls": ["https://example.com/pricing"],
    "exclude_domains": ["ads.example.com"]
  }
}

频率

以自然语言设置 frequency,例如:
  • every hour(省略时的默认值)
  • every day at 9am
  • every weekday at 14:30
规则:
  • 必须读作调度语言(而不是任意的监控问题)。
  • 最小间隔:每 10 分钟
  • 调度存储并在 UTC 中执行(schedule.timezoneUTC)。
  • 最大长度:50 个字符。
API 从你的 frequency 文本中派生出一个 cron 表达式,并在 schedule.cron 上暴露出来。当监控器为 active 时,schedule.next_run_at 显示 ISO 8601 格式的下一次运行。

列出监控器

使用 GET /v1/monitors 检索你的团队的所有监控器。 默认情况下,已删除的监控器被过滤掉。使用 ?include_deleted=true 来包含它们。
import requests
import json

API_KEY = "<YOUR_API_KEY>"
API_URL = "https://api.olostep.com/v1"

headers = { "Authorization": f"Bearer {API_KEY}" }

response = requests.get(f"{API_URL}/monitors", headers=headers)
result = response.json()
print(f"Total monitors: {result['count']}")
print(json.dumps(result, indent=2))

响应形状

{
  "monitors": [
    {
      "id": "monitor_0wj35czpn7",
      "object": "monitor",
      "query": "监控 AirOps 博客的新博文",
      "tracked": {
        "type": "urls",
        "urls": ["https://www.airops.com/blog"],
        "web_query": null
      },
      "source_policy": {},
      "schedule": {
        "frequency": "every hour",
        "cron": "2 * * * ? *",
        "timezone": "UTC",
        "next_run_at": null
      },
      "notification": {
        "channels": [],
        "events": []
      },
      "webhook": null,
      "output_schema": {},
      "status": "paused",
      "error_message": null,
      "last_run": null,
      "agent": { "id": "agent_forward_deployed_0_fda_x4822l9h3i" },
      "metadata": {},
      "created": 1780062756,
      "updated": 1780063025
    },
    {
      "id": "monitor_biglavgvq3",
      "object": "monitor",
      "query": "当 Y Combinator Launches 上有新创业公司发布时通知我",
      "tracked": {
        "type": "urls",
        "urls": ["https://www.ycombinator.com/launches/"],
        "web_query": null
      },
      "source_policy": {},
      "schedule": {
        "frequency": "every 20 minutes",
        "cron": "7/20 * * * ? *",
        "timezone": "UTC",
        "next_run_at": "2026-05-29T14:27:00.000Z"
      },
      "notification": {
        "channels": [],
        "events": []
      },
      "webhook": null,
      "output_schema": {},
      "status": "active",
      "error_message": null,
      "last_run": null,
      "agent": { "id": "agent_forward_deployed_0_fda_nlkxhr5kto" },
      "metadata": {},
      "created": 1780063068,
      "updated": 1780063141
    }
  ],
  "count": 5
}

获取监控器

使用 GET /v1/monitors/:monitor_id 检索单个监控器。 响应包括 last_run(最新快照摘要)和 total_count(快照计数),除非你传递 include_total_count=false。添加 include-diagram=true 以包含监控器 DAG 的 mermaid_diagram
import requests
import json

API_KEY = "<YOUR_API_KEY>"
API_URL = "https://api.olostep.com/v1"
MONITOR_ID = "monitor_biglavgvq3"

headers = { "Authorization": f"Bearer {API_KEY}" }

response = requests.get(f"{API_URL}/monitors/{MONITOR_ID}", headers=headers)
print(json.dumps(response.json(), indent=2))

响应形状

{
  "id": "monitor_biglavgvq3",
  "object": "monitor",
  "query": "当 Y Combinator Launches 上有新创业公司发布时通知我",
  "tracked": {
    "type": "urls",
    "urls": ["https://www.ycombinator.com/launches/"],
    "web_query": null
  },
  "source_policy": {},
  "schedule": {
    "frequency": "every 20 minutes",
    "cron": "7/20 * * * ? *",
    "timezone": "UTC",
    "next_run_at": "2026-05-29T14:27:00.000Z"
  },
  "notification": {
    "channels": [],
    "events": []
  },
  "webhook": null,
  "output_schema": {},
  "status": "active",
  "error_message": null,
  "last_run": {
    "id": "run_iwsoafcpyx",
    "status": "completed",
    "change_detected": false,
    "ran_at": "2026-05-29T14:03:15.963Z"
  },
  "agent": {
    "id": "agent_forward_deployed_0_fda_nlkxhr5kto"
  },
  "metadata": {},
  "created": 1780063068,
  "updated": 1780063141,
  "total_count": 1
}

列出监控器事件

使用 GET /v1/monitors/:monitor_id/events 列出监控器的快照事件。 分页:
  • limit(默认 25,最大 100
  • cursor(来自 next_cursor 的不透明令牌)
  • count_only=true 仅返回 { "total_count": N }
事件按最新优先返回。每个项目包括一个短期有效的预签名 snapshot_url
import requests
import json

API_KEY = "<YOUR_API_KEY>"
API_URL = "https://api.olostep.com/v1"
MONITOR_ID = "monitor_biglavgvq3"

headers = { "Authorization": f"Bearer {API_KEY}" }

response = requests.get(
    f"{API_URL}/monitors/{MONITOR_ID}/events?limit=10",
    headers=headers,
)
print(json.dumps(response.json(), indent=2))

响应形状

{
  "data": [
    {
      "id": "run_iwsoafcpyx",
      "run_id": "run_iwsoafcpyx",
      "created": 1780063395,
      "changed": false,
      "summary": "已拍摄此监控器的第一次快照。将当前内容存储为基线。",
      "snapshot_url": "https://olostep-monitor-snapshots.s3.amazonaws.com/monitor_biglavgvq3/run_iwsoafcpyx_snapshot.json?X-Amz-Expires=600&..."
    }
  ],
  "has_more": false,
  "next_cursor": null,
  "total_count": 1
}

获取监控器计划

使用 GET /v1/monitors/:monitor_id/planning 检查 FDA 工作流规范和计划 DAG 在配置后的状态。
{
  "spec": {
    "saved_at": "2026-05-29T12:00:00.000000+00:00",
    "status": "complete",
    "goal": "跟踪 example.com 上的定价",
    "reasoning": "...",
    "constraints": "...",
    "assumptions": "...",
    "input": { "query": "...", "urls": ["https://www.ycombinator.com/launches/"] },
    "output": { "type": "free_text" },
    "chat_history": []
  },
  "dag": {
    "user_query": "...",
    "graph": { "nodes": [], "edges": [] },
    "has_unresolved": false,
    "unresolved": [],
    "validation": { "is_valid": true, "attempts": 1, "history": [] }
  }
}

获取监控器运行

使用 GET /v1/monitors/:monitor_id/runs/:run_id 获取一次执行的快照元数据和解析的代理日志事件(run_id 必须以 run_ 开头)。
{
  "monitor_id": "monitor_biglavgvq3",
  "run_id": "run_v7k2p9m3",
  "snapshot": { "changed": true, "summary": "..." },
  "log_group": "/aws/ecs/olostep-agents/...",
  "events": [
    {
      "id": "...",
      "ts": 1777960800123,
      "message": "运行 run_v7k2p9m3 完成。上传文件:2",
      "event": { "type": "run_complete", "run_id": "run_v7k2p9m3", "files_uploaded": 2 }
    }
  ]
}

流式代理日志

使用 GET /v1/monitors/:monitor_id/agent-logs?stream=1(或 Accept: text/event-stream)来跟踪监控器代理的 CloudWatch 日志,过滤到此 monitor_id 可选查询参数 since 是一个毫秒时间戳(默认:30 分钟前)。 SSE 事件类型:readylogheartbeaterror

更新监控器

使用 POST /v1/monitors/:monitor_id 更新监控器。 支持的字段(仅包含你想更改的内容):
  • metadata — 与现有键合并;空字符串值删除键
  • frequency — 重新创建内部时间表并将 status 设置回 active
  • notification — 替换整个通知对象
  • webhook — 传递 null 以移除
statusprovisioning 时返回 409 当你添加 notification.channels 而没有 events 时,API 默认 events["changed", "first_snapshot"]

添加电子邮件通知

import requests
import json

API_KEY = "<YOUR_API_KEY>"
API_URL = "https://api.olostep.com/v1"
MONITOR_ID = "monitor_biglavgvq3"

payload = {
    "notification": {
        "channels": [
            {"type": "email", "target": "you@example.com"}
        ]
    }
}

headers = {
    "Authorization": f"Bearer {API_KEY}",
    "Content-Type": "application/json",
}

response = requests.post(
    f"{API_URL}/monitors/{MONITOR_ID}",
    headers=headers,
    json=payload,
)
print(json.dumps(response.json(), indent=2))
{
  "id": "monitor_biglavgvq3",
  "object": "monitor",
  "query": "当 Y Combinator Launches 上有新创业公司发布时通知我",
  "tracked": {
    "type": "urls",
    "urls": ["https://www.ycombinator.com/launches/"],
    "web_query": null
  },
  "source_policy": {},
  "schedule": {
    "frequency": "every 20 minutes",
    "cron": "7/20 * * * ? *",
    "timezone": "UTC",
    "next_run_at": "2026-05-29T14:27:00.000Z"
  },
  "notification": {
    "events": ["changed", "first_snapshot"],
    "channels": [
      { "type": "email", "target": "you@example.com" }
    ]
  },
  "webhook": null,
  "output_schema": {},
  "status": "active",
  "error_message": null,
  "last_run": null,
  "agent": { "id": "agent_forward_deployed_0_fda_nlkxhr5kto" },
  "metadata": {},
  "created": 1780063068,
  "updated": 1780064634
}

添加 webhook

import requests
import json

API_KEY = "<YOUR_API_KEY>"
API_URL = "https://api.olostep.com/v1"
MONITOR_ID = "monitor_biglavgvq3"

payload = {
    "webhook": { "url": "https://webhook.site/your-unique-id" }
}

headers = {
    "Authorization": f"Bearer {API_KEY}",
    "Content-Type": "application/json",
}

response = requests.post(
    f"{API_URL}/monitors/{MONITOR_ID}",
    headers=headers,
    json=payload,
)
print(json.dumps(response.json(), indent=2))
{
  "id": "monitor_biglavgvq3",
  "object": "monitor",
  "query": "当 Y Combinator Launches 上有新创业公司发布时通知我",
  "tracked": {
    "type": "urls",
    "urls": ["https://www.ycombinator.com/launches/"],
    "web_query": null
  },
  "source_policy": {},
  "schedule": {
    "frequency": "every 20 minutes",
    "cron": "7/20 * * * ? *",
    "timezone": "UTC",
    "next_run_at": "2026-05-29T14:47:00.000Z"
  },
  "notification": {
    "channels": [
      { "type": "email", "target": "you@example.com" }
    ],
    "events": ["changed", "first_snapshot"]
  },
  "webhook": {
    "url": "https://webhook.site/your-unique-id"
  },
  "output_schema": {},
  "status": "active",
  "error_message": null,
  "last_run": null,
  "agent": { "id": "agent_forward_deployed_0_fda_nlkxhr5kto" },
  "metadata": {},
  "created": 1780063068,
  "updated": 1780065538
}

暂停监控器

使用 POST /v1/monitors/:monitor_id/pause 暂停监控器。 暂停会禁用底层时间表并将 status 设置为 paused。只有 status: active 的监控器可以暂停。请求体为空。
import requests
import json

API_KEY = "<YOUR_API_KEY>"
API_URL = "https://api.olostep.com/v1"
MONITOR_ID = "monitor_biglavgvq3"

response = requests.post(
    f"{API_URL}/monitors/{MONITOR_ID}/pause",
    headers={ "Authorization": f"Bearer {API_KEY}" },
)
print(response.status_code)
print(json.dumps(response.json(), indent=2))
成功时,返回 200 和监控器及 status: paused。暂停时,schedule.next_run_atnull

恢复监控器

使用 POST /v1/monitors/:monitor_id/resume 恢复暂停的监控器。 恢复会重新启用时间表并将 status 设置回 active。只有 paused 的监控器可以恢复。
import requests
import json

API_KEY = "<YOUR_API_KEY>"
API_URL = "https://api.olostep.com/v1"
MONITOR_ID = "monitor_biglavgvq3"

response = requests.post(
    f"{API_URL}/monitors/{MONITOR_ID}/resume",
    headers={ "Authorization": f"Bearer {API_KEY}" },
)
print(response.status_code)
print(json.dumps(response.json(), indent=2))

删除监控器

使用 DELETE /v1/monitors/:monitor_id 删除监控器。 删除会软删除监控器行(status: deleted)并移除其时间表和影子代理资源。
import requests
import json

API_KEY = "<YOUR_API_KEY>"
API_URL = "https://api.olostep.com/v1"
MONITOR_ID = "monitor_biglavgvq3"

response = requests.delete(
    f"{API_URL}/monitors/{MONITOR_ID}",
    headers={ "Authorization": f"Bearer {API_KEY}" },
)
print(json.dumps(response.json(), indent=2))

监控器状态

状态含义
provisioning代理、规范、计划者和时间表正在设置中
active时间表启用;运行在 schedule.frequency 上执行
paused通过 /pause 禁用时间表
failed配置或时间表更新失败(error_message 已设置)
deleted通过 DELETE 软删除

示例用例

以下是常见的监控器模式。每个示例在创建时只需要 queryfrequency;如果你想在第一次运行或变化时收到警报,可以稍后添加 notificationwebhook

Y Combinator 新发布

监控 Y Combinator Launches 上新发布的创业公司。在计划之后,tracked.typeurlstracked.urls 指向发布页面。
import requests

API_URL = "https://api.olostep.com/v1"
headers = {
    "Authorization": "Bearer <YOUR_API_KEY>",
    "Content-Type": "application/json",
}

requests.post(
    f"{API_URL}/monitors",
    headers=headers,
    json={
        "query": "当 Y Combinator Launches 上有新创业公司发布时通知我",
        "frequency": "every 20 minutes",
    },
)
在监控器 active 后添加电子邮件和 webhook 传递:
curl -s -X POST "https://api.olostep.com/v1/monitors/monitor_biglavgvq3" \
  -H "Authorization: Bearer $OLOSTEP_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "notification": {
      "channels": [{ "type": "email", "target": "you@example.com" }]
    },
    "webhook": { "url": "https://webhook.site/your-unique-id" }
  }'
设置了 channels 并省略了 events,API 默认为 ["changed", "first_snapshot"],因此你会在基线运行和检测到变化时收到通知。

竞争对手博客文章(AirOps,Profound)

监控竞争对手博客索引以获取新文章。计划者将 tracked.urls 解析为博客 URL(例如 https://www.airops.com/bloghttps://www.tryprofound.com/blog)。
curl -sS -X POST "https://api.olostep.com/v1/monitors" \
  -H "Authorization: Bearer $OLOSTEP_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "query": "监控 AirOps 博客的新博文",
    "frequency": "every hour"
  }'
创建后,此系列中的监控器看起来像:
{
  "id": "monitor_588ck513zd",
  "object": "monitor",
  "query": "监控 Profound 博客的新博文",
  "tracked": {
    "type": "urls",
    "urls": ["https://www.tryprofound.com/blog"],
    "web_query": null
  },
  "schedule": {
    "frequency": "every 20 minutes",
    "cron": "15/20 * * * ? *",
    "timezone": "UTC",
    "next_run_at": "2026-05-29T15:15:00.000Z"
  },
  "status": "active"
}
如果你只想在新文章出现时收到警报,而不是在第一次基线快照时,请在 notification 上使用 events: ["changed"]

股票价格阈值(特斯拉)

当条件是数字而不是页面差异时,监控结构化数据源。计划者将 tracked.type 设置为 data_api 并将 tracked.urls 留空。
curl -sS -X POST "https://api.olostep.com/v1/monitors" \
  -H "Authorization: Bearer $OLOSTEP_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "query": "当特斯拉股价跌破 436$ 时通知我",
    "frequency": "every 12 minutes"
  }'
{
  "id": "monitor_7609p3191t",
  "object": "monitor",
  "query": "当特斯拉股价跌破 436$ 时通知我",
  "tracked": {
    "type": "data_api",
    "urls": [],
    "web_query": null
  },
  "schedule": {
    "frequency": "every 12 minutes",
    "cron": "2/12 * * * ? *",
    "timezone": "UTC",
    "next_run_at": "2026-05-29T15:02:00.000Z"
  },
  "status": "active"
}

OpenAI API 更新日志

OpenAI 的 API 更新日志 列出新功能、模型发布或弃用时收到通知。在 query 中提到更新日志 URL 或使用 source_policy.include_urls 固定它。
curl -sS -X POST "https://api.olostep.com/v1/monitors" \
  -H "Authorization: Bearer $OLOSTEP_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "query": "当 OpenAI API 更新日志有新更新或功能时通知我 https://developers.openai.com/api/docs/changelog",
    "frequency": "every hour",
    "notification": {
      "events": ["changed"],
      "channels": [{ "type": "email", "target": "you@example.com" }]
    }
  }'
events 设置为 ["changed"],这样当更新日志内容发生变化时你会收到警报,而不仅仅是在存储第一次快照时。

管理多个监控器

列出你的团队的所有监控器,以便在一个地方查看状态、时间表和已解析的目标:
curl -s -X GET "https://api.olostep.com/v1/monitors" \
  -H "Authorization: Bearer $OLOSTEP_API_KEY"
运行上述示例的团队可能会看到几个监控器并排显示——不同节奏的博客监控、data_api 价格监控,以及配置了电子邮件和 webhook 的 YC 发布监控——响应中 "count": 4(或更多)。

常见验证错误

监控器端点为常见的无效请求返回明确的验证错误:
  • 缺少或空的 query
  • frequency 不是调度语言,解析过于频繁(低于 10 分钟)或超过 50 个字符
  • 无效的 source_policy 条目(URL 数组必须包含有效的 http/https 字符串)
  • 无效的 notification 形状,未知的 events,或无效的频道 type / target
  • 无效的 webhook.url(必须是 httphttps
  • 无效的 output_schema(必须是有效的 JSON Schema)
  • 无效的 monitor_idrun_id 格式
  • statusprovisioning 时更新(409
  • 当状态不是 active / paused 时暂停/恢复
示例错误:
{
  "error": "无法解释 'frequency': \"每秒检查一次\"。请使用调度语言,例如 \"every hour\"\"every day at 9am\"。"
}