为什么一家圣经出版商要自建汇率服务
每家跨国销售的公司都会遇到同样一个反复出现的小问题:这笔金额在今天价值几何?在开票那天又价值几何?对于一家以美元、欧元和英镑结算的挪威出版商而言,这个问题每周都会出现好几次——在会计记账、定价制定、合同起草中,在与协助起草报价单的 AI 助手的对话中。
市面上有成百上千个汇率 API。但我们依然决定自建。以下是关于我们为何自建、成本如何、它能做什么以及何时你应该使用其他服务的如实说明。
大多数汇率指南注意到了什么——又忽略了什么
大多数货币 API 的对比评测,都会根据支持的货币种类数量、更新频率以及每千次调用的价格对服务商进行排名。如果你正在选购服务,这些确实是该问的问题。但如果你正在构建打算长期维护的基础设施,这些问题就问错了方向。
它们极少问及的是:谁才是权威数据源(source of truth)?以及在数据源没有发布数据的日子里,会发生什么?几乎所有商业汇率数据源都会抹平空缺。如果某家央行在周日没有发布任何数据,API 依然会返回一个数值,因为对客户来说,空白响应看起来就像是出了 bug。那个数值其实是伪装成事实的插值;一旦它进入你的账本,你就无法将二者区分开来。
我们的结论是:对于会计和合同而言,缺失的汇率远比捏造的汇率有用得多。
为什么我们选择自建而非采购
原因有三点,按重要程度排列:
单一权威数据源。 挪威央行发布挪威克朗的官方汇率。对于一家挪威公司而言,这些数字是税务机关、审计机构和法院都认可的标准。任何其他数据源都只是经由中间商转手的一份副本。
不为我们自己的算术付费。 该服务响应来自其他 Publifye 系统(定价、开票、报表)的数千次内部调用,我们不希望央行免费发布的数字还要被按次计费。
我们的 AI 助手需要直接使用它。 我们技术栈中的每项服务都支持 Model Context Protocol,因此助手可以在对话过程中即时查询真实汇率,而不是从训练数据中去回忆。AI 记住的汇率来自未知的日期,这比没有汇率还要糟糕。
这项服务到底是什么
Currency Exchange 是我们运行的最小服务。它每天通过挪威央行的 SDMX API 进行同步,并以三种方式提供结果:一个公开网站、一个小型只读 Web API,以及供 AI 助手使用的 MCP 工具。
| 属性 | 具体说明 |
|---|---|
| 数据来源 | 挪威央行 SDMX REST API,挪威官方汇率 |
| 货币种类 | 38 种对克朗货币,包括 I-44、TWI 和国际货币基金组织特别提款权(SDR)指数 |
| 历史数据 | 大约追溯至 1980 年,存储了 326,970 条每日观测数据 |
| 发布时间 | 挪威央行在工作日欧洲中部时间 16:00 左右发布 |
| 数据空缺 | 保持空缺;该服务绝不进行插值计算 |
| 购买力指数 | 基于世界银行数据,涵盖 202 个国家,1990 年至 2025 年 |
| 交互接口 | 网站、只读 JSON API 以及八个 MCP 工具 |
拒绝填补空缺是一切设计决策的出发点。在挪威公众假期,由于没有汇率,服务就会如实说明。当你在周末换算金额时,它最多会回溯五天找到最近一次发布的真实汇率,并明确告知你它使用的是哪个日期的汇率。
工程实现:小型服务如何保持稳定运行
一项服务只有在运行起来足够省心时,才值得去构建。三个选择让这项服务变得毫无负担。
无需网络即可启动
完整的汇率历史数据作为压缩数据打包在二进制文件内部,因此一个全新的容器在启动瞬间就能正确回答请求。随后它从数据库预热,并在后台从挪威央行拉取补全任何缺失的数据。这排除了服务处于运行状态却返回错误数据的窗口期。
双层缓存机制
读取操作直接来自内存中已知的汇率映射表。它背后的数据库负责持久化存储和写入路径,而非读取路径。汇率查询实际上就是一次 map 查找。
故障倾向于沉默,而非倾向于捏造
如果挪威央行无法访问,昨天的数据依然保持准确,今天的数据则直接保持缺失。代码路径中没有任何逻辑会去凭空制造一个数字。
购买力指数:因国定价,而非因币定价
换算价格只是算术问题。给产品定价则不然。
一本定价 249 克朗的书在奥斯陆很寻常,在马尼拉却很昂贵,而汇率不会告诉你这一点。因此,该服务还包含一个基于涵盖 202 个国家的世界银行数据构建的购买力指数,这让我们的商店能够根据当地购买力调整价格,而不是简单地换算数字。
这是普通货币 API 无法为你提供的部分,因为这根本不是一个单纯的货币问题。这关乎在某个国家真正销售产品,还是仅仅在那里露个面而已。
你的 AI 如何使用它
将该服务连接到助手后,助手就可以直接使用这些工具:
| 工具 | 解决的问题 |
|---|---|
| get_rate | 单一货币在某一特定日期的汇率 |
| convert | 将金额从一种货币换算为另一种货币,通过克朗进行交叉换算 |
| get_rates_range | 特定日期范围内的时间序列数据,用于图表和趋势分析 |
| get_all_rates | 单一日期的所有汇率 |
| list_currencies | 38 种货币代码及其名称 |
| get_buying_power | 单个国家的购买力指数 |
| list_buying_power | 完整的国家购买力指数列表 |
| service_status | 服务健康状况、版本信息以及最近一次同步时间 |
无需创建 API 密钥,也无需安装客户端。连接方式与我们技术栈中的其他服务完全相同,我们在你的 AI 如何连接到 Darash、Junifye 和 Lexifye一文中做过详细说明。
何时你应该选择其他服务
我们宁愿开门见山地说清楚,也不愿让你在使用后才发现不合适。
你需要实时交易汇率。 这些是每日参考汇率,每个工作日仅发布一次。如果你在执行交易,你需要的是市场行情数据源,而不是央行参考汇率。
你的业务不锚定克朗。 这里的每个汇率都是对挪威克朗进行标价的。另外两种货币之间的交叉汇率是通过克朗折算出来的,这种方法虽然正确,但增加了一步换算过程。如果你的业务与挪威完全没有交集,以欧元或美元为基准的数据源会更加适合。
你需要我们未收录的货币。 挪威央行仅发布 38 种货币的汇率。它并不涵盖全世界的所有货币。
这与出版商有什么关系
询问一家出版圣经的公司为什么要运行货币服务,是很合理的疑问。
答案在于:基础设施本身也是产品的一部分。我们通过自己的在线商店,在许多国家以多种货币销售图书。要正确制定价格,就需要汇率和购买力数据。开具发票需要审计机构认可的特定历史日期的汇率。我们自己的 AI 助手在回答与金钱相关的问题时,绝不能产生幻觉去凭空捏造数字。
我们技术栈中的每项服务都是基于类似的原因而存在的。圣经引擎只是冰山水面上的可见部分。Darash 用于希伯来语和希腊语研究。Junifye 负责图书出版。而一个小型服务则在后台安静地回答:在签署合同的那一天,一美元究竟值多少钱。
常见问题解答
汇率数据来自哪里?
来自挪威央行(Norges Bank,挪威的中央银行)的公开 SDMX API。这些是挪威官方的基准汇率。
汇率多久更新一次?
每个工作日更新一次,在欧洲中部时间 16:00 左右发布。周末或挪威法定节假日没有汇率,因为央行在这些日期不发布数据。
如果我查询周末日期的汇率会发生什么?
换算逻辑会向前回溯最多五天,寻找最近一次发布的汇率,并明确告诉你它实际使用的是哪一天的汇率。你绝不会在不知情的情况下收到一个捏造出来的数字。
历史数据可以追溯到多久以前?
大约追溯至 1980 年,也就是挪威央行数据序列的最早起点。涵盖 38 种货币,总计约 326,970 条每日观测数据。
可以免费使用吗?
网站和只读 API 是公开的,无需登录。通过 MCP 进行的 AI 访问提供用于评估的免费额度,超出后有付费方案。
我可以用它做会计记账吗?
这正是它被构建出来的初衷。这些汇率是挪威官方汇率,严格对应其发布的具体日期,并且该服务不会在没有数据的日期凭空编造汇率。
购买力指数有什么用途?
用于定价。它利用涵盖 202 个国家的世界银行数据,反映特定金额在某个国家实际拥有的价值,从而使价格能够契合当地购买力,而不仅仅是做简单的数值换算。
最终结论
Currency Exchange 并不是一个多么精巧复杂的微服务。它每天抓取一次公开数据集,拒绝无根据地猜测,并将结果提供给网站、API 和 AI 助手。
这正是其全部意义所在。在基础设施领域,那些你从来不需要费心去想的组件,才是构建得恰到好处的组件。如果你想看看它的实际效果,汇率数据和换算器均已公开,无需注册账户即可查看。
我们发布新内容时给您发邮件。 订阅新闻通讯