mcpField
F
FlagQuantum MCP Server

FlagQuantum MCP Server

本地服务
github.com科研与教育02 天前更新

关于 FlagQuantum MCP Server

FlagQuantum MCP Server 为 MCP Agent 提供本地 FlagQuantum SDK 工具,用于构建、编译、路由、导出和模拟量子电路,也支持本地研究能力执行。工具在本地进程内运行,不调用外部服务或提交硬件任务。

主要功能

  1. 01分析和序列化量子电路
  2. 02优化、编译并路由电路
  3. 03导入与导出 OpenQASM、QCIS
  4. 04本地模拟及 Lindblad 演化
  5. 05训练参数并规划执行
  6. 06检索、验证和执行本地研究能力

适用场景

  1. 01分析电路门数、深度和线路使用情况
  2. 02针对目标拓扑编译和比较电路
  3. 03本地运行模拟或动力学演化
  4. 04验证并执行获准的本地研究请求

MCP 相关

作为 MCP 服务,通过 stdio 或 Streamable HTTP 暴露 FlagQuantum 的电路、模拟和研究能力工具,并提供资源与提示词。所有工具在本地运行,不访问外部网络。

配置

本地服务的配置在各客户端中通用,复制后粘贴到客户端的 MCP 配置文件即可。

mcp.json · 通用配置
{
"mcpServers": {
"flagquantum-flagquantum": {
"command": "uvx",
"args": [
"flagquantum-mcp-server"
],
"env": {
"FLAGQUANTUM_MCP_MAX_QUBITS": "<FLAGQUANTUM_MCP_MAX_QUBITS>",
"FLAGQUANTUM_MCP_MAX_GATES": "<FLAGQUANTUM_MCP_MAX_GATES>",
"FLAGQUANTUM_MCP_MAX_IR_BYTES": "<FLAGQUANTUM_MCP_MAX_IR_BYTES>"
}
}
}
}
启动命令uvx flagquantum-mcp-server
需要配置的环境变量
FLAGQUANTUM_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+)。各客户端的配置文件位置不同,请参考客户端文档。

安装包
pypiflagquantum-mcp-server0.3.2

工具

17

收录的工具列表 · 更新于 1 天前

参数类型必填说明
circuitstring是电路载荷。使用 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_formatenum否"ir" 表示 FlagQuantum IR JSON,"qir" 表示门列表。ir | qir

详细介绍

FlagQuantum MCP 服务

MCP Registry

一个 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 协议。

标志默认值含义
--transportstdiostdio 或 http。默认值不变,因此现有可用配置无需修改
--host127.0.0.1要绑定的接口。默认绑定回环接口,避免服务端意外变得可访问
--port8105要绑定的端口
--allowed-hostnone服务端会响应的 Host 标头,可重复指定
--allowed-originnone服务端会响应的浏览器 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_QUBITS24电路宽度
FLAGQUANTUM_MCP_MAX_GATES10000指令数量
FLAGQUANTUM_MCP_MAX_IR_BYTES262144序列化电路载荷
FLAGQUANTUM_MCP_MAX_QASM_CHARS1000000生成的程序大小
FLAGQUANTUM_MCP_MAX_COMPARE_TOPOLOGIES4每次比较的拓扑数量
FLAGQUANTUM_MCP_MAX_TRAIN_SECONDS60单次训练调用的预测耗时
FLAGQUANTUM_MCP_MAX_RESPONSE_VALUES65536单个结果可返回的值数量
FLAGQUANTUM_MCP_MAX_HAMILTONIAN_TERMS1024每个期望值请求中的 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 时同时提供 outputsSDK 只接受其中一项,并用不包含任一字段名称的说法说明了这一点

完整概率分布停止返回的宽度上限,取决于 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。

评论

支持 Markdown

第一次接触 MCP?

从协议是什么,到在客户端里装上第一个服务,这几条回答覆盖了大多数入门问题。

一个开放协议,规定了 AI 应用如何以统一方式连接外部工具与数据源。客户端负责与模型对话,MCP 服务负责提供工具、资源和提示模板,两者通过标准消息通信,同一个服务可以被不同客户端复用。