☰
内容复习---高精度空间数据分析(CODEX、CosMx、IMC)与 TaoToken 统一 Key 配置
2026/10/3 6:32:12 网站建设 项目流程

1. 空间组学复习为什么总卡在环境与通道上

CODEX、CosMx、IMC 这三类高精度空间数据分析,本质上都在回答同一个问题:细胞在组织里到底怎么排布、谁挨着谁、不同分组之间邻域结构差在哪。CODEX 靠抗体面板循环染色拿到蛋白层面的空间坐标,CosMx 用原位杂交把转录本定位到亚细胞级别,IMC 则是金属同位素标记的成像质谱。数据模态不同,但落到分析流程上,都会汇聚到 AnnData 对象、空间邻接图、邻域富集、空间特征打分这几步。

我复习这套流程时最烦的不是算法本身,而是每次换工具就要重新配一遍 API 通道。比如用 CellCharter 算邻域富集、用 Squidpy 做空间邻接、用 Scanpy 打分,中间如果还想接一个大模型辅助解读结果或者跑个 coding agent 帮你改脚本,就得在好几个平台之间来回切 Key。空间组学研究者本来就有一堆湿实验和干分析要盯,Key 管理这种杂事不该占精力。

这篇复习笔记的目标很明确:把 CODEX、CosMx、IMC 三类数据的核心分析步骤串一遍,同时把多工具调用的 API 通道统一到 TaoToken 一个 Key 上。你跟着做,既能复习邻域组成、邻域差异、空间特征分数这三块,又能顺手把 API 接入规范化。适合已经跑过单细胞或空间转录组、想系统梳理空间分析流程的人,也适合刚接触 CODEX/CosMx/IMC 想找一条可复制路径的人。

先说清楚一个概念:TaoToken 是一个统一 API 网关,它把不同模型和工具的调用入口收敛成一个 Base URL 加一个 Key。你不需要在每个工具里单独填不同的 endpoint,只要把 Base URL 指向https://taotoken.net/api,用同一个 Key 就能调通。对空间组学这种经常要混用 Python 脚本、Notebook、coding agent 的场景,省掉的就是反复找 Key、改配置的时间。

下面按复习顺序走:先讲三类数据的分析目标,再讲 TaoToken 前置准备,然后给可复制的配置片段,接着做一次完整调用验证,最后把常见报错列出来对照排查。

2. CODEX、CosMx、IMC 三类数据的分析目标拆解

复习空间数据分析,先把目标拆成三层,后面写代码才不会乱。

第一层是目标细胞的邻域组成。你有一个感兴趣的细胞类型,比如肿瘤细胞或者某个免疫亚群,想知道它周围一圈邻居都是谁、比例多少。CellCharter 的nhood_enrichment就是干这个的,它基于空间邻接图统计每个 cluster 的邻居 cluster 分布,再用置换检验算富集或耗竭。CosMx 数据里常见的是cluster_20这种聚类标签,CODEX 里可能是cluster_11映射到spatial_cluster,IMC 里则是细胞表型标签。不管标签叫什么,思路一致:先建空间邻接,再算邻域富集矩阵。

第二层是不同组的邻域差异。比如 BALBc 健康脾脏 vs MRL 系统性红斑狼疮脾脏,或者不同 patient 之间。CellCharter 的diff_nhood_enrichment直接对比两组条件,输出差异邻域富集图。这一步的关键是condition_key和condition_groups要对应上,library_key用来处理多样本拼接后的批次。CosMx 数据里如果按 patient 分组,逻辑一样,只是条件列名不同。

第三层是空间特征分数。你有一组基因签名,比如细胞因子互作、EMT、缺氧、增殖,想在空间上给每个细胞打分,再平滑到邻域级别看空间分布。Scanpy 的score_genes负责单细胞打分,Squidpy 的spatial_neighbors建邻接,然后用邻接矩阵做加权平均平滑。平滑之后用spatial_scatter画出来,就能看到某个签名在组织切片上的空间梯度。

这三层目标对应到代码上,就是 excerpt 里那两大部分:第一部分是 CosMx 的邻域富集加空间特征打分平滑,第二部分是 CODEX 的邻域富集加组间差异。IMC 的数据结构类似,只是读取的 h5ad 文件名和 obs 列名不同,分析函数调用基本可以复用。

我试过把这套流程拆成独立脚本,每个脚本负责一层,中间用 h5ad 传递。这样复习的时候可以单独跑某一层,不用每次从头读数据。但脚本一多,如果每个脚本里都硬编码 API Key 就很危险,也不方便换模型。所以下一步先把 TaoToken 的 Key 和 endpoint 统一管起来。

3. TaoToken 统一 Key 配置与可复制片段

TaoToken 的接入逻辑很简单:一个 Base URL,一个 API Key,模型 ID 按需选。Base URL 固定用https://taotoken.net/api,注意这里不加任何查询参数。Key 在控制台生成,生成后只显示一次,记得存到环境变量或者本地配置文件里,别直接写进脚本提交到 git。

先做前置准备。打开 TaoToken 控制台,路径是https://taotoken.net/console?utm_source=taotoken_aicg_blog_end&utm_medium=csdn&utm_campaign=rewrite&utm_content=console,登录后在 API Keys 页面创建一个新 Key。创建时给它起个能认出来的名字,比如spatial-omics-review,方便以后区分。创建完复制 Key,存到本地。

接下来配置环境变量。Linux 或 macOS 在~/.zshrc或~/.bashrc里加一行,Windows 在系统环境变量里加。这样所有 Python 脚本和命令行工具都能读到,不用在每个文件里重复写。

export TAOTOKEN_API_KEY="sk-你的实际Key" export TAOTOKEN_BASE_URL="https://taotoken.net/api"

如果你用的是 Claude Code 或者类似的 coding agent,它需要一个 settings 文件来读配置。Claude Code 的配置文件通常在~/.claude/settings.json,内容如下。注意 Base URL 和 Key 都要填对,Model ID 按你实际要用的模型填。

{ "env": { "ANTHROPIC_BASE_URL": "https://taotoken.net/api", "ANTHROPIC_API_KEY": "sk-你的实际Key", "ANTHROPIC_MODEL": "claude-sonnet-4-20250514" } }

如果你用的是 Codex 类的工具,它读~/.codex/auth.json,格式如下。这里同样要写全三件套:Base URL、Key、Model ID。

{ "base_url": "https://taotoken.net/api", "api_key": "sk-你的实际Key", "model": "gpt-4.1" }

Cline 或者带 MCP 的编辑器插件,配置入口在插件的设置里,填三个字段:API Provider 选 OpenAI Compatible,Base URL 填https://taotoken.net/api,API Key 填你的 Key,Model ID 填你要用的模型。保存后插件会自己发一次测试请求,通了就能用。

Python 脚本里读取环境变量,用os.environ就行。下面这段是给空间分析脚本加一个辅助解读函数的示例,它不参与 CellCharter 或 Squidpy 的计算,只在你想让模型帮你解释邻域富集结果时调用。

import os import requests TAOTOKEN_BASE_URL = os.environ.get("TAOTOKEN_BASE_URL", "https://taotoken.net/api") TAOTOKEN_API_KEY = os.environ["TAOTOKEN_API_KEY"] def ask_model(prompt: str, model: str = "claude-sonnet-4-20250514") -> str: url = f"{TAOTOKEN_BASE_URL}/v1/messages" headers = { "x-api-key": TAOTOKEN_API_KEY, "anthropic-version": "2023-06-01", "content-type": "application/json", } payload = { "model": model, "max_tokens": 1024, "messages": [{"role": "user", "content": prompt}], } resp = requests.post(url, headers=headers, json=payload, timeout=60) resp.raise_for_status() data = resp.json() return data["content"][0]["text"]

这段代码里 endpoint 是/v1/messages,对应 Anthropic 风格的接口。如果你用的是 OpenAI 兼容接口,endpoint 换成/v1/chat/completions,headers 里用Authorization: Bearer <Key>。两种都走同一个 Base URL,Key 也是同一个。

配置写完先别急着跑分析,做一次最小验证,确认通道是通的。下一节给完整验证动作。

4. 一次完整调用验证与空间分析串联

验证分两步:先验证 API 通道,再验证空间分析脚本能正常跑。两步都过了,说明环境和通道都没问题。

第一步,用 curl 发一个最小请求。把 Key 换成你自己的,模型 ID 换成你控制台里可用的。

curl -s https://taotoken.net/api/v1/messages \ -H "x-api-key: $TAOTOKEN_API_KEY" \ -H "anthropic-version: 2023-06-01" \ -H "content-type: application/json" \ -d '{ "model": "claude-sonnet-4-20250514", "max_tokens": 64, "messages": [{"role": "user", "content": "回复 OK 两个字母"}] }'

正常返回是一个 JSON,content数组里第一项的text字段应该是OK或者类似短回复。如果返回 401,说明 Key 不对或者没读到环境变量;如果返回 404,说明 endpoint 拼错了;如果返回 429,说明触发了限流,等一会儿再试。

第二步,跑一段空间分析验证脚本。这段脚本用 CosMx 数据做邻域富集,逻辑和 excerpt 第一部分一致,但精简到最小可跑。你需要准备一个cosmx.h5ad,obs 里有sample、patient、cluster_20这几列。

import anndata as ad import cellcharter as cc import matplotlib.pyplot as plt adata = ad.read_h5ad("cosmx.h5ad") adata.uns["spatial"] = {s: {} for s in adata.obs["sample"].unique()} adata_sample = adata[adata.obs["patient"] == "Lung5"].copy() cc.gr.nhood_enrichment( adata_sample, cluster_key="cluster_20", ) cc.pl.nhood_enrichment( adata_sample, cluster_key="cluster_20", row_groups=[4, 7], col_groups=[1, 8, 10, 11, 16, 17], vmin=-0.5, vmax=0.5, min_freq=0.001, transpose=True, ) plt.savefig("nhood_enrichment_lung5.png", dpi=150, bbox_inches="tight")

跑通后你会得到一张邻域富集热图,横轴和纵轴是 cluster 编号,颜色深浅代表富集或耗竭程度。row_groups和col_groups用来聚焦你关心的 cluster 子集,vmin/vmax控制色阶范围,min_freq过滤掉出现频率太低的 cluster。

第三步,把空间特征打分和平滑串进来。这段对应 excerpt 里的score_cells和smooth_signature,我把它整理成可直接调用的形式。

import numpy as np import pandas as pd import scanpy as sc import squidpy as sq def score_cells(adata, signature_name, genes): adata.obs[f"score_{signature_name}"] = np.nan for patient in adata.obs["patient"].cat.categories: adata_patient = adata[adata.obs["patient"] == patient].copy() valid_genes = [g for g in genes if g in adata_patient.var_names] sc.tl.score_genes( adata_patient, gene_list=valid_genes, score_name=f"score_{signature_name}", ) adata.obs.loc[ adata.obs["patient"] == patient, f"score_{signature_name}", ] = adata_patient.obs[f"score_{signature_name}"].values def smooth_signature(adata, signature_name, n_neighbors, group_key=None, groups=None): if groups: adata_groups = adata[adata.obs[group_key].isin(groups)].copy() sq.gr.spatial_neighbors( adata_groups, library_key="sample", n_neighs=n_neighbors, coord_type="generic", ) adata_groups.obsp["spatial_connectivities"].setdiag(1) adata.obs[f"score_{signature_name}_smoothed"] = np.nan for patient in adata_groups.obs["patient"].cat.categories: sub = adata_groups[adata_groups.obs["patient"] == patient] adj = sub.obsp["spatial_connectivities"] score = sub.obs[f"score_{signature_name}"].values smoothed = (adj @ score) / np.array(adj.sum(axis=1)).squeeze() smoothed[smoothed == float("inf")] = 0 low = np.nanpercentile(smoothed, 5) smoothed[smoothed < low] = low high = np.nanpercentile(smoothed, 95) smoothed[smoothed > high] = high mask = (adata.obs["patient"] == patient) & (adata.obs[group_key].isin(groups)) adata.obs.loc[mask, f"score_{signature_name}_smoothed"] = smoothed

调用时先准备签名字典,再循环打分和平滑。

signatures = pd.read_excel("data/tumor_cell_state_signatures_gavish.xlsx") signatures.columns = [ c.replace("/", "").replace(" ", "_").replace(" - ", "-") for c in signatures.columns ] signatures_dict = signatures.to_dict(orient="list") signatures_names = [ "MP13_EMT-II", "MP6_Hypoxia", "Cell_Proliferation", ] for name in signatures_names: score_cells(adata, name, signatures_dict[name]) smooth_signature(adata, name, 50, "cell_type_reduced", ["tumor"])

跑完检查adata.obs里有没有score_MP13_EMT-II_smoothed这类列,有就说明打分和平滑都成功了。最后用sq.pl.spatial_scatter画出来,color传平滑后的列名,cmap用Spectral_r,ncols=4一行排开。

到这里,API 通道验证和空间分析验证都完成了。如果你在跑的过程中遇到报错,下一节对照排查。

5. 常见报错对照与排查路径

空间分析脚本本身报错和 API 通道报错要分开看。先列 API 侧的。

401 Unauthorized 最常见。原因通常是 Key 没读到、Key 复制时带了空格、或者环境变量没生效。排查方法:在终端里echo $TAOTOKEN_API_KEY,看输出是不是完整的 Key。如果是空的,说明~/.zshrc没 source,执行source ~/.zshrc再试。如果 Key 末尾有换行或空格,重新复制一次。

local proxy failed 这类报错,通常出现在你本地网络环境有额外代理设置的时候。TaoToken 的 Base URL 是直连的,不需要额外代理。检查你的 shell 里有没有http_proxy或https_proxy环境变量,有的话临时 unset 掉再跑。Python 的 requests 库也会读这些变量,可以在脚本开头加os.environ.pop("http_proxy", None)和os.environ.pop("https_proxy", None)。

reading choices 报错一般出现在 OpenAI 兼容接口的响应解析上。如果你用/v1/chat/completions,返回结构是data["choices"][0]["message"]["content"];如果你用/v1/messages,返回结构是data["content"][0]["text"]。两种接口的解析路径不一样,混用就会报 KeyError。检查你的解析代码和 endpoint 是否匹配。

OAuth 相关报错,通常出现在 Claude Code 或 Codex 这类工具里。这些工具默认可能走 OAuth 登录流程,如果你在 settings 里填了 API Key 但工具还在尝试 OAuth,就会冲突。解决办法是在 settings 里明确指定 API Key 模式,Claude Code 用ANTHROPIC_API_KEY,Codex 用auth.json里的api_key字段。填完之后重启工具,让它重新读配置。

空间分析侧的报错,列几个高频的。

KeyError: 'spatial'出现在 Squidpy 建邻接的时候。原因是adata.uns["spatial"]没设置。CosMx 和 CODEX 数据读进来后,如果 h5ad 里没带 spatial 信息,需要手动补一个空字典,key 是 sample 名。excerpt 里那行adata.uns['spatial'] = {s: {} for s in adata.obs['sample'].unique()}就是干这个的。

ValueError: cannot reorder categories出现在cat.reorder_categories的时候。原因是你要 reorder 的类别列表和实际类别不完全一致。先用adata.obs["spatial_cluster"].cat.categories打印实际类别,再对照cluster2region.values()看差在哪。CODEX 数据里cluster_11映射到spatial_cluster时,映射字典的 value 顺序要和 reorder 列表一致。

IndexError: index out of bounds出现在spatial_scatter画图的时候。通常是library_id和library_key对不上,或者adata_sample.obsm["spatial"]的维度不对。检查adata_sample.obsm["spatial"].shape,应该是(n_cells, 2)。如果 y 轴方向反了,用np.max(y) - y翻转一下,excerpt 里就有这行。

MemoryError出现在大样本平滑的时候。spatial_neighbors建的邻接矩阵是稀疏的,但adj @ score如果 adj 没转稀疏格式,会爆内存。确认adata_groups.obsp["spatial_connectivities"]是 scipy 稀疏矩阵,不是 dense array。如果是 dense,用scipy.sparse.csr_matrix转一下。

排查顺序建议:先确认 API 通道通不通,再确认数据读进来 obs 列名对不对,最后确认空间邻接和矩阵运算的维度。三步都过了,基本不会有大问题。

6. 把统一 Key 接入你的空间分析工作流

复习到这里,CODEX、CosMx、IMC 三类数据的核心分析步骤已经串完了。邻域组成用nhood_enrichment,组间差异用diff_nhood_enrichment,空间特征分数用score_genes加spatial_neighbors平滑。这三块是空间数据分析的骨架,换数据模态只是换 obs 列名和 h5ad 文件名,函数调用逻辑可以复用。

TaoToken 统一 Key 的价值在于,你不需要为每个工具单独维护一套认证。Base URL 固定https://taotoken.net/api,Key 存环境变量,Model ID 按需切换。Claude Code、Codex、Cline MCP 这些工具的配置三件套都是 Base URL、Key、Model ID,填一次就能长期用。如果你要长期跑 coding agent 辅助写分析脚本,可以看看 Coding Plan 的接入方式,路径是https://taotoken.net/coding-plan?utm_source=taotoken_aicg_blog_end&utm_medium=csdn&utm_campaign=rewrite&utm_content=coding-plan。如果你只是想验证某个模型对空间结果的解读能力,用模型对话入口更快,路径是https://taotoken.net/chat?utm_source=taotoken_aicg_blog_end&utm_medium=csdn&utm_campaign=rewrite&utm_content=chat。Key 管理和文档在https://taotoken.net/api-keys?utm_source=taotoken_aicg_blog_end&utm_medium=csdn&utm_campaign=rewrite&utm_content=api-keys和https://taotoken.net/doc?utm_source=taotoken_aicg_blog_end&utm_medium=csdn&utm_campaign=rewrite&utm_content=doc。

最后给一个实用技巧:把空间分析脚本里的 API 调用部分抽成一个独立模块,比如llm_helper.py,里面只放ask_model函数和配置读取。这样你的分析脚本不依赖具体 Key,换 Key 只改环境变量,脚本本身不用动。复习的时候也可以单独测这个模块,确认通道没问题再跑重计算,省得算到一半发现 Key 过期。

空间组学的数据量只会越来越大,CODEX 和 CosMx 的单样本细胞数经常到几十万,IMC 的多通道图像也不小。把通道配置规范化,省下来的时间可以多跑几组邻域差异对比。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询