1. 从零搭一个 Beancount 记账 Web 应用,为什么值得用 Claude Code 来做
Beancount 是一个纯文本复式记账工具,账本就是一个.bean文件,每一笔收支都写成一行行结构化文本。它的好处是数据完全归你、可版本管理、可脚本化;但痛点也很明显——官方只提供命令行,想看个「本月餐饮花了多少」「资产趋势图」得自己写查询、自己搭前端。对不写代码的人来说,这一步基本就卡死了。
我这次想验证的事情很具体:能不能让 Claude Code 把「解析 Beancount 账本 + 起一个 Web 页面展示」这条链路全部写完,我只负责描述需求和点确认。答案是能,但前提是把模型通道配置对——Claude Code 默认走 Anthropic 官方接口,国内直连经常超时,所以我用 TaoToken 的统一 Key 和 Base URL 把它接上,后面所有代码生成、文件读写、命令执行都由 Claude Code 在终端里完成。
这篇适合三类人:一是用 Beancount 记账但不会写前端的;二是想体验 Claude Code 但卡在接入配置的;三是想找一个「零代码也能跑通」的 AI 编程实战案例的。全程你只需要复制配置、粘贴提示词、按回车。下面从环境准备讲到页面跑起来,每一步都给可复制的命令和配置。
2. 前置准备:TaoToken 统一 Key 接入 Claude Code 的完整配置
Claude Code 是一个跑在终端里的编程 Agent,它能读你项目里的文件、执行 shell 命令、改代码。它本身是个客户端,需要背后有一个模型服务。默认它连 Anthropic 官方,我们要做的是把请求指向 TaoToken 的 API 通道,用统一 Key 鉴权。
先拿到 Key。打开 TaoToken 控制台(https://taotoken.net/console?utm_source=taotoken_aicg_blog_end&utm_medium=csdn&utm_campaign=rewrite&utm_content=claude_code_beancount),在 API Keys 页面创建一个新 Key,复制出来,形如sk-xxxxxxxx。这个 Key 后面既用于 Claude Code,也能用于其他兼容 Anthropic 协议的工具,所以叫「统一 Key」。
接着配置环境变量。Claude Code 读取的是ANTHROPIC_BASE_URL和ANTHROPIC_AUTH_TOKEN这两个变量。Base URL 填 TaoToken 的 API 地址https://taotoken.net/api,注意这里不加任何查询参数。macOS / Linux 在~/.zshrc或~/.bashrc里追加:
export ANTHROPIC_BASE_URL="https://taotoken.net/api" export ANTHROPIC_AUTH_TOKEN="sk-你的Key"Windows PowerShell 用户在当前会话里执行:
$env:ANTHROPIC_BASE_URL="https://taotoken.net/api" $env:ANTHROPIC_AUTH_TOKEN="sk-你的Key"想永久生效就写进系统环境变量,或者用setx。改完记得source ~/.zshrc或重开终端。
如果你用的是 Claude Code 的配置文件方式(部分版本支持~/.claude/settings.json),可以写成 JSON:
{ "env": { "ANTHROPIC_BASE_URL": "https://taotoken.net/api", "ANTHROPIC_AUTH_TOKEN": "sk-你的Key" } }这里有个容易踩的点:Base URL 结尾不要带/v1,也不要带斜杠,Claude Code 会自己拼接路径。填错会直接 404 或 401。配置完先别急着建项目,用一条最小请求验证通道是否通——这一步放在第 4 节,先把项目骨架搭起来。
3. 可复制配置:项目初始化与 Beancount 解析代码生成
环境变量配好后,新建一个空目录当项目根:
mkdir beancount-web && cd beancount-web然后在这个目录里启动 Claude Code:
claude第一次启动它会问你是否信任当前目录,选 yes。进去之后就是一个对话界面,你输入自然语言,它来干活。下面是我实际用的提示词,你可以直接抄:
帮我用 Python 搭一个 Beancount 记账 Web 应用。要求:1)用 Flask 做后端;2)读取当前目录下的
main.bean账本文件,用 beancount 库解析;3)提供一个首页,展示账户余额列表和最近 20 笔交易;4)提供一个/add接口,能往账本追加一笔交易;5)所有依赖写进 requirements.txt。请直接创建文件。
Claude Code 会依次创建app.py、templates/index.html、requirements.txt,并在终端里告诉你它做了什么。核心解析逻辑大致长这样,你可以对照检查它有没有写对:
from flask import Flask, render_template, request, redirect from beancount import loader from beancount.core import data, realization import datetime app = Flask(__name__) BEAN_FILE = "main.bean" def load_ledger(): entries, errors, options = loader.load_file(BEAN_FILE) return entries, errors @app.route("/") def index(): entries, errors = load_ledger() # 按账户聚合余额 balances = {} for entry in entries: if isinstance(entry, data.Transaction): for posting in entry.postings: amt = posting.units if amt is None: continue balances.setdefault(posting.account, 0) balances[posting.account] += float(amt.number) recent = [e for e in entries if isinstance(e, data.Transaction)][-20:] return render_template("index.html", balances=balances, recent=recent, errors=errors)注意beancount库的 API 在不同版本间有差异,2.x 和 3.x 的loader.load_file返回值结构基本一致,但postings里units可能是None(比如自动平衡的行),所以上面加了判空。Claude Code 一般会处理这些边界,但你最好扫一眼。
依赖文件:
flask beancount装依赖:
pip install -r requirements.txt再准备一个最小账本main.bean,让页面有数据可展示:
2024-01-01 open Assets:Cash CNY 2024-01-01 open Expenses:Food CNY 2024-01-01 open Income:Salary CNY 2024-01-05 * "午餐" "公司楼下" Expenses:Food 35.00 CNY Assets:Cash -35.00 CNY 2024-01-10 * "工资" Assets:Cash 12000.00 CNY Income:Salary -12000.00 CNY到这里项目骨架就有了。如果 Claude Code 生成的代码有语法问题,直接在对话里说「app.py 第 30 行报错,帮我修」,它会读文件、改、再让你跑。
4. 验证请求:跑起服务并写入一笔真实记账数据
先验证模型通道。在 Claude Code 里输入一句「你好,确认一下连接正常」,如果它能正常回复,说明 Base URL 和 Key 都生效了。如果报 401,回到第 2 节检查 Key 有没有复制全、有没有多余空格。
接着启动 Flask:
python app.py终端会打印Running on http://127.0.0.1:5000。浏览器打开这个地址,你应该能看到账户余额和最近交易列表。如果页面空白或报 500,看终端 traceback,把错误贴回 Claude Code 让它修。
现在做一次真实的写入验证。我让 Claude Code 加一个表单提交,或者你直接用 curl 测/add接口:
curl -X POST http://127.0.0.1:5000/add \ -d "date=2024-01-15" \ -d "payee=超市" \ -d "amount=88.50" \ -d "account=Expenses:Food"接口内部会把这笔交易格式化成 Beancount 语法追加到main.bean:
@app.route("/add", methods=["POST"]) def add(): d = request.form["date"] payee = request.form["payee"] amount = request.form["amount"] account = request.form["account"] line = f'\n{d} * "{payee}"\n {account} {amount} CNY\n Assets:Cash -{amount} CNY\n' with open(BEAN_FILE, "a", encoding="utf-8") as f: f.write(line) return redirect("/")提交后刷新首页,余额应该变了,最近交易里也多了一条「超市」。这一步跑通,说明「解析—展示—写入」整条链路是活的。你可以再让 Claude Code 加个饼图,用 Chart.js 在模板里画,它一样能写。
5. 本篇常见报错排查:401、local proxy failed 与 reading choices
接入 Claude Code 时最常见的几个报错,我按实际遇到的整理一下。
401 Unauthorized:Key 错了或没生效。检查ANTHROPIC_AUTH_TOKEN是否和 TaoToken 控制台里的一致,有没有把sk-前缀漏掉。改完环境变量要重开终端,export只在当前会话有效。
local proxy failed / connection refused:Base URL 填错,或者本地网络到taotoken.net不通。确认填的是https://taotoken.net/api,不带/v1、不带尾斜杠。如果公司网络有出口限制,换网络再试。
Error reading choices / unexpected response:通常是模型名不匹配或返回体解析失败。Claude Code 默认会带一个模型 ID,如果你在配置里手动指定了模型,确认它和 TaoToken 支持的模型列表一致。不确定就别指定,用默认。
OAuth / login required:Claude Code 有时会尝试走官方登录流程。确保ANTHROPIC_AUTH_TOKEN已设置,它会优先用这个而不是 OAuth。
Beancount 解析报错:main.bean里缩进必须用空格不能用 Tab,金额和账户之间至少两个空格。报错信息里会带行号,照着改。
排查顺序建议:先确认通道(发一句普通对话),再确认项目代码(跑python app.py看 traceback),最后确认账本语法。三层分开定位,比一上来就改代码快得多。
6. 把这条链路用起来:从记账 Demo 到长期可维护的小工具
跑通之后,这个项目其实可以继续长。你可以让 Claude Code 加账户筛选、按月统计、导出 CSV,甚至接一个定时任务每天自动备份main.bean。因为账本是纯文本,配合 git 做版本管理,每次改动都有记录,比很多记账 App 的数据更可控。
如果你打算长期用 Claude Code 写这类小工具,可以考虑 TaoToken 的 Coding Plan(https://taotoken.net/coding-plan?utm_source=taotoken_aicg_blog_end&utm_medium=csdn&utm_campaign=rewrite&utm_content=claude_code_beancount),统一 Key 在多工具间复用,省得每个客户端配一遍。想先单独验证模型效果,用模型对话页(https://taotoken.net/chat?utm_source=taotoken_aicg_blog_end&utm_medium=csdn&utm_campaign=rewrite&utm_content=claude_code_beancount)发几条请求看看返回质量。接入文档在 https://taotoken.net/doc?utm_source=taotoken_aicg_blog_end&utm_medium=csdn&utm_campaign=rewrite&utm_content=claude_code_beancount,API Keys 管理在 https://taotoken.net/api-keys?utm_source=taotoken_aicg_blog_end&utm_medium=csdn&utm_campaign=rewrite&utm_content=claude_code_beancount。
最后留一个我踩过的坑:Claude Code 生成代码时偶尔会「自作主张」改你的main.bean格式,尤其是缩进。每次让它改完,用beancount main.bean命令行校验一遍,确认账本没被写坏再提交。这个习惯能帮你省掉很多对账时的困惑。