MDAN MDAN Docs
官网

Agent 直接消费

MDAN 本来就是为了让 Agent 直接消费而设计的。

Agent 在使用 MDAN 应用之前,不需要先套一层无头浏览器、MCP 包装器,或者额外的运行时,才有办法继续一个可交互 Markdown 页面。

只要 Agent 能做到下面几件事:

它就可以自己继续交互。

Agent 在读取什么

Agent 通常会请求 Markdown:

Accept: text/markdown; profile="https://mdan.ai/spec/v1"

这时服务端返回的是一个 Markdown 页面或片段,其中已经包含:

这个响应不只是内容,而是下一步交互面本身。

Agent 在发送什么

对于写操作,Agent 发送的仍然是普通 HTTP 请求,请求体类型是:

Content-Type: text/markdown

这里的请求体不是任意自然语言,而是 MDAN 的直写 body 格式,例如:

nickname: "Ada", password: "pass-1234"

另一个例子:

message: "Private note from agent"

如果 body 不符合预期格式,服务端可以返回一个可恢复的错误结果。

最小消费循环

一个简单的 Agent 消费循环通常是这样:

  1. 用 Accept: text/markdown 去 GET 当前页面
  2. 读取返回的 Markdown,并找出当前可执行操作
  3. 选择下一步 operation
  4. 发送对应的 GET 或 POST
  5. 如果服务端设置了 session,就保存 cookie
  6. 基于返回的页面或片段继续下一步

这已经足够支撑很多真实应用流程。

示例:Auth Session

在 auth-session 例子里,Agent 可以这样工作:

  1. GET /login
  2. 发现 POST "/login" 和 GET "/register"
  3. 用下面的 body 执行 POST /register:
nickname: "HttpAgent", password: "pass-1234"
  1. 保存返回的 mdan_session cookie
  2. 再执行 POST /vault:
message: "Private note from agent"
  1. 最后执行 POST /vault/logout

关键在于,每一次响应都已经把“下一步能做什么”告诉 Agent 了。

示例:Agent Tasks

在 agent-tasks demo 里,一个 Agent 可以创建任务,另一个 Agent 可以直接接手并继续推进,整个过程都通过 MDAN 页面完成。

流程大致是:

  1. Agent A 注册并打开 /tasks
  2. Agent A 通过 POST /tasks 创建任务
  3. 返回页面里会出现:
POST "/tasks/task-1/accept" () -> accept
  1. Agent B 直接发送 POST /tasks/task-1/accept
  2. 返回结果里会出现:
POST "/tasks/task-1/submit" (result) -> submit
  1. Agent B 提交结果
  2. reviewer 会收到: POST "/tasks/task-1/request-revision" 和 POST "/tasks/task-1/complete"

这是一条直接通过 HTTP 完成的 handoff 流程,不需要浏览器自动化。

Agent 只需要像普通 HTTP 客户端一样保留 cookie。

这就足以支持下面这些流程:

也就是说,session 仍然留在普通 HTTP 语义里,不需要单独再发明一条 agent session 通道。

这说明了什么

直接消费很重要,因为它保证应用表面是统一的。

这也是为什么 MDAN 更像一种 agent-native interaction surface,而不只是渲染格式。

相关文档