模型

在本教程中,我们介绍 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-09 07:38:59.868_4f2f56', created_at='2026-01-09 07:38:59.868', 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-09 07:39:01.294_6ca40f', created_at='2026-01-09 07:39:01.295', type='chat', usage=ChatUsage(input_tokens=10, output_tokens=8, time=1.425032, type='chat'), metadata=None)
作为 Msg 的响应: Msg(id='dp9b73ww2hneDEzhhX4WVk', name='Friday', content=[{'type': 'text', 'text': '你好!有什么我能帮助你的吗?'}], role='assistant', metadata=None, timestamp='2026-01-09 07:39:01.295', 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-09 07:39:02.528_b62243', created_at='2026-01-09 07:39:02.528', type='chat', usage=ChatUsage(input_tokens=26, output_tokens=1, time=1.231672, type='chat'), metadata=None)

块 1
        类型: <class 'list'>
        ChatResponse(content=[{'type': 'text', 'text': '1\n'}], id='2026-01-09 07:39:02.595_8d9642', created_at='2026-01-09 07:39:02.595', type='chat', usage=ChatUsage(input_tokens=26, output_tokens=2, time=1.299115, type='chat'), metadata=None)

块 2
        类型: <class 'list'>
        ChatResponse(content=[{'type': 'text', 'text': '1\n2\n3'}], id='2026-01-09 07:39:02.665_7a0962', created_at='2026-01-09 07:39:02.665', type='chat', usage=ChatUsage(input_tokens=26, output_tokens=5, time=1.369363, type='chat'), metadata=None)

块 3
        类型: <class 'list'>
        ChatResponse(content=[{'type': 'text', 'text': '1\n2\n3\n4\n'}], id='2026-01-09 07:39:03.193_297190', created_at='2026-01-09 07:39:03.193', type='chat', usage=ChatUsage(input_tokens=26, output_tokens=8, time=1.896638, type='chat'), metadata=None)

块 4
        类型: <class 'list'>
        ChatResponse(content=[{'type': 'text', 'text': '1\n2\n3\n4\n5\n6\n7\n'}], id='2026-01-09 07:39:03.338_be59e2', created_at='2026-01-09 07:39:03.338', type='chat', usage=ChatUsage(input_tokens=26, output_tokens=14, time=2.041547, type='chat'), metadata=None)

块 5
        类型: <class 'list'>
        ChatResponse(content=[{'type': 'text', 'text': '1\n2\n3\n4\n5\n6\n7\n8\n9\n10'}], id='2026-01-09 07:39:03.504_1215f0', created_at='2026-01-09 07:39:03.504', type='chat', usage=ChatUsage(input_tokens=26, output_tokens=20, time=2.208119, 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='2026-01-09 07:39:03.625_db87dd', created_at='2026-01-09 07:39:03.625', type='chat', usage=ChatUsage(input_tokens=26, output_tokens=26, time=2.329352, 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='2026-01-09 07:39:04.106_44af17', created_at='2026-01-09 07:39:04.106', type='chat', usage=ChatUsage(input_tokens=26, output_tokens=32, time=2.809867, 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='2026-01-09 07:39:04.291_d405f1', created_at='2026-01-09 07:39:04.291', type='chat', usage=ChatUsage(input_tokens=26, output_tokens=38, time=2.994659, 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='2026-01-09 07:39:04.397_c2effe', created_at='2026-01-09 07:39:04.397', type='chat', usage=ChatUsage(input_tokens=26, output_tokens=44, time=3.100434, 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='2026-01-09 07:39:04.789_8e19b6', created_at='2026-01-09 07:39:04.789', type='chat', usage=ChatUsage(input_tokens=26, output_tokens=50, time=3.49334, 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='2026-01-09 07:39:04.906_a3700a', created_at='2026-01-09 07:39:04.906', type='chat', usage=ChatUsage(input_tokens=26, output_tokens=50, time=3.609617, 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\n还要注意避免可能的误解。比如,用户可能认为我是AI,所以“我是谁”可能是在询问我的身份,但根据上下文,用户可能是在问自己。需要确认这一点,但如果没有更多信息,可能需要假设是用户在问自己。\n\n最后,确保回答友好、支持,并且鼓励用户进行自我反思。可能需要使用开放性问题,引导用户思考自己的价值观、经历、目标等,从而帮助他们找到自己的答案。'}, {'type': 'text', 'text': '“我是谁?”是一个深刻而复杂的问题,不同的人、不同的文化、不同的哲学体系可能会给出不同的答案。以下是一些可能的视角,或许能帮助你探索这个问题:\n\n---\n\n### **1. 哲学视角**\n- **笛卡尔**:“我思故我在”(Cogito, ergo sum)——思考本身证明了你的存在,但“我是谁”可能超越了单纯的思维。\n- **存在主义**(如萨特):人是“被抛入世界”的存在,通过选择和行动定义自己。\n- **东方哲学**(如佛教):可能认为“我”是虚幻的,是五蕴(色、受、想、行、识)的暂时组合,真正的“自我”是空性。\n\n---\n\n### **2. 心理学视角**\n- **弗洛伊德**:人的身份由本我(欲望)、自我(现实调节)和超我(道德)的动态平衡构成。\n- **荣格**:强调“个体化”过程,通过整合潜意识中的阴影、阿尼玛/阿尼姆斯等元素,形成完整的自我。\n- **自我认同**:你可能通过职业、关系、兴趣、价值观等逐渐构建“我是谁”的答案。\n\n---\n\n### **3. 灵性与宗教视角**\n- **基督教**:人是上帝的造物,拥有灵魂,通过爱与信仰找到意义。\n- **佛教**:否定“我”的永恒性,强调“无我”(Anatta),通过修行超越对“自我”的执着。\n- **道教**:追求“道法自然”,“我”是天地万物的一部分,与宇宙合一。\n\n---\n\n### **4. 实践性思考**\n如果你正在探索“我是谁”,可以尝试以下问题:\n- **我的核心价值观是什么?**(例如:自由、善良、创造力)\n- **我最珍视的品质或经历是什么?**\n- **如果没有人定义我,我会如何描述自己?**\n- **我的梦想或恐惧背后,隐藏着什么?**\n\n---\n\n### **5. 一个简单的答案**\n“你是独一无二的个体,由你的思想、情感、经历和选择共同塑造。你既是过去的选择,也是未来的可能性。”  \n但最终,这个问题的答案可能需要你通过生活、反思和行动去不断发现。\n\n---\n\n如果你愿意分享更多背景(比如你现在的处境、困惑或兴趣),我可以提供更具体的建议。你并不孤单,探索“我是谁”本身就是一种深刻的自我对话。 🌱'}], id='2026-01-09 07:39:17.247_17bb0a', created_at='2026-01-09 07:39:17.247', type='chat', usage=ChatUsage(input_tokens=11, output_tokens=1004, time=12.336457, 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 17.384 seconds)

Gallery generated by Sphinx-Gallery