模型

在本教程中,我们介绍 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_args={"base_url": "http://your-api-endpoint"} 参数指定 API 端点。例如:

OpenAIChatModel(client_args={"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='2025-10-03 14:52:06.220_76dff3', created_at='2025-10-03 14:52:06.220', 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='2025-10-03 14:52:07.612_df747f', created_at='2025-10-03 14:52:07.612', type='chat', usage=ChatUsage(input_tokens=10, output_tokens=8, time=1.391126, type='chat'), metadata=None)
作为 Msg 的响应: Msg(id='FTbncbcxyuKdcGpqo3uSb7', name='Friday', content=[{'type': 'text', 'text': '你好!有什么我能帮助你的吗?'}], role='assistant', metadata=None, timestamp='2025-10-03 14:52:07.612', 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='2025-10-03 14:52:08.544_1f7dfa', created_at='2025-10-03 14:52:08.544', type='chat', usage=ChatUsage(input_tokens=26, output_tokens=1, time=0.930346, type='chat'), metadata=None)

块 1
        类型: <class 'list'>
        ChatResponse(content=[{'type': 'text', 'text': '1\n'}], id='2025-10-03 14:52:08.606_f8f926', created_at='2025-10-03 14:52:08.606', type='chat', usage=ChatUsage(input_tokens=26, output_tokens=2, time=0.99281, type='chat'), metadata=None)

块 2
        类型: <class 'list'>
        ChatResponse(content=[{'type': 'text', 'text': '1\n2\n3'}], id='2025-10-03 14:52:08.671_f110e3', created_at='2025-10-03 14:52:08.671', type='chat', usage=ChatUsage(input_tokens=26, output_tokens=5, time=1.057749, type='chat'), metadata=None)

块 3
        类型: <class 'list'>
        ChatResponse(content=[{'type': 'text', 'text': '1\n2\n3\n4\n'}], id='2025-10-03 14:52:08.745_4979e6', created_at='2025-10-03 14:52:08.745', type='chat', usage=ChatUsage(input_tokens=26, output_tokens=8, time=1.132041, type='chat'), metadata=None)

块 4
        类型: <class 'list'>
        ChatResponse(content=[{'type': 'text', 'text': '1\n2\n3\n4\n5\n6\n7\n'}], id='2025-10-03 14:52:08.864_05734a', created_at='2025-10-03 14:52:08.864', type='chat', usage=ChatUsage(input_tokens=26, output_tokens=14, time=1.251179, type='chat'), metadata=None)

块 5
        类型: <class 'list'>
        ChatResponse(content=[{'type': 'text', 'text': '1\n2\n3\n4\n5\n6\n7\n8\n9\n10'}], id='2025-10-03 14:52:09.160_9594f2', created_at='2025-10-03 14:52:09.160', type='chat', usage=ChatUsage(input_tokens=26, output_tokens=20, time=1.546696, type='chat'), metadata=None)

块 6
        类型: <class 'list'>
        ChatResponse(content=[{'type': 'text', 'text': '1\n2\n3\n4\n5\n6\n7\n8\n9\n10\n11\n12'}], id='2025-10-03 14:52:09.281_c47f94', created_at='2025-10-03 14:52:09.281', type='chat', usage=ChatUsage(input_tokens=26, output_tokens=26, time=1.667402, type='chat'), metadata=None)

块 7
        类型: <class 'list'>
        ChatResponse(content=[{'type': 'text', 'text': '1\n2\n3\n4\n5\n6\n7\n8\n9\n10\n11\n12\n13\n14'}], id='2025-10-03 14:52:09.424_02e111', created_at='2025-10-03 14:52:09.424', type='chat', usage=ChatUsage(input_tokens=26, output_tokens=32, time=1.810335, type='chat'), metadata=None)

块 8
        类型: <class 'list'>
        ChatResponse(content=[{'type': 'text', 'text': '1\n2\n3\n4\n5\n6\n7\n8\n9\n10\n11\n12\n13\n14\n15\n16'}], id='2025-10-03 14:52:09.570_46c403', created_at='2025-10-03 14:52:09.570', type='chat', usage=ChatUsage(input_tokens=26, output_tokens=38, time=1.956854, type='chat'), metadata=None)

块 9
        类型: <class 'list'>
        ChatResponse(content=[{'type': 'text', 'text': '1\n2\n3\n4\n5\n6\n7\n8\n9\n10\n11\n12\n13\n14\n15\n16\n17\n18'}], id='2025-10-03 14:52:09.732_597992', created_at='2025-10-03 14:52:09.732', type='chat', usage=ChatUsage(input_tokens=26, output_tokens=44, time=2.11836, type='chat'), metadata=None)

块 10
        类型: <class 'list'>
        ChatResponse(content=[{'type': 'text', 'text': '1\n2\n3\n4\n5\n6\n7\n8\n9\n10\n11\n12\n13\n14\n15\n16\n17\n18\n19\n20'}], id='2025-10-03 14:52:09.803_721d79', created_at='2025-10-03 14:52:09.803', type='chat', usage=ChatUsage(input_tokens=26, output_tokens=50, time=2.189462, type='chat'), metadata=None)

块 11
        类型: <class 'list'>
        ChatResponse(content=[{'type': 'text', 'text': '1\n2\n3\n4\n5\n6\n7\n8\n9\n10\n11\n12\n13\n14\n15\n16\n17\n18\n19\n20'}], id='2025-10-03 14:52:10.065_f63dc7', created_at='2025-10-03 14:52:10.065', type='chat', usage=ChatUsage(input_tokens=26, output_tokens=50, time=2.452107, 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最后,总结时要强调“我是谁”是一个持续探索的过程,鼓励用户进行自我反思,并保持开放的心态。这样既回答了问题,又提供了进一步思考的方向。\n'}, {'type': 'text', 'text': '“我是谁?”是一个古老而深邃的问题,不同的人、不同的文化、不同的哲学体系可能会给出不同的答案。以下是一些可能的视角,或许能帮助你探索这个问题:\n\n---\n\n### 1. **从哲学的角度**\n   - **笛卡尔的“我思故我在”**:法国哲学家笛卡尔认为,即使怀疑一切,只要“我”在思考,就证明“我”存在。因此,“我是谁”可以简化为“我是一个思考的存在”。\n   - **存在主义**:萨特说“存在先于本质”,人类没有预设的本质,而是通过选择和行动定义自己。因此,“我是谁”取决于你如何选择生活。\n   - **东方哲学**:佛教认为“我”是虚幻的,是五蕴(色、受、想、行、识)的暂时组合,真正的“我”可能是超越个体意识的“空性”;道家则强调“无我”与自然合一。\n\n---\n\n### 2. **从心理学的角度**\n   - **自我意识**:心理学认为“我”是大脑对自身存在、思想和情感的觉察。它由记忆、经验、价值观和人际关系共同构建。\n   - **身份认同**:你可能通过职业、家庭角色、兴趣爱好、文化背景等来定义自己。但这些标签是动态的,会随着时间和经历变化。\n   - **潜意识**:弗洛伊德认为“我”由本我(本能)、自我(现实调节者)和超我(道德约束)构成,而潜意识中隐藏着未被察觉的欲望和冲突。\n\n---\n\n### 3. **从科学的角度**\n   - **生物学**:从基因到细胞,你是一个由数十万亿细胞组成的复杂系统,依赖于DNA、神经网络和生理机制。\n   - **量子物理**:一些理论认为,观察者(“我”)与被观察的现实是相互关联的,但这一观点仍存在争议。\n\n---\n\n### 4. **从日常生活的角度**\n   - **角色与关系**:你可能是某个家庭中的孩子、朋友、同事,或是社会中的一个公民。这些角色塑造了你与他人的互动方式。\n   - **行动与选择**:你的行为、决定和价值观不断塑造“你是谁”。比如,你选择帮助他人,可能说明你是一个有同理心的人。\n\n---\n\n### 5. **从灵性的角度**\n   - **灵魂与超越**:一些灵性传统认为,“我”是永恒的灵魂或意识,身体只是暂时的容器。例如,印度教中的“阿特曼”(Atman)与“梵”(Brahman)合一。\n   - **内在的觉知**:禅宗强调“明心见性”,认为“我”是超越语言和概念的觉知本身。\n\n---\n\n### 6. **可能的答案**\n   - **“我是谁?”** 可能没有终极答案,但可以尝试回答:\n     - **我是我的思想、情感和经历的集合**。\n     - **我是不断变化的,没有固定的身份**。\n     - **我是与他人和世界互动的主体**。\n     - **我是探索这个问题的“我”**。\n\n---\n\n### 7. **如何进一步探索?**\n   - **自我反思**:写下你最珍视的价值观、恐惧、梦想,以及你希望成为什么样的人。\n   - **提问**:问自己“如果我不再是现在的身份,我会是谁?”“什么让我感到真实?”\n   - **阅读与实践**:哲学、心理学、宗教或艺术作品可能提供新的视角。\n   - **与他人对话**:通过交流了解他人眼中的“你”,或许能发现新的自我认知。\n\n---\n\n最终,“我是谁”可能是一个没有终点的旅程,而非一个需要抵达的终点。你愿意和我一起探索这个问题吗? 😊'}], id='2025-10-03 14:52:21.396_98a1ad', created_at='2025-10-03 14:52:21.396', type='chat', usage=ChatUsage(input_tokens=11, output_tokens=1123, time=11.326148, 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 15.182 seconds)

Gallery generated by Sphinx-Gallery