模型

在本教程中,我们介绍 AgentScope 中集成的模型 API、如何使用它们,以及如何集成新的模型 API。 AgentScope 目前支持的模型 API 和模型提供商包括:

API

兼容

流式

工具

视觉

推理

OpenAI

OpenAIChatModel

vLLM, DeepSeek

DashScope

DashScopeChatModel

Anthropic

AnthropicChatModel

Gemini

GeminiChatModel

Ollama

OllamaChatModel

备注

当使用 vLLM 时,需要在部署时为不同模型配置相应的工具调用参数,例如 --enable-auto-tool-choice--tool-call-parser 等参数。更多详情请参考 vLLM 官方文档

备注

兼容 OpenAI API 的模型(例如 vLLM 部署的模型),推荐使用 OpenAIChatModel,并通过 client_kwargs={"base_url": "http://your-api-endpoint"} 参数指定 API 端点。例如:

OpenAIChatModel(client_kwargs={"base_url": "http://localhost:8000/v1"})

备注

模型的行为参数(如温度、最大长度等)可以通过 generate_kwargs 参数在构造函数中提前设定。例如:

OpenAIChatModel(generate_kwargs={"temperature": 0.3, "max_tokens": 1000})

为了提供统一的模型接口,上述所有类均被统一为:

  • __call__ 函数的前三个参数是 messagestoolstool_choice,分别是输入消息,工具函数的 JSON schema,以及工具选择的模式。

  • 非流式返回时,返回类型是 ChatResponse 实例;流式返回时,返回的是 ChatResponse 的异步生成器。

备注

不同的模型 API 在输入消息格式上有所不同,AgentScope 通过 formatter 模块处理消息的转换,请参考 format

ChatResponse 包含大模型生成的推理/文本/工具使用内容、身份、创建时间和使用信息。

import asyncio
import json
import os

from agentscope.message import TextBlock, ToolUseBlock, ThinkingBlock, Msg
from agentscope.model import ChatResponse, DashScopeChatModel

response = ChatResponse(
    content=[
        ThinkingBlock(
            type="thinking",
            thinking="我应该在 Google 上搜索 AgentScope。",
        ),
        TextBlock(type="text", text="我将在 Google 上搜索 AgentScope。"),
        ToolUseBlock(
            type="tool_use",
            id="642n298gjna",
            name="google_search",
            input={"query": "AgentScope"},
        ),
    ],
)

print(response)
ChatResponse(content=[{'type': 'thinking', 'thinking': '我应该在 Google 上搜索 AgentScope。'}, {'type': 'text', 'text': '我将在 Google 上搜索 AgentScope。'}, {'type': 'tool_use', 'id': '642n298gjna', 'name': 'google_search', 'input': {'query': 'AgentScope'}}], id='2026-01-28 04:23:23.020_468959', created_at='2026-01-28 04:23:23.020', type='chat', usage=None, metadata=None)

DashScopeChatModel 为例,调用和返回结果如下:

async def example_model_call() -> None:
    """使用 DashScopeChatModel 的示例。"""
    model = DashScopeChatModel(
        model_name="qwen-max",
        api_key=os.environ["DASHSCOPE_API_KEY"],
        stream=False,
    )

    res = await model(
        messages=[
            {"role": "user", "content": "你好!"},
        ],
    )

    # 您可以直接使用响应内容创建 ``Msg`` 对象
    msg_res = Msg("Friday", res.content, "assistant")

    print("LLM 返回结果:", res)
    print("作为 Msg 的响应:", msg_res)


asyncio.run(example_model_call())
LLM 返回结果: ChatResponse(content=[{'type': 'text', 'text': '你好!有什么可以帮助你的吗?'}], id='2026-01-28 04:23:25.782_37126d', created_at='2026-01-28 04:23:25.782', type='chat', usage=ChatUsage(input_tokens=10, output_tokens=7, time=2.761288, type='chat'), metadata=None)
作为 Msg 的响应: Msg(id='as2Am63NS2FuX6qagRJa5t', name='Friday', content=[{'type': 'text', 'text': '你好!有什么可以帮助你的吗?'}], role='assistant', metadata=None, timestamp='2026-01-28 04:23:25.782', invocation_id='None')

流式返回

要启用流式返回,请在模型的构造函数中将 stream 参数设置为 True。 流式返回中,__call__ 方法将返回一个 异步生成器,该生成器迭代返回 ChatResponse 实例。

备注

AgentScope 中的流式返回结果为 累加式,这意味着每个 chunk 中的内容包含所有之前的内容加上新生成的内容。

async def example_streaming() -> None:
    """使用流式模型的示例。"""
    model = DashScopeChatModel(
        model_name="qwen-max",
        api_key=os.environ["DASHSCOPE_API_KEY"],
        stream=True,
    )

    generator = await model(
        messages=[
            {
                "role": "user",
                "content": "从 1 数到 20,只报告数字,不要任何其他信息。",
            },
        ],
    )
    print("响应的类型:", type(generator))

    i = 0
    async for chunk in generator:
        print(f"块 {i}")
        print(f"\t类型: {type(chunk.content)}")
        print(f"\t{chunk}\n")
        i += 1


asyncio.run(example_streaming())
响应的类型: <class 'async_generator'>
块 0
        类型: <class 'list'>
        ChatResponse(content=[{'type': 'text', 'text': '1'}], id='2026-01-28 04:23:27.186_59d27f', created_at='2026-01-28 04:23:27.186', type='chat', usage=ChatUsage(input_tokens=26, output_tokens=1, time=1.402248, type='chat'), metadata=None)

块 1
        类型: <class 'list'>
        ChatResponse(content=[{'type': 'text', 'text': '1 2 '}], id='2026-01-28 04:23:27.276_8b87e7', created_at='2026-01-28 04:23:27.276', type='chat', usage=ChatUsage(input_tokens=26, output_tokens=4, time=1.491684, type='chat'), metadata=None)

块 2
        类型: <class 'list'>
        ChatResponse(content=[{'type': 'text', 'text': '1 2 3 4'}], id='2026-01-28 04:23:28.297_102675', created_at='2026-01-28 04:23:28.297', type='chat', usage=ChatUsage(input_tokens=26, output_tokens=7, time=2.512854, type='chat'), metadata=None)

块 3
        类型: <class 'list'>
        ChatResponse(content=[{'type': 'text', 'text': '1 2 3 4 5 '}], id='2026-01-28 04:23:28.383_65876d', created_at='2026-01-28 04:23:28.383', type='chat', usage=ChatUsage(input_tokens=26, output_tokens=10, time=2.598791, type='chat'), metadata=None)

块 4
        类型: <class 'list'>
        ChatResponse(content=[{'type': 'text', 'text': '1 2 3 4 5 6 7 8 '}], id='2026-01-28 04:23:28.619_be2da9', created_at='2026-01-28 04:23:28.619', type='chat', usage=ChatUsage(input_tokens=26, output_tokens=16, time=2.834871, type='chat'), metadata=None)

块 5
        类型: <class 'list'>
        ChatResponse(content=[{'type': 'text', 'text': '1 2 3 4 5 6 7 8 9 10 1'}], id='2026-01-28 04:23:28.827_d56c3e', created_at='2026-01-28 04:23:28.827', type='chat', usage=ChatUsage(input_tokens=26, output_tokens=22, time=3.043263, type='chat'), metadata=None)

块 6
        类型: <class 'list'>
        ChatResponse(content=[{'type': 'text', 'text': '1 2 3 4 5 6 7 8 9 10 11 12 1'}], id='2026-01-28 04:23:28.960_87196d', created_at='2026-01-28 04:23:28.960', type='chat', usage=ChatUsage(input_tokens=26, output_tokens=28, time=3.176539, type='chat'), metadata=None)

块 7
        类型: <class 'list'>
        ChatResponse(content=[{'type': 'text', 'text': '1 2 3 4 5 6 7 8 9 10 11 12 13 14 1'}], id='2026-01-28 04:23:29.157_5a8447', created_at='2026-01-28 04:23:29.157', type='chat', usage=ChatUsage(input_tokens=26, output_tokens=34, time=3.372862, type='chat'), metadata=None)

块 8
        类型: <class 'list'>
        ChatResponse(content=[{'type': 'text', 'text': '1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 1'}], id='2026-01-28 04:23:29.315_fb1400', created_at='2026-01-28 04:23:29.315', type='chat', usage=ChatUsage(input_tokens=26, output_tokens=40, time=3.530738, type='chat'), metadata=None)

块 9
        类型: <class 'list'>
        ChatResponse(content=[{'type': 'text', 'text': '1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 1'}], id='2026-01-28 04:23:29.491_3aadad', created_at='2026-01-28 04:23:29.491', type='chat', usage=ChatUsage(input_tokens=26, output_tokens=46, time=3.70717, type='chat'), metadata=None)

块 10
        类型: <class 'list'>
        ChatResponse(content=[{'type': 'text', 'text': '1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20'}], id='2026-01-28 04:23:29.688_359d9d', created_at='2026-01-28 04:23:29.688', type='chat', usage=ChatUsage(input_tokens=26, output_tokens=50, time=3.904525, type='chat'), metadata=None)

块 11
        类型: <class 'list'>
        ChatResponse(content=[{'type': 'text', 'text': '1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20'}], id='2026-01-28 04:23:29.710_0fb943', created_at='2026-01-28 04:23:29.710', type='chat', usage=ChatUsage(input_tokens=26, output_tokens=50, time=3.925685, type='chat'), metadata=None)

推理模型

AgentScope 通过提供 ThinkingBlock 来支持推理模型。

async def example_reasoning() -> None:
    """使用推理模型的示例。"""
    model = DashScopeChatModel(
        model_name="qwen-turbo",
        api_key=os.environ["DASHSCOPE_API_KEY"],
        enable_thinking=True,
    )

    res = await model(
        messages=[
            {"role": "user", "content": "我是谁?"},
        ],
    )

    last_chunk = None
    async for chunk in res:
        last_chunk = chunk
    print("最终响应:")
    print(last_chunk)


asyncio.run(example_reasoning())
最终响应:
ChatResponse(content=[{'type': 'thinking', 'thinking': '好的,用户问“我是谁?”,这是一个哲学性很强的问题。首先,我需要理解用户为什么会问这个问题。可能他们正在经历自我探索的阶段,或者对存在主义有所思考。也有可能他们感到迷茫,想要寻找自我认同。\n\n接下来,我应该考虑如何回答这个问题。直接回答“你是你”可能太简单,不够深入。需要从不同角度分析,比如哲学、心理学、社会学等。比如,哲学上,笛卡尔的“我思故我在”强调思考作为存在的证明;心理学上,自我认同涉及个人经历和性格;社会学角度,身份由社会角色和关系构成。\n\n还要注意用户可能的深层需求。他们可能希望得到情感上的支持,或者寻找自我价值的确认。这时候需要提供一些引导性的思考,而不是直接给出答案。比如,可以建议他们回顾自己的经历、价值观、兴趣等,帮助他们自我探索。\n\n另外,要避免过于抽象或理论化的回答,保持语言通俗易懂。同时,要让用户感到被理解和尊重,避免评判。可能还需要提醒他们,自我认知是一个持续的过程,不需要急于找到答案。\n\n还要考虑文化差异。不同文化对“自我”的定义可能不同,比如东方文化更强调集体,而西方更强调个体。但用户可能没有明确说明,所以回答需要保持中立。\n\n最后,确保回答结构清晰,分点说明不同角度的观点,并鼓励用户进行自我反思。这样既提供了信息,又促进用户自主思考,满足他们的深层需求。'}, {'type': 'text', 'text': '“我是谁?”这个问题看似简单,却蕴含着深刻的哲学、心理学和社会学意义。它可能源于对自我认知的探索、对存在意义的追问,或是对身份认同的迷茫。以下从不同角度尝试回答:\n\n---\n\n### **1. 哲学视角:我是“思考”的主体**\n- **笛卡尔**提出“我思故我在”(Cogito, ergo sum),认为思考本身证明了“我”的存在。你的意识、疑问和反思,本身就是“你”的证据。\n- **存在主义**(如萨特)认为,“人是先存在,然后才定义自己”。你通过选择、行动和责任塑造“我是谁”的答案。\n\n---\n\n### **2. 心理学视角:我是“经验”的集合**\n- **自我认同**(Self-identity)由你的经历、性格、价值观、记忆和情感构成。例如:\n  - 你可能认为自己是“善良的”“好奇的”“敏感的”……这些特质共同定义了你。\n  - 心理学中的“自我概念”(Self-concept)会随着成长、环境变化而调整。\n- **潜意识**也可能影响你对“我是谁”的感知,比如未被察觉的创伤或内在冲突。\n\n---\n\n### **3. 社会学视角:我是“关系”的产物**\n- 你的身份不仅是内在的,也由外部关系塑造:\n  - 你是某个家庭的成员、职业角色(如学生、工作者)、社会群体中的一员。\n  - 他人对你的看法、社会对“成功”“价值”的定义,都可能影响你对自我的认知。\n- **文化**也深刻影响身份:比如东方文化可能更强调“集体性”,而西方文化更注重“个体性”。\n\n---\n\n### **4. 佛教与东方哲学:我是“无常”的流动**\n- 佛教认为“我”是五蕴(色、受、想、行、识)的暂时组合,没有固定不变的“自我”。\n- **道家**主张“物我合一”,强调超越对“我”的执着,回归自然与整体。\n\n---\n\n### **5. 实践层面:如何探索“我是谁”?**\n- **反思**:写下你的核心价值观、人生目标、让你感到充实的时刻。\n- **提问**:  \n  - 我最珍惜什么?(如自由、爱、知识)  \n  - 我害怕什么?(可能揭示内心深处的恐惧)  \n  - 如果没有社会标签(如职业、年龄),我会如何定义自己?\n- **行动**:尝试新事物,观察哪些活动让你感到“真实”或“完整”。\n\n---\n\n### **6. 也许答案本身就是过程**\n“我是谁”没有标准答案,它可能是一个**动态的、开放的问题**。  \n- 有时你觉得自己是“一个寻求答案的人”,有时又觉得自己是“答案本身”。  \n- 接受这种不确定性,或许正是“自我”的一部分。\n\n---\n\n如果你愿意分享更多背景(比如你为什么突然思考这个问题),我可以提供更具体的探讨方向。 🌱'}], id='2026-01-28 04:23:41.740_36dcc4', created_at='2026-01-28 04:23:41.740', type='chat', usage=ChatUsage(input_tokens=11, output_tokens=964, time=12.026652, type='chat'), metadata=None)

工具 API

不同的模型提供商在工具 API 方面有所不同,例如工具 JSON schema、工具调用/响应格式。 为了提供统一的接口,AgentScope 通过以下方式解决了这个问题:

  • 提供了统一的工具调用结构 block ToolUseBlock 和工具响应结构 ToolResultBlock

  • 在模型类的 __call__ 方法中提供统一的工具接口 tools,接受工具 JSON schema 列表,如下所示:

json_schemas = [
    {
        "type": "function",
        "function": {
            "name": "google_search",
            "description": "在 Google 上搜索查询。",
            "parameters": {
                "type": "object",
                "properties": {
                    "query": {
                        "type": "string",
                        "description": "搜索查询。",
                    },
                },
                "required": ["query"],
            },
        },
    },
]

进一步阅读

Total running time of the script: (0 minutes 18.726 seconds)

Gallery generated by Sphinx-Gallery