AS AgentScopeAPI 手册 / API Reference
MISSION 01 · Scout · 160 XP

侦察兵Research Scout

给模型装上工具和结构化输出Give the model tools and typed output

类比Analog Perplexity / Deep ResearchPerplexity / Deep Research 技能Skills 工具系统Tool system模型抽象Model abstractionAgent 运行时Agent runtime权限与沙箱Permissions & sandbox生产意识Production readiness

任务简报Brief

研究员让 Agent 查本地资料库、把结论写成简报并返回严格 JSON。下游系统只接受 ResearchBrief,不接受“看起来差不多”的文本。

A researcher asks an agent to search a local corpus, write a brief and return strict JSON. The downstream system accepts ResearchBrief, not free-form text that looks close enough.

只会聊天的模型无法改变世界;能调用工具的模型才可以。这一关把“工具”与“结构化输出”放在一起练:模型先决定调用哪个工具、传什么参数,再读取工具结果,最后用 generate_response 把答案压进 schema。你会亲眼看到 schema 如何同时约束模型和下游代码。

A model that only chats cannot change the world; one that calls tools can. This mission pairs tools with structured output: the model chooses a tool and arguments, reads the result, then uses generate_response to squeeze the answer into a schema. You will see how one schema constrains both the model and downstream code.

学习目标Learning goals

  • 用 FunctionTool / @Tool 暴露 search_notes 与 save_brief。

    Expose search_notes and save_brief with FunctionTool / @Tool.

  • 让模型在一次 ReAct 循环里连续调用两个工具。

    Let the model call two tools in one ReAct loop.

  • 用 Pydantic / record 接收结构化结果,并验证字段。

    Receive and validate structured output with Pydantic / a record.

  • 确保工具真的产生了副作用文件,而不是只返回一句话。

    Ensure the tool actually writes its artifact instead of only returning text.

核心概念Core concepts

ToolUseBlock / ToolResultBlock

模型发出的调用意图与工具返回结果;它们是消息内容的一部分,而不是隐藏状态。

The model's call intent and the tool's result; both are message content, not hidden state.

agentscope.message.ToolUseBlockio.agentscope.core.message.ToolUseBlock

Structured output

强制最终答案符合 schema;Python 用 structured_schema,Java 用 call(..., Type.class)。

Forces the final answer to match a schema; Python uses structured_schema, Java uses call(..., Type.class).

双轨实现Build it twice

先完整跑通一条轨道,再切换重来。两条轨道写出同一种产物,方便直接对照行为。Run one track end to end, then switch and repeat. Both tracks write the same artifact so you can compare behavior directly.

当前轨道Current track
Python 2.0.11 轨道Track

工具函数用 Google 风格 docstring 描述参数与返回值;参数类型注解会被转换成 JSON Schema。不需要手写 schema。

Describe tool parameters and returns in a Google-style docstring; type hints become JSON Schema. No hand-written schema required.

01

声明工具并注册Declare and register tools

只读工具建议标记 is_read_only=True,权限引擎和 UI 都能据此做更安全的决策。

Mark read-only tools with is_read_only=True; the permission engine and UI can make safer decisions.

lab/missions/m1_researcher/mission.py
from agentscope.tool import FunctionTool, Toolkit
from common.tools import save_brief, search_notes

toolkit = Toolkit(
    tools=[
        FunctionTool(search_notes, permission=LAB_ALLOW, is_read_only=True),
        FunctionTool(save_brief, permission=LAB_ALLOW),
    ],
)
02

定义结构化结果Define the structured result

Pydantic 模型既约束模型输出,也约束下游代码。Field(ge=0, le=1) 这种约束会在校验时生效。

The Pydantic model constrains both model output and downstream code. Constraints such as Field(ge=0, le=1) are enforced during validation.

lab/missions/m1_researcher/mission.py
from pydantic import BaseModel, Field

class ResearchBrief(BaseModel):
    title: str = Field(description="Short title of the brief")
    findings: list[str] = Field(description="Concrete findings")
    confidence: float = Field(ge=0, le=1)

reply = await agent.reply(
    UserMsg("user", "Research ReAct guardrails and save a brief."),
    structured_schema=ResearchBrief,
)
print(reply.structured_output)  # dict, already validated
03

检查副作用Check the side effect

check 不只看回复文本,还读取 lab/work/m1/brief.json,确认工具真的落盘了三段 findings。

The check does not stop at reply text; it reads lab/work/m1/brief.json and confirms three findings were persisted.

shell
python lab.py check m1
cat work/m1/brief.json

# 期望看到
# PASS CODE: AS-M1-K2VD
运行判题Run the check
python lab.py check m1

search_notes 是本地关键词检索,不依赖网络;save_brief 写入 lab/work/m1/,两个轨道共用同一个产物路径。

search_notes is local keyword search with no network; save_brief writes into lab/work/m1/, shared by both tracks.

源码Source lab/missions/m1_researcher/mission.py

判题证明了什么What the check proves

  • Toolkit 暴露了 search_notes 与 save_brief 的 schemaToolkit exposed schemas for search_notes and save_brief
  • Agent 在一次 ReAct 循环里执行了两个工具The agent executed two tools inside one ReAct loop
  • 结构化输出通过了 ResearchBrief 校验Structured output passed the ResearchBrief schema
  • brief.json 已由工具真实写入brief.json was really written by the tool
Java 2.0.4 轨道Track

Java 用 @Tool / @ToolParam 注解把方法注册进 Toolkit。参数类型必须是 Jackson 可序列化的类型;List<String>、Double 这类都没问题。

Java registers methods through @Tool / @ToolParam. Parameters must be Jackson-serializable; List<String> and Double are fine.

01

用注解声明工具Declare tools with annotations

required=false 对应可选参数;schema 会生成默认值信息。readOnly=true 是给权限引擎和 UI 的语义标记。

required=false marks optional parameters; readOnly=true is a semantic hint for the permission engine and UI.

lab/java/src/main/java/lab/m1/M1Researcher.java
public final class BriefTools {
  @Tool(name = "search_notes", readOnly = true,
        description = "Search the local research corpus.")
  public String searchNotes(
      @ToolParam(name = "query") String query,
      @ToolParam(name = "limit", required = false) Integer limit) { ... }

  @Tool(name = "save_brief", description = "Save a research brief.")
  public String saveBrief(
      @ToolParam(name = "title") String title,
      @ToolParam(name = "findings") List<String> findings,
      @ToolParam(name = "confidence", required = false) Double confidence) { ... }
}
02

注册并请求结构化结果Register and request typed output

call(..., ResearchBrief.class, context) 会让 ReActAgent 自动加上 generate_response 工具;最终结果在 Msg 元数据的 _structured_output 里。

call(..., ResearchBrief.class, context) makes ReActAgent add a generate_response tool; the result lands in the _structured_output metadata of the Msg.

lab/java/src/main/java/lab/m1/M1Researcher.java
Toolkit toolkit = new Toolkit();
toolkit.registerTool(new BriefTools());

ReActAgent agent = ReActAgent.builder()
        .name("scout").sysPrompt("Search, save a brief, return typed output.")
        .model(model).toolkit(toolkit).maxIters(6)
        .permissionContext(PermissionContextState.builder()
                .mode(PermissionMode.BYPASS).build())
        .build();

Msg reply = agent.call(List.of(LabSupport.user("Research ReAct guardrails.")),
        ResearchBrief.class, context).block();
03

编译并判题Compile and check

检查会验证 schema 名称、三条 findings、confidence 范围和 brief.json。如果工具结果报错,先看回复里是不是出现了 “Tool not found”。

The check validates schema names, three findings, the confidence range and brief.json. If a tool fails, look for “Tool not found” in the reply.

shell
cd lab/java
mvn -q -o compile exec:java -Dexec.args="check m1"

# 期望看到
# PASS CODE: AS-M1-K2VD
运行判题Run the check
cd lab/java && mvn -q -o compile exec:java -Dexec.args="check m1"

Java 的 ToolExecutor 从 ToolUseBlock.getContent() 读取并校验参数;自写 FakeChatModel 脚本时要保证 input 与 content 一致。

Java's ToolExecutor validates from ToolUseBlock.getContent(); when scripting a FakeChatModel, keep input and content consistent.

源码Source lab/java/src/main/java/lab/m1/M1Researcher.java

判题证明了什么What the check proves

  • Toolkit 暴露了注解工具 schemaToolkit exposed annotated tool schemas
  • Agent 在 ReAct 循环里执行了搜索与保存The agent searched and saved inside the ReAct loop
  • 结构化输出绑定到 ResearchBriefStructured output bound to ResearchBrief
  • brief.json 已持久化brief.json persisted

Python ↔ Java 差异Python ↔ Java differences

  • Python 从 docstring/类型注解推导 schema;Java 用 @Tool / @ToolParam 显式描述。两边最终都变成模型可读的 JSON Schema。

    Python derives schema from docstrings/type hints; Java uses @Tool / @ToolParam. Both end up as model-readable JSON Schema.

  • Python 返回 reply.structured_output 字典;Java 从 Msg.getMetadata().get("_structured_output") 取 Map,再转换成 record。

    Python returns a structured_output dict; Java reads _structured_output from Msg metadata and converts it to a record.

  • Java 的结构化输出依赖内置工具 generate_response;调试时如果模型没调用它,回复会是普通文本。

    Java structured output relies on the built-in generate_response tool; if the model skips it, you get plain text.

常见坑Pitfalls

  1. 工具参数类型不是 JSON 可序列化的:例如自定义对象没有无参构造/序列化器。保持参数为字符串、数字、布尔、列表和简单 Map。

    Non-JSON-serializable tool parameters break schema generation. Keep parameters to strings, numbers, booleans, lists and simple maps.

  2. 只检查文本回复:工具可能返回 Error 但模型仍然礼貌地回答。必须读取 ToolResultBlock 的状态与内容。

    Checking only reply text: a tool may return an Error while the model still answers politely. Inspect the ToolResultBlock state and content.

  3. 把 confidence 当成模型自觉:它只是字段。生产环境要用外部校验、置信度阈值或人工复核。

    Treating confidence as self-awareness: it is only a field. Production needs external validation, thresholds or human review.

领取通行码Claim your pass code

先运行当前轨道的 check。CLI 会打印 PASS CODE、XP 与徽章。粘贴到这里;同一关在每条轨道可各领取一次。Run the check for the current track. The CLI prints PASS CODE plus the exact XP and badge. Paste it here; the same mission can be claimed once on each track.

记录到轨道Record on track

费曼复述Feynman recall

合上教程,用自己的话讲清机制。关键点覆盖 65%、篇幅 20%、结构 15%;60 分通过并一次性获得 20 XP。Explain the mechanism without looking. Coverage 65%, length 20%, structure 15%; 60 passes and earns +20 XP once.

为什么需要 Toolkit 和结构化输出?模型调用工具的一轮里,消息是怎样流动的?

Why do we need Toolkit and structured output? How do messages flow during one tool-calling turn?

0 chars

查看参考答案Show the model answer

Toolkit 把函数签名变成模型能理解的 schema,让模型知道有哪些工具、参数怎么填;工具调用与结果作为消息块进入上下文,模型据此继续推理。结构化输出再把最终答案约束成固定字段,避免下游解析自由文本。一次回合里,消息依次是:系统提示 → 用户消息 → 工具调用 → 工具结果 → 最终结构化结果。

Toolkit turns signatures into schemas the model can understand, so it knows which tools exist and how to fill their arguments. Tool calls and results enter the context as message blocks, and the model continues reasoning from them. Structured output then constrains the final answer to fixed fields, so downstream code does not parse free text. One turn flows as system prompt → user message → tool call → tool result → final structured result.

间隔复习Spaced review

首次领取后会在明天安排复习。按真实感受评分,下一次间隔会自适应。After the first claim a review is scheduled for tomorrow. Rate how it felt; the next interval adapts.

领取通行码后会自动安排第一次复习。Claim the pass code to schedule your first review.
基于官方固定版本源码静态生成Generated from pinned official sources · Python 2.0.11 · Java 2.0.4
签名与文档为静态抽取;如有疑问请以源码为准。Signatures and docs are extracted statically; verify against the source when in doubt.