关于 FlagQuantum MCP Server
FlagQuantum MCP Server 为 MCP Agent 提供本地 FlagQuantum SDK 工具,用于构建、编译、路由、导出和模拟量子电路,也支持本地研究能力执行。工具在本地进程内运行,不调用外部服务或提交硬件任务。
主要功能
- 01分析和序列化量子电路
- 02优化、编译并路由电路
- 03导入与导出 OpenQASM、QCIS
- 04本地模拟及 Lindblad 演化
- 05训练参数并规划执行
- 06检索、验证和执行本地研究能力
适用场景
- 01分析电路门数、深度和线路使用情况
- 02针对目标拓扑编译和比较电路
- 03本地运行模拟或动力学演化
- 04验证并执行获准的本地研究请求
MCP 相关
作为 MCP 服务,通过 stdio 或 Streamable HTTP 暴露 FlagQuantum 的电路、模拟和研究能力工具,并提供资源与提示词。所有工具在本地运行,不访问外部网络。
配置
本地服务的配置在各客户端中通用,复制后粘贴到客户端的 MCP 配置文件即可。
uvx flagquantum-mcp-serverFLAGQUANTUM_MCP_MAX_QUBITSLargest circuit width the server will process. Defaults to 24.FLAGQUANTUM_MCP_MAX_GATESLargest instruction count the server will process. Defaults to 10000.FLAGQUANTUM_MCP_MAX_IR_BYTESLargest serialized circuit payload accepted, in bytes. Defaults to 262144.本地服务需要在你的电脑上安装运行环境(如 Node.js 18+)。各客户端的配置文件位置不同,请参考客户端文档。
工具
17收录的工具列表 · 更新于 1 天前
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| circuit | string | 是 | 电路载荷。使用 circuit_format="qir" 时,传入门列表,例如 '[{"name": "h", "index": [0]}, {"name": "cx", "index": [0, 1]}]'。门的参数位于 "parameters" 下,因此旋转门示例如下: '[{"name": "rz", "index": [0], "parameters": {"theta": 0.5}}]'。使用 circuit_format="ir" 时,传入 FlagQuantum IR JSON。参数可以是数字, 也可以是按如下形式书写的符号:{"theta": {"$parameter": "theta"}}。不接受 OpenQASM。 |
| circuit_format | enum | 否 | "ir" 表示 FlagQuantum IR JSON,"qir" 表示门列表。ir | qir |
详细介绍
FlagQuantum MCP 服务
一个 MCP 服务,可让任何兼容 MCP 的 Agent 在本地访问 FlagQuantum SDK:构建、编译、路由、序列化和规划量子线路,并在本地运行——无需凭据、无需访问外部网络,也无需提交到硬件。
“外部”是关键所在。这里的每个工具都在此进程中运行,不会访问任何其他对象;服务不会调用提供商、读取令牌或提交任务。它也可以监听,因此,连接到客户端而非启动客户端的网关也能访问它——参见通过 HTTP 提供服务。入站监听器不属于出站流量。
属于 FlagQuantum/mcp-servers 项目。
上方的 mcp-name 注释并非装饰:MCP Registry 会从此 README 中读取它,以验证发布 registry 条目的人也控制着 PyPI 包。删除它会导致 registry 发布失败。
功能
通过 stdio 或 Streamable HTTP 提供二十七种工具。研究工具直接使用已安装的 FlagQuantum 服务契约;MCP 层不会重新实现请求解码、估算、提供商路由或科学验证。
构建和检查
| 工具 | 用途 |
|---|---|
describe_gate_set_tool | 查询指定门(或所有门)的线路数、参数名称和别名 |
analyze_circuit_tool | 查询门数量、深度、线路用量和双量子比特门数量 |
describe_layers_tool | 查询哪些门并行运行,以及深度由此产生的原因 |
serialize_circuit_tool | 获取规范 IR JSON 及其内容哈希 |
deserialize_circuit_tool | 检查此 IR 是否有效,以及往返转换后是否保持不变 |
参数
| 工具 | 用途 |
|---|---|
inspect_parameters_tool | 检查此线路是否已参数化,以及每个符号所在的位置 |
bind_parameters_tool | 查看将符号替换为数值后的 ansatz |
编译和路由
| 工具 | 用途 |
|---|---|
optimize_circuit_tool | 查看与目标无关的优化产生了哪些变化 |
compile_circuit_tool | 查看完整的优化和路由流水线生成的线路 |
route_circuit_tool | 查看此线路在线形/环形/网格/自定义拓扑上的成本 |
compare_topologies_tool | 找出对此线路成本最低的连通方式 |
describe_topology_tool | 查询连通方式,以及两条线路之间的距离 |
导出和展示
| 工具 | 用途 |
|---|---|
emit_openqasm_tool | 获取 OpenQASM 2.0 或 3.0 文本 |
import_openqasm_tool | 从 OpenQASM 文本获取 FlagQuantum IR——与 emit_openqasm_tool 相反的操作 |
emit_qcis_tool | 获取 QCIS 文本 |
draw_circuit_tool | 获取线路的 ASCII 图示 |
plan_execution_tool | 查看 SDK 将如何执行——使用哪种模式、设备和内存量 |
plan_evolution_tool | 验证连续时间 Lindblad 演化并估算其规模,但不实际运行 |
运行
| 工具 | 用途 |
|---|---|
simulate_circuit_tool | 从本地状态向量运行中获取计数、样本、边缘概率或期望值 |
evolve_dynamics_tool | 从本地 Lindblad 演化中获取随时间变化的布居数、可观测量和可选的密度矩阵 |
train_parameters_tool | 获取能够降低线路相对于 Pauli 和 Hamiltonian 的能量的角度 |
研究能力工作流
| 工具 | 能回答什么 |
|---|---|
search_capabilities_tool | 哪些获批的本地研究操作符合结构化筛选条件? |
describe_capability_tool | 某项操作声明的确切请求、结果、限制和验证器是什么? |
estimate_capability_tool | 此请求是否受本地支持?FlagQuantum 估算的资源上限是多少? |
validate_capability_input_tool | 完整的类型化请求是否通过上游验证? |
execute_local_capability_tool | 显式执行本地提供方后会得到什么 Evidence Bundle? |
validate_evidence_tool | 返回的 Evidence Bundle 是否完整,并通过指定验证器的科学验收? |
四个具体资源包括 flagquantum://version、
flagquantum://gate-set、flagquantum://ir-schema,以及已安装的研究
目录 flagquantum://capabilities/index。两个资源模板可直接公开确切的上游文档,
而无需复制它们:
flagquantum://capabilities/{capability_id}/{version} 和
flagquantum://schemas/{schema_id}。
三个提示词:build_and_analyze_circuit、compile_for_topology、
export_circuit。
这些是为向用户展示提示词的客户端编写的使用配方,例如 Claude
Desktop、MCP Inspector,以及将其转换为斜杠命令的宿主。自主 Agent 可能收不到其中任何提示词:有几次记录的会话甚至无法枚举它们,并报告说无法判断提示词是否存在。因此,Agent 必须知道的内容绝不会只存在于此处。提示词中陈述的每项限制也会出现在工具摘要、服务端说明或资源中;QCIS 拒绝规则和“说明你做了哪些假设”规则是仅有的两个例外,而现在它们已加入 emit_qcis_tool 和 bind_parameters_tool。
tests/test_server_contract.py 中的 PROMPT_CONSTRAINTS 确保这一点始终成立。
安装
pip install flagquantum-mcp-server
这会拉取 flagquantum,它依赖 torch。
Claude Code
claude mcp add flagquantum -- uvx flagquantum-mcp-server
Claude Desktop / Cline
{
"mcpServers": {
"flagquantum": {
"command": "uvx",
"args": ["flagquantum-mcp-server"]
}
}
}
MCP Inspector
npx @modelcontextprotocol/inspector uvx flagquantum-mcp-server
通过 HTTP 提供服务
启动进程的客户端——Claude Code、Claude Desktop、Inspector——使用默认的 stdio 传输,无需进行以下设置。连接到服务端的客户端(例如持有多个服务端的网关)则需要服务端开始监听:
flagquantum-mcp-server --transport http --host 0.0.0.0 --port 8105 \
--allowed-host quantum-mcp:8105
端点位于该主机和端口上的 /mcp,使用 Streamable HTTP 协议。
| 标志 | 默认值 | 含义 |
|---|---|---|
--transport | stdio | stdio 或 http。默认值不变,因此现有可用配置无需修改 |
--host | 127.0.0.1 | 要绑定的接口。默认绑定回环接口,避免服务端意外变得可访问 |
--port | 8105 | 要绑定的端口 |
--allowed-host | none | 服务端会响应的 Host 标头,可重复指定 |
--allowed-origin | none | 服务端会响应的浏览器 Origin,可重复指定 |
**绑定非回环接口需要 --allowed-host。**如果未指定,服务端会拒绝启动,而不是在所有接口上监听且不检查访问者:
$ flagquantum-mcp-server --transport http --host 0.0.0.0
usage: flagquantum-mcp-server [-h] ...
flagquantum-mcp-server: error: --host 0.0.0.0 is not a loopback address, so the
server would answer any Host header that reaches it. Name the hosts it should
answer with --allowed-host HOST[:PORT], or bind 127.0.0.1.
传入任何 --allowed-host 或 --allowed-origin 都会启用主机验证;携带未列出的 Host 的请求将收到 421 Misdirected Request 响应。
服务端始终会响应回环主机,因此启用验证不会导致本地客户端被拒之门外。
接入时有两点值得注意:
- **通过设置对象配置验证,而不是使用
http_app( allowed_hosts=...)。**该关键字参数会将值追加到一个列表中,而只有在启用验证后才会检查此列表,因此单独使用时看起来像安全设置,实际上却不会强制执行任何检查。根据 fastmcp 3.4.7 的实测结果:使用该关键字参数时,虚假的Host会收到200响应;通过设置对象配置时则会收到421响应。 - **
--transport http添加的是入站套接字,而非出站套接字。**没有任何工具因此获得网络访问路径;AGENTS.md 中的第 4 条规则保持不变。
电路格式
接受两种输入格式,均为 FlagQuantum 自有的序列化格式。
ir(规范格式)——FlagQuantum IR JSON,由
CircuitIR.to_json() 生成。具有版本信息、可哈希,且包含未知
字段时会被拒绝:
{
"kind": "flagquantum.circuit_ir",
"version": "1.0",
"n_wires": 2,
"dtype": "complex64",
"shape": [4],
"instructions": [
{"opcode": "h", "wires": [0], "params": {}, "matrix": null, "metadata": {}},
{"opcode": "cx", "wires": [0, 1], "params": {}, "matrix": null, "metadata": {}}
],
"observables": [],
"measurements": [],
"metadata": {}
}
qir(便捷格式)——来自 Circuit.to_qir() 的紧凑门列表,更容易
手动编写:
[{"name": "h", "index": [0]}, {"name": "cx", "index": [0, 1]}]
门的参数由 parameters 承载,上面的示例没有展示这一点,因为其中的门都不需要参数:
[{"name": "rz", "index": [0], "parameters": {"theta": 0.5}}]
两种格式使用不同的键名,这是最常见的错误:门列表使用 name 表示门名、用 index 表示导线,而序列化的
IR 使用 opcode 和 wires。将 IR 键作为 qir 发送会被拒绝,并会明确指出这一点。空门列表也会被拒绝,因为导线数量是根据最高索引推断的——空列表表示没有电路。单导线门可以使用裸整数("index": 0 表示 "index": [0])。
两种格式都可以传给任何工具;serialize_circuit_tool 会将
qir 转换为规范的 ir。
还有一个容易混淆的命名细节:IR 载荷的版本字段拼作 version,
若发送 ir_version,则会因未知键而被拒绝——但工具结果会将同一字段报告为 ir_version。载荷键和报告键的拼写并不相同。
circuit_format 是一个封闭集合——JSON 架构公开
"enum": ["ir", "qir"],因此错误的值会在任何工具主体运行之前被拒绝。
OpenQASM 文本不是受支持的输入。 FlagQuantum 提供发射器,但没有 QASM 解析器,因此无法将其转换;持有 OpenQASM 的调用方必须先在 FlagQuantum 中加载它,再发送生成的 IR。
关于参数
门参数可以是数字或符号,符号写作一个以符号名为键的单键对象:
{"name": "ry", "index": [0], "parameters": {"theta": {"$parameter": "theta"}}}
两种输入格式都支持这种写法。符号使电路成为一个 ansatz:inspect_parameters_tool 会报告它,而 bind_parameters_tool 会用数字替换它。
裸字符串不是符号。 {"theta": "theta"} 是一个值,而不是引用;SDK 会将其存储为值,因此电路会报告自己未参数化。其他环节都不会报错:draw_circuit_tool 会打印传入的值,字符串会显示为 RY(theta)——看起来与真正的符号无法区分——而 plan_execution_tool 会为该电路制定执行计划。因此,输入边界会拒绝这种写法,以及拼写错误的标记({"$unknown": ...})和非字符串符号名,并指出门和参数的名称。参数还可以采用 $expression、$complex 和 $tensor 这几种编码;不包含这四个键中任何一个的映射也会因此被拒绝。flagquantum://ir-schema 资源包含一个完整的 parameter_example。
SDK 遗留了一个不太理想的细节:真正的符号会以 SDK 对它的 repr 形式呈现,因此 RY(theta) 会显示为 RY(Parameter(name='theta'))。
FlagQuantum 的 Parameter 没有定义 __str__,因此 str() 会回退到 __repr__。符号本身没有问题——只是图示中的写法不够直观——而且两种输入格式都会受到同样的影响。
导出时需要绑定:发射器会写入数字,并会拒绝未绑定的电路,同时提示使用 bind_parameters。其他操作都不需要绑定。analyze、optimize、route、draw、describe_layers 和 plan_execution_tool 都接受原样的参数化电路,因为它们都不会读取参数值——计划是根据载荷的形状和 dtype 构建的。只有在需要生成的文本或要运行的具体电路时才绑定,无需提前绑定。
关于显式酉矩阵
门矩阵通过一个因格式而异的键传递:门列表称其为 gate,
序列化 IR 称其为 matrix。
[{"name": "any", "index": [0], "gate": [[0, 1], [1, 0]]}]
有两种情况会被拒绝,而不是只部分接受。
格式对应的键不正确。 Circuit.from_qir 会读取 gate,并完全忽略
matrix,因此,如果门列表用 IR 的方式写出矩阵,就会在没有矩阵的情况下构建——且不会发出提示。对于内置名称,这意味着生成的电路与调用者编写的不同,因此会明确指出键不匹配。
内置操作码上的矩阵。 矩阵应属于 any,这是 FlagQuantum 为此保留的操作码。对于内置名称,SDK 会将矩阵保留在负载中,但以该内置门自身的定义为准,这会导致工具行为不一致:
analyze_circuit_tool 会以该内置名称报告门,而发射器则拒绝将其降级。请将门命名为 any。
关于线编号
两种格式中的线编号都必须是整数,wires 列表也必须是列表。两点都值得说明,因为 SDK 接受的格式更多:它会遍历收到的任何内容,并对每个元素调用 int(),因此 "1"、true、1.7 和
0.9 都会成为线编号;而 "01" 会成为线 0 和线 1,{"0": 1} 则会成为线 0。最后几种情况说明了为什么这应当报错,而不是图方便——一个没有意义的值会变成看起来正常的电路。
关于信封自身的字段
同一规则也适用于 instructions 之外的字段。SDK 会对 n_wires 和
shape 的各个条目调用 int(),因此 "2"、2.7 和 true 都会成为宽度;dtype 则会作为 torch 的属性查找,因此非字符串值会在 SDK 内部触发属性查找。
判断是否拒绝的标准是信息是否丢失,而不是 JSON 类型是否与架构完全一致。这就是为什么 version: 1.0 会被接受——str(1.0) 能还原它——而 n_wires: 2.7 不会被接受:它会静默变成 2;n_wires: true 也不会被接受,因为它会静默变成 1。
此处会检查 dtype 是否为字符串。哪些字符串合法由 SDK 决定,其自身的消息会指出规则(complex_dtype must be complex64 or complex128),因此两者不会出现偏差。
关于可观测量和测量
两者都是对象列表;当电路中没有对应内容时列表为空,条目也很简短——SDK 会在加载时补全其余内容:
{
"observables": [{"name": "ZZ", "wires": [0, 1]}],
"measurements": [{"kind": "counts", "wires": [0, 1], "shots": 1024}]
}
SDK 存储的内容会添加可选键,并将可观测量名称转换为小写,因此 "ZZ" 会以 "coefficient": 1.0 的形式返回,名称为 "zz"。coefficient 是该项的权重,也可以是符号,就像门角度一样({"$parameter": "w"}),这正是哈密顿量项携带变分权重的方式。省略 shots 时,其值为 null。
可观测量是 VQE ansatz 要测量的对象,因此值得了解:即使形状本身无误,也可以访问该内容——flagquantum://ir-schema 会通过 observable_example 并列展示这两种形式。
关于发射的文本
emit_openqasm_tool 会测量每条线,除非 result_wires 指定了所需线,因此发射的程序通常会带有源电路中没有的测量——即使 Bell 电路没有 measurements,仍会发射 c = measure q;。
在源 IR 中声明测量不会改变任何内容:发射的文本完全由 result_wires 决定。结果中的 content_hash 标识的是源电路,而不是发射的文本。emit_qcis_tool 不会追加任何内容。
关于导入的文本
import_openqasm_tool 会读取 FlagQuantum 自有生成器编写的规范子集,并拒绝其余内容,返回 UNSUPPORTED_FORMAT 以及导入器自己的消息,其中会指出相关语句和行号。它不是通用的 OpenQASM 前端:来自其他工具链的文本可能会被拒绝,而不是被近似处理;程序绝不会被悄悄改写以适配要求。
往返转换忠实保留的是文本,而非源电路。由于 emit_openqasm_tool 会添加源电路中原本没有的测量操作,导入其输出会得到一个包含测量操作的电路。因此,它的 content_hash 与描述源电路的生成器哈希不同。重复导入,哈希保持稳定;导入自己生成的内容,门序列一致,但测量操作是新增的。
关于 content_hash
每个载荷都带有 SDK 的 content_hash,它是包含 metadata 对象的规范 JSON 的 SHA-256 值。不含 metadata 的 IR 载荷是合法的——默认值为 {}——但其哈希与携带运行时元数据的同一电路不同。应将该哈希视为对载荷的标识,而不只是对门序列的标识。flagquantum://ir-schema 资源也说明了这一点,供 Agent 查阅。
限制
每项限制都可通过环境变量覆盖,因此部署时无需更改代码即可收紧限制:
| 变量 | 默认值 | 限制内容 |
|---|---|---|
FLAGQUANTUM_MCP_MAX_QUBITS | 24 | 电路宽度 |
FLAGQUANTUM_MCP_MAX_GATES | 10000 | 指令数量 |
FLAGQUANTUM_MCP_MAX_IR_BYTES | 262144 | 序列化电路载荷 |
FLAGQUANTUM_MCP_MAX_QASM_CHARS | 1000000 | 生成的程序大小 |
FLAGQUANTUM_MCP_MAX_COMPARE_TOPOLOGIES | 4 | 每次比较的拓扑数量 |
FLAGQUANTUM_MCP_MAX_TRAIN_SECONDS | 60 | 单次训练调用的预测耗时 |
FLAGQUANTUM_MCP_MAX_RESPONSE_VALUES | 65536 | 单个结果可返回的值数量 |
FLAGQUANTUM_MCP_MAX_HAMILTONIAN_TERMS | 1024 | 每个期望值请求中的 Pauli 项数 |
最后一项是唯一限制此服务返回内容的限制,而非限制其接受的内容。结果会进入模型的上下文,而不是内存;采样结果会随着 shots 增长——按这里的其他所有限制,200,000 次抽样都是合法的,但远超回答所需。
错误
错误分为两层,具体由哪一层返回,取决于模式能否描述该错误。
模式违规会在任何工具主体运行之前由 MCP 层捕获,并作为协议错误返回。这包括 circuit_format 不属于枚举值、缺少必需参数,以及参数的 JSON 类型错误。
其他所有错误都会以结构化封装返回,以便调用方根据代码分支处理,而不必解析说明文字:
{"status": "error", "error": {"code": "LIMIT_EXCEEDED", "message": "..."}}
代码:INVALID_INPUT、LIMIT_EXCEEDED、UNSUPPORTED_FORMAT、SDK_UNAVAILABLE、INTERNAL_ERROR。
这两层都会向客户端返回可读的错误,区别只在于错误所在的层。不会有任何错误以未处理异常的形式逃逸并破坏传输——调用失败后,会话仍可用于下一次调用;tests/test_server_process.py 会通过真实的 stdio 连接对此进行断言。
此服务器刻意不做的事
- 不涉及硬件、凭据或出站网络。 FlagQuantum 自身的 0.2.0 版本未提供远程提交入口,此适配器也不会添加。HTTP 传输会打开一个监听套接字,但不会改变请求到达后工具可以执行的操作。
- 不提供指令级
NoiseModel对象。 这些是实时 SDK 对象,而非可序列化值。因此,连续时间演化改为接受带物理速率的封闭 JSON 坍缩算符描述符。 - 不在仓库内耦合。 此包绝不能由 FlagQuantum 仓库导入。该项目的长期架构契约将“主仓库没有生产环境 MCP 传输依赖”列为退役条件;如果核心路径上可以导入
mcp或fastmcp,其tests/team/services/test_service_boundaries.py就会失败。将网关放在仓库外,正是该契约的要求。
它运行什么,以及这并不能证明什么
plan_evolution_tool 和 evolve_dynamics_tool 使用单独的连续时间契约。哈密顿量和可观测量采用 Pauli 项列表表示,初始状态是基态比特串或稠密状态,时间点需明确指定且严格递增;振幅阻尼是 Lindblad 方程中的物理速率,而非信道概率。执行工具会针对每个请求的时间点返回一行布居数、迹漂移、布居数边界检查,以及数值方法、阶数、步长和精度的来源信息。这两个工具都是确定性的本地 CPU 操作,不需要提供商、凭据、硬件或出站网络访问。
simulate_circuit_tool 会在此进程中执行电路:在 CPU 上进行状态向量模拟。仅此而已——没有远程目标、提供商或令牌。它并非一开始就存在。在它加入之前,服务器只会规划而不会运行,上面的那一行也曾如此说明;一项实际任务揭示了这样做的代价,因此我们修改了那一行,而不是暗中塞入这个工具。
结果通过 SDK 自身的字段说明了运行位置,而非用摘要描述:
"execution": {
"execution_path": "local_statevector",
"platform_provider": "pytorch_cpu",
"mode": "statevector",
"device": "cpu",
"accuracy": {"metric": "not_measured", "...": "..."}
}
accuracy.metric 为 not_measured,而 plan_execution_tool 针对同一电路报告 release_gate_allowed: false。第二个字段属于计划,位于其 summary 中——上面的模拟结果包含 execution、outputs 和 status,其 accuracy 块有五个字段(version、metric、value、tolerance、passed)。电路的理想模拟只能说明该电路本身,不能说明任何可能运行它的设备——SDK 不认可更强的解读,此服务器也不会这么做。
以下三种情况会被拒绝,而不会被重新解释,因为接受它们都会产生看似合理的答案:
| 输入 | 拒绝原因 |
|---|---|
| 含有未绑定参数的电路 | SDK 的拒绝信息是 planned execution failed,没有指出具体原因。此处的消息会列出参数,并指向 bind_parameters_tool |
携带 observables 的电路 | 默认的状态向量路径从不读取该字段,因此运行既不会返回期望值,也不会报错。请改用 pauli 或 terms 直接请求期望值 |
电路自带 measurements 时同时提供 outputs | SDK 只接受其中一项,并用不包含任一字段名称的说法说明了这一点 |
完整概率分布停止返回的宽度上限,取决于 SDK 自身的收缩限制;其消息会指向此服务器未提供的设置。此处的拒绝保留了 SDK 的文本,同时补充了调用者实际可采取的做法——指定少数几个量子位,或请求 counts,它只会报告实际出现的结果。
测量能量
{"kind": "expectation", "pauli": "ZZ"} 会计算一项。哈密顿量是加权和,因此需要使用 terms:
{"kind": "expectation",
"terms": [{"pauli": "ZZZZ", "coefficient": 1.0},
{"pauli": "XIII", "coefficient": -1.0}]}
每一项都会作为单独一行返回,其中包含其 coefficient 和对应的值,因为这是 SDK 的计算方式——它逐项计算求和,不会汇总。因此,⟨H⟩ 需要由调用方自行计算:
energy = sum(row["coefficient"] * row["value"][0] for row in rows)
这是有意为之,而非图方便。在此处计算总值,会得到一个 SDK 从未生成、此服务也无法归属来源的数字;逐项返回的行则让结果可审计——你可以看出哪一项占主导。只有 SDK 为其添加了 coefficient 的行才会显示 coefficient,也就是说,只有加权期望的各项才会显示。
coefficient 必须是实数。不接受符号:Z(0) * Parameter 构造的是参数表达式,而非可观测量,因此没有可计算的内容——应先绑定电路的门。单个未加权项仍写作 "pauli": "ZZ",这两种写法共用同一条代码路径,因此不会出现行为不一致。
优化能量
simulate_circuit_tool 会计算能量。train_parameters_tool 会对其进行优化,使用状态向量模拟报告的精确梯度:
{
"circuit": "[{\"name\": \"ry\", \"index\": [0], \"parameters\": {\"theta\": {\"$parameter\": \"t0\"}}}]",
"circuit_format": "qir",
"hamiltonian": [{"pauli": "Z", "coefficient": -1.0}, {"pauli": "X", "coefficient": 1.0}],
"steps": 100,
"learning_rate": 0.1
}
它会返回每一步之后的损失、最终参数以及初始参数。若要继续运行而非重新开始,请再次调用,并将 values 设为它返回的 parameters。
hamiltonian 参数与 expectation 输出所使用的项列表相同,而且是必填项:没有目标函数,被最小化的数值就不是能量。每条线路对应一个字母——上面的电路只有一条线路,因此每项都是一个字母。双线路电路需要使用 "ZZ";长度与电路不匹配的项会在运行前被拒绝。
调用前有两个限制值得了解。训练的开销远高于模拟——实测中,16 量子比特的一步需要 85 ms,而模拟只需几毫秒——因此,若预测开销超过 FLAGQUANTUM_MCP_MAX_TRAIN_SECONDS,运行会在开始前被拒绝,提示信息中会包含预测值、宽度和步数。在宽度范围的高端,主要开销来自保持状态:模型预测 24 条线路时,每步需要 25.2 s,甚至还没应用任何门,因此任何 24 线路电路最多只能运行两步;而这里实测的分层 Ansatz 有 71 条指令,预测每步需要 119 s,因此一步也无法运行。这与电路有关,而非宽度:24 条线路上的一个门仍在预算范围内;预算是按预测开销而非宽度拒绝运行,因此,较窄但层数很多的电路也会因此受到限制——一个含 2500 条指令的四线路电路,预测每步需要 0.5 s,按默认预算可运行 119 步;而相同宽度下仅含一个门的电路则可运行三千步。
结果就是它所呈现的内容:一条损失曲线和一组角度。运行是否收敛由你来判断,而非此工具所宣称;SDK 的 accuracy.metric == "not_measured" 会与执行结果一同返回,与模拟时完全相同。
依赖的契约
FlagQuantum 发布了冻结的 stable_exports 快照(包含 31 个名称,每个名称都有对应的命名验证测试),将 flagquantum.compiler 描述为其“稳定的专家编译器接口”,并允许每个包声明自己的 __all__。本服务使用了这三个层级,tests/test_api_contract.py 会固定每个层级的成员:
| 层级 | 接口 | 用途 |
|---|---|---|
| 1. 冻结快照 | Circuit、CircuitIR、Instruction、IR_VERSION、ExecutionOptions、ExecutionPlan、plan、Parameter、RuntimePolicy、… | 分析、序列化、反序列化、规划、检查/绑定参数、train_parameters |
| 2. 有文档说明的模块 | flagquantum.compiler:CouplingMap、optimize、route_to_topology、schedule_layers | 优化、路由、比较、描述层 |
| 3. 公开但未冻结 | flagquantum.compiler.openqasm.emit_openqasm、flagquantum.compiler.qcis.emit_qcis、flagquantum.drawer.draw、flagquantum.core.{operator_manifest,gate_info,canonical_opcode}、flagquantum.algorithms.{Hamiltonian, pauli_term} | emit_openqasm、emit_qcis、draw、门验证、train_parameters |
第 3 层最不可靠,但它并非可有可无。 门验证需要知道每个门的线路数量和参数名称,而 SDK 的运算符清单是唯一的权威来源;调用方无法从电路格式推断这些信息,在这里重新实现则会产生第二个事实来源,最终出现偏差。我们通过一个辅助函数访问该清单,在名称被迁移时返回明确错误,而不是在工具调用内部触发 AttributeError。每个第 3 层名称都由测试固定,因此上游迁移会导致构建失败,而不是让用户遇到问题。我们要防范的是不易察觉的故障:较宽松的门检查会接受拼写错误的参数并将其丢弃。
训练工具是唯一一个无法只靠这三个层级说明的地方。它的目标函数需要两个未冻结的名称——来自 flagquantum.algorithms 的 Hamiltonian 和 pauli_term——以及一个已冻结的名称:RuntimePolicy 位于冻结快照中,但快照只固定名称。哈密顿量是否会传入运行过程,取决于 RuntimePolicy().observable;它的默认值是 "z"。因此,tests/test_api_contract.py 也会固定该默认值,而不是假定快照会包含它。
依赖项固定为 flagquantum>=0.3.1,<0.4。这是一个版本范围,绝不能使用 Git URL:依赖表中的 URL 会导致安装不同上游修订版本的环境均无法解析依赖。
能力覆盖决策
contracts/sdk-capability-coverage-v1.json 记录了固定的、位于 #632 之后的 FlagQuantum 源码清单中每项生产支持或经发布认证的能力的决策。FlagQuantum 0.3.1 是首个发布的兼容核心 wheel。每项决策要么列出本服务范围受限的工具接口,要么说明为何不公开工具。现有的绘图工具单独记录为遗留实验性例外;该清单不授权添加其他实验性工具。CI 检查器会将这些决策与固定的上游 capability-maturity.toml 以及服务声明的工具接口进行比对。新增符合条件的能力或 MCP 工具若没有对应决策,检查就会失败。
这份清单是暴露面审计,并不表示每个 Python 函数都能通过 MCP 使用。它也不能替代已安装包的兼容性测试:当前的 flagquantum>=0.3.1,<0.4 依赖项由测试矩阵和全新安装 wheel 后的 MCP 握手分别验证。仅有源代码映射并不授权添加新工具,也不能证明未来版本的 FlagQuantum 可正常运行。
要在本地检查固定的源代码,请检出 FlagQuantum 的提交
5c78e1d3b3fad31af5bce9e785ca8a1954229cf7,然后运行:
python tools/check_capability_coverage.py --upstream-root /path/to/FlagQuantum
开发
python3 -m venv .venv
.venv/bin/python -m pip install -e ".[dev]"
.venv/bin/ruff check .
.venv/bin/ruff format --check .
.venv/bin/mypy --config-file ../mypy.ini src
.venv/bin/pytest -m "not integration"
请参阅仓库 README和 CONTRIBUTING.md。
许可证
Apache-2.0。
评论
一个开放协议,规定了 AI 应用如何以统一方式连接外部工具与数据源。客户端负责与模型对话,MCP 服务负责提供工具、资源和提示模板,两者通过标准消息通信,同一个服务可以被不同客户端复用。