AgentScope2.0、LangGraph、DeepSeek Harness,谁才是生产级 Agent 王者?

2026 年聊 AI Agent,绕不开三个名字:LangGraph、AgentScope 2.0、DeepSeek Harness。
但真正让技术人纠结的,从来不是“哪个更火”,而是同一件事——搭一个能自己干活的多智能体——三个框架给出了三种完全不同的答案。
我最近把 AgentScope 2.0 从头跑了一遍。这篇文章用一份 15 分钟实操加一张对比表,讲清楚三者的本质差异,以及你该怎么选。
01 真正难选的不是框架,是三种不同的“编排哲学”
先给一个判断:三个框架的差别,不在功能多少,而在它们默认相信谁。
LangGraph 相信“流程”。它把你的业务画成一张图(节点加边),每一步谁先谁后、哪里需要人工审批、哪里可以自动,都由开发者预先定义。它的招牌能力是持久化执行:中途崩溃、服务器重启,都能从检查点恢复。
AgentScope 2.0 相信“模型”。它不让你画流程,而是给你一个 ReAct 循环(推理、行动、观察),让模型自己决定下一步干什么;框架的重点是管住边界——什么工具能用、什么权限能碰、代码在什么沙箱里跑。
DeepSeek Harness 相信“拆装”。它把自己定位成“元框架”,用 Cordis 插件内核把模型、工具、沙箱、会话、UI 全拆成插件,你在配置里自由组合,招牌主张就是“一切皆插件”。
一句话总结:LangGraph 在解决“流程怎么不丢”,AgentScope 2.0 在解决“模型怎么不乱来”,DeepSeek Harness 在解决“框架怎么随便改”。
02 AgentScope 2.0:它是什么,不是什么
用三句话把它说清楚。
一句人话:AgentScope 2.0 是阿里通义实验室开源的智能体框架,核心是“ReAct 智能体 + 工具系统 + 权限沙箱 + 记忆”,目标是让模型在受控边界内自主干活。
一句排除:它不是流程编排器(不用画状态图),不是低代码平台,也不绑定某一家模型——OpenAI、Anthropic、Gemini、DashScope、DeepSeek、Kimi、xAI、Ollama 都有内置接入。
一句关系:对后端开发者来说,它最特别的是“生产护栏”出厂自带:5 种权限模式、8 种沙箱后端(本地、Docker、E2B、K8s)、事件流可观测、分布式多租户,而且 Python、Java 双版本。
它同时支持:工具函数(同步/异步/流式/并行)、MCP 服务器、长期记忆、结构化输出、运行中实时中断。核心智能体是开箱即用的 ReActAgent,也提供 AgentBase / ReActAgentBase 让你从零自定义。
03 15 分钟实操:装好、跑通、加工具
这一步我全程在终端跑过,按顺序做即可。
Step 1 安装(Python 3.11+)
pip install agentscope
用 uv 更省心:
uv pip install agentscope
一行验证装好没有:
python -c "import agentscope; print(agentscope.__version__)"

Step 2 写一个最小 ReAct 智能体
核心就四件事:名字、人设、模型、工具。下面是官方快速开始简化版,让它用 Python 跑一个 Hello World。
# -*- coding: utf-8 -*-
"""最小 ReAct 智能体:Reasoning + Acting 循环。
AgentScope 2.x 里**没有**单独的 ``ReActAgent`` 类:``Agent`` 本身就是
ReAct 循环(reason → act → observe → reason → …),循环行为由
``react_config`` 控制。所以「最小 ReAct 智能体」=
Agent + 工具(Toolkit) + ReActConfig(max_iters=...)
本示例给 Agent 两个只读工具,并问一个必须「先查天气、再换算单位」的
问题,从而触发两轮工具调用(Act)与结果观察(Observe)。
运行::
python react_agent.py
密钥优先读环境变量 ``DASHSCOPE_API_KEY``,其次读本目录的 ``.env``。
"""
import asyncio
import os
from pathlib import Path
from agentscope.agent import Agent, ReActConfig
from agentscope.credential import DashScopeCredential
from agentscope.event import (
ReplyEndEvent,
ReplyFinishedReason,
TextBlockDeltaEvent,
ThinkingBlockDeltaEvent,
ToolCallDeltaEvent,
ToolCallStartEvent,
ToolResultEndEvent,
ToolResultTextDeltaEvent,
)
from agentscope.message import UserMsg
from agentscope.model import DashScopeChatModel
from agentscope.tool import FunctionTool, Toolkit
# ---------------------------------------------------------------- 工具(Act)
# 普通 Python 函数即可,FunctionTool 会从函数签名 + docstring 自动生成
# JSON Schema。is_read_only=True 表示无副作用,权限引擎直接放行,
# 不会停下来问你「是否允许调用」。
def get_weather(city: str) -> str:
"""查询指定城市的实时天气。
Args:
city: 城市名,例如 "成都"
"""
# 示例用假数据,换成真实 API 调用即可
mock = {
"成都": "多云,气温 18℃",
"北京": "晴,气温 12℃",
}
return mock.get(city, f"暂无 {city} 的天气数据")
def celsius_to_fahrenheit(celsius: float) -> str:
"""把摄氏度换算成华氏度。
Args:
celsius: 摄氏温度数值
"""
return f"{celsius:g}℃ = {celsius * 9 / 5 + 32:.1f}℉"
# ------------------------------------------------- ReAct 轨迹打印(可选)
async def run(agent: Agent, question: str) -> str:
"""跑一轮对话,并把 ReAct 的每一步打印出来。
事件流里的关键事件对应 ReAct 的三个环节:
- ``ThinkingBlockDeltaEvent`` / ``TextBlockDeltaEvent`` → Reasoning
- ``ToolCallStartEvent`` / ``ToolCallDeltaEvent`` → Acting
- ``ToolResultEndEvent`` → Observation
"""
names: dict[str, str] = {}
args: dict[str, str] = {}
results: dict[str, str] = {}
# 每次模型调用都会另起一个 text block:只保留最后一个,即最终答案
answer: list[str] = []
answer_block: str | None = None
async for ev in agent.reply_stream(
inputs=UserMsg(name="user", content=question),
):
if isinstance(ev, ToolCallStartEvent):
names[ev.tool_call_id] = ev.tool_call_name
args[ev.tool_call_id] = ""
results[ev.tool_call_id] = ""
elif isinstance(ev, ToolCallDeltaEvent):
args[ev.tool_call_id] += ev.delta
elif isinstance(ev, ToolResultTextDeltaEvent):
results[ev.tool_call_id] += ev.delta
elif isinstance(ev, ToolResultEndEvent):
print(f" [Act] {names.pop(ev.tool_call_id, '?')}({args.pop(ev.tool_call_id, '')})")
print(f" [Obs] {results.pop(ev.tool_call_id, '').strip()}")
elif isinstance(ev, ThinkingBlockDeltaEvent):
# 仅当开启 thinking_enable 时才会出现
print(f" [Think] {ev.delta}")
elif isinstance(ev, TextBlockDeltaEvent):
if ev.block_id != answer_block:
answer_block, answer[:] = ev.block_id, []
answer.append(ev.delta)
elif (
isinstance(ev, ReplyEndEvent)
and ev.finished_reason != ReplyFinishedReason.COMPLETED
):
print(f" [End] finished_reason={ev.finished_reason}")
return "".join(answer)
def _load_env_file() -> None:
"""读取脚本同目录的 ``.env``,已存在的环境变量优先。"""
env_file = Path(__file__).with_name(".env")
if not env_file.is_file():
return
for line in env_file.read_text(encoding="utf-8").splitlines():
line = line.strip()
if not line or line.startswith("#") or "=" not in line:
continue
key, value = line.split("=", 1)
os.environ.setdefault(key.strip(), value.strip().strip("\"'"))
async def main() -> None:
_load_env_file()
api_key = os.environ.get("DASHSCOPE_API_KEY")
if not api_key:
raise SystemExit("请先 export DASHSCOPE_API_KEY=sk-...,或写入 examples/ggs/.env")
agent = Agent(
name="ReAct",
# 明确要求「用工具」而不是心算,这样才看得到多轮 ReAct 循环
system_prompt=(
"你是一个严谨的助手。需要外部数据时必须调用工具获取,不要凭记忆"
"编造;所有单位换算也必须调用工具完成,不要自己心算。"
),
model=DashScopeChatModel(
credential=DashScopeCredential(api_key=api_key),
model="qwen3.7-plus",
stream=True,
# 想看到 Reasoning 的思考块,可打开 thinking_enable
# parameters=DashScopeChatModel.Parameters(thinking_enable=True),
),
toolkit=Toolkit(
tools=[
FunctionTool(get_weather, is_read_only=True),
FunctionTool(celsius_to_fahrenheit, is_read_only=True),
],
),
# ReAct 循环控制:一个 reply 内最多几轮 reason-act(默认 50)
react_config=ReActConfig(max_iters=5),
)
question = "成都现在气温多少华氏度?"
print(f"user: {question}")
answer = await run(agent, question)
print(f"\n{agent.name}: {answer}")
asyncio.run(main())

跑起来后,你会看到智能体先输出一次工具调用(执行 Python 代码),拿到结果后再给出最终回复——这就是一个完整的 ReAct 循环。
Step 3 想更快体验?直接跑终端 console
from agentscope.agent import Agent
from agentscope.console import launch_console
from agentscope.tool import Toolkit, Bash, Grep, Glob, Read, Write, Edit
from agentscope.credential import DashScopeCredential
from agentscope.model import DashScopeChatModel
import os, asyncio
async def main() -> None:
agent = Agent(
name="Friday",
system_prompt="You're a helpful assistant named Friday.",
model=DashScopeChatModel(
credential=DashScopeCredential(
api_key=os.environ["DASHSCOPE_API_KEY"]
),
model="qwen3.7-plus",
)
)
# Chat with the agent in the terminal — streamed output, tool-call
# confirmation and Ctrl+C interruption are all handled for you
await launch_console(agent)
asyncio.run(main())

流式输出、工具调用确认、Ctrl+C 中断,全部开箱即用。
Step 4 给 Agent 配上“能干活”的工具
文件读写、搜索、命令执行这些高频工具是内置的,注册即用。
from agentscope.agent import Agent
from agentscope.credential import DashScopeCredential
from agentscope.model import DashScopeChatModel
from agentscope.tool import Toolkit, Bash, Grep, Glob, Read, Write, Edit
agent = Agent(
name="Friday",
system_prompt="You are a helpful assistant named Friday.",
model=DashScopeChatModel(
credential=DashScopeCredential(
api_key=os.environ["DASHSCOPE_API_KEY"]
),
model="qwen3.7-plus",
),
toolkit=Toolkit(
tools=[Bash(), Grep(), Glob(), Read(), Write(), Edit()]
),
)
到这一步,你的智能体已经能读代码、搜文件、执行命令、改文件——一个最小“能干活”的 Agent 就绪。
Step 5 给 Agent 配上长期记忆
from agentscope.agent import Agent
from agentscope.middleware import AgenticMemoryMiddleware
from agentscope.tool import Toolkit
from agentscope.workspace import LocalWorkspace
async with LocalWorkspace(workdir="./workspace") as workspace:
agent = Agent(
name="Friday",
system_prompt=(
"You are a helpful assistant named Friday. "
"Use the provided tools whenever they help.\n\n"
+ await workspace.get_instructions() # 把 workspace 说明注入系统提示
),
model=..., # 与第 3 节相同,此处省略
toolkit=Toolkit(
tools=await workspace.list_tools(), # 文件工具来自 workspace
skills_or_loaders=await workspace.list_skills(),
),
middlewares=[
AgenticMemoryMiddleware(
workdir=workspace.workdir,
backend=workspace.get_backend(),
),
],
offloader=workspace, # 把压缩后的上下文和超大工具结果卸载到磁盘
)
我把我的爱好跟他说

退出进程后,还是可以记得我的爱好

Step 6 给 Agent 服务化,配上WEBUI
# server.py
import os
from pathlib import Path
import uvicorn
from fastapi.middleware import Middleware
from fastapi.middleware.cors import CORSMiddleware
from agentscope.app import create_app
from agentscope.app.message_bus import InMemoryMessageBus
from agentscope.app.rag import LocalBlobStore
from agentscope.app.rag.knowledge_base_manager import CollectionPerKbManager
from agentscope.app.storage import AsyncSQLAlchemyStorage
from agentscope.app.workspace_manager import LocalWorkspaceManager
from agentscope.rag import (
ApproxTokenChunker,
ExcelParser,
PDFParser,
PPTParser,
QdrantStore,
TextParser,
WordParser,
)
_HERE = Path(__file__).resolve().parent
_DB = os.environ.get("AGENTSCOPE_DB", str(_HERE / "agentscope.db"))
storage = AsyncSQLAlchemyStorage(f"sqlite+aiosqlite:///{_DB}")
app = create_app(
storage=storage,
message_bus=InMemoryMessageBus(),
workspace_manager=LocalWorkspaceManager(basedir=str(_HERE / "workspaces")),
# 不传这个,所有 /knowledge_bases/* 都会返回 503
knowledge_base_manager=CollectionPerKbManager(
storage=storage,
vector_store=QdrantStore(path=str(_HERE / "qdrant_data")),
),
knowledge_parsers=[
TextParser(), PDFParser(), WordParser(), ExcelParser(), PPTParser(),
],
knowledge_chunkers=[ApproxTokenChunker],
blob_store=LocalBlobStore(root_dir=str(_HERE / "blobs")),
# 前端跑在另一个 origin,不挂 CORS 的话预检 OPTIONS 全是 405
extra_middlewares=[
Middleware(
CORSMiddleware,
allow_origins=["*"], allow_methods=["*"], allow_headers=["*"],
),
],
)
if __name__ == "__main__":
uvicorn.run(app, host="127.0.0.1", port=8000)

启动webui
cd examples/web_ui
pnpm install
pnpm dev

浏览器打开后,在设置页填 server_url = http://127.0.0.1:8000 和你的用户名(这个用户名就是上面那个 X-User-ID),然后新建 Agent、选模型,就能聊了。

给 Java 架构师的一句提示
AgentScope 同时发布了 Java 2.0:JDK 17 起步,Maven 引入 io.agentscope:agentscope-harness,从 HarnessAgent 开始;只想用轻量 ReAct 循环就用 agentscope-core。配置里写模型字符串、工作区、上下文压缩策略即可。
04 进阶:权限、沙箱与 Agent Team
入门只是热身。AgentScope 2.0 真正拉开差距的,是下面三块生产级能力。
1. 权限:5 种模式细粒度管控
每一次工具调用都可以设置权限模式:从完全自主、需要审批,到直接禁止。多智能体场景下,可以给不同 Agent 配不同权限等级,而不是一把钥匙开所有门。
2. 沙箱:8 种后端隔离代码执行
本地、Docker、E2B、K8s 等 8 种沙箱后端,限制 Agent 的代码执行和文件操作范围。这是它和“研究型框架”最大的分水岭——默认按生产安全设计。
3. Agent Team:多智能体怎么协作
和多智能体框架常见的“层层嵌套”不同,AgentScope 2.0 的团队模型是:leader 创建 team,worker 是独立会话、在同一服务上并发执行,leader 通过读会话流观察进度;成员之间用 Redis 做消息总线通信。
加上类型化事件流(运行过程可观测、可中断、可恢复),以及上下文自动压缩、长期记忆,一套“可信、可控、可审计”的底座基本齐了。
05 一张表看清三个框架
信息来自各自官方文档与公开发布资料(2026 年 9 月核对),同一维度并排列出,方便横向比较。
|
维度 |
AgentScope 2.0 |
LangGraph |
DeepSeek Harness |
|---|---|---|---|
|
出品方 |
阿里通义实验室 |
LangChain 团队 |
DeepSeek |
|
编排哲学 |
弱编排:模型自主决策,框架管安全边界 |
强编排:图/状态机,节点加边预定义 |
元框架:一切皆插件,配置里自由组合 |
|
核心抽象 |
ReAct 智能体 + 事件流 |
图 + Checkpointer 检查点 |
Cordis 插件内核 + 工具契约 |
|
语言生态 |
Python、Java |
Python、JS/TS |
npm/TypeScript 为主 |
|
上手成本 |
pip 安装,20 行起 |
需理解状态图,学习曲线较陡 |
npx 一行起,深度定制需懂插件机制 |
|
安全边界 |
5 种权限模式 + 8 种沙箱后端 |
基础权限,靠检查点保证执行可靠 |
TS 工具契约 + Docker 沙箱 |
|
多智能体 |
Agent Team(leader-worker,Redis 总线) |
图内子图/节点编排 |
子 Agent 以插件形式挂载 |
|
可观测性 |
类型化事件流 |
LangSmith 生态 |
Trajectory 轨迹,可回放、可分叉 |
|
成本优化 |
记忆压缩、上下文管理 |
依赖模型层/外部方案 |
KV Cache 优化,官方称省 80%+ Token |
|
部署形态 |
本地/Serverless/K8s,多租户 |
单机强,分布式需自建或平台版 |
本地/私有部署,npm + GitHub |
|
最适合 |
生产级开放任务、多租户、要安全边界 |
严格流程、人工审批、审计 |
深度定制 Agent 产品、省 Token、插件生态 |
06 三个最容易踩的误区
误区一:框架越“重”越安全。
有一定道理:AgentScope 2.0 权限加沙箱、DSH 的 Docker 隔离,确实比裸调模型安全。但“安全”是配置出来的,不是框架自带光环——权限模式设成“全自主”、沙箱用本地后端,照样裸奔。判断标准不是框架名,而是你的权限策略和沙箱配置。
误区二:“LangGraph 不适合生产”是误读。
它和 AgentScope 的差异是“防什么”:LangGraph 用检查点防的是执行丢状态,AgentScope 用权限沙箱防的是越权乱跑。如果你的业务是固定流程、要人工审批和审计,LangGraph 的持久化执行恰恰是生产刚需。
误区三:插件化就是万能。
DeepSeek Harness 的“一切皆插件”解决的是定制与组合问题,不解决模型能力和流程设计问题。插件再多,模型推理弱、工具契约写得含糊,Agent 照样干不好活。元框架的代价是:你决定的东西变多了,要自己扛的责任也变多了。
07 以后怎么选:一套判断框架
不用记参数,记住三个问题就行。
问题一:你的任务到底“确定”还是“开放”?
流程固定、步骤可枚举、要审批要审计——选 LangGraph,图编排和检查点正好。任务开放、结果不确定、要靠模型临场发挥——选 AgentScope 2.0,让模型自主、框架管边界。
问题二:你是“用框架”还是“造产品”?
快速搭业务智能体,AgentScope 2.0 的出厂护栏最省事;想深度定制一个 Agent 产品、要省 Token、要自己定义运行规则——DeepSeek Harness 的插件化给你最大自由度。
问题三:你的团队是什么技术栈?
Java 团队优先看 AgentScope 2.0(JVM 原生支持);前端/全栈团队可以顺手上 DeepSeek Harness(npm 生态);LangGraph 则对 LangChain 生态用户最平滑。
补充一句:这三个框架不是互斥关系。生产环境里完全可以用 AgentScope 管多租户边界、内部再挂 LangGraph 跑确定性子流程——先选对主框架,再谈组合。
更多推荐

所有评论(0)