Claude Code 生成 svgwrite 户型图,Base URL 填 TaoToken
用 Claude Code 配 svgwrite 画户型图通道这一步其实很快到 TaoToken 官网 https://taotoken.net/?utm_sourcetaotoken_aicg_blog_end 创建一把 Key再把 Base URL 填成 https://taotoken.net/api剩下的交给四轮对话。先说这个是因为「Claude Code 100 个真实案例」里那个用 AI 生成两室一厅建筑平面图 SVG 的例子真正劝退人的地方不在 svgwrite 的 API。设计师打开终端还没敲下pip install svgwrite cairosvg就已经在登录、切模型、看额度这几件事上耗掉了半小时。而后面那四轮提示词——搭 FloorPlanDrawer 框架、写 design_two_bedroom_apartment()、补 FurnitureLibrary 家具符号库、汇总面积导出 two_bedroom_apartment.svg——每一轮都要把上下文重新发给模型Token 是一路往上走的。通道没准备好第一轮就可能断在半路。这篇按原文的推进顺序走一遍把「准备通道」和「写绘图代码」拆开讲TaoToken 只负责给你一把 Key 和一个 Base URL墙厚 240/120、1:50 比例尺、门弧的 Arc 命令、家具怎么摆全部还是 svgwrite 的活。1. 为什么 svgwrite 户型图的卡点在 Claude Code 通道而不是绘图代码svgwrite 本身的学习曲线并不陡。它做的事情很朴素把矩形、直线、路径这类 SVG 基本元素用 Python 对象包一层再dwg.save()落盘成.svg。真正难的是「让 Claude Code 连续四轮帮你把这套代码写对」而这件事的成败有两个前提对话别断、上下文别丢。1.1 四轮提示词每一步都在消耗 Token原文的流程是这样的第一轮让 Claude Code 搭出 FloorPlanDrawer 类包含 1:50 的 SCALE、mm_to_px 单位换算以及墙体、门弧、窗三类图元的绘制方法第二轮补 design_two_bedroom_apartment()把 11000×8000 的外轮廓拆成七个房间和内外墙第三轮加 FurnitureLibrary画沙发、双人床、L 型橱柜、马桶这些符号第四轮汇总各房间面积导出 two_bedroom_apartment.svg。四轮下来模型每次都要重新读一遍前面的类定义和房间坐标。对 Claude Code 来说这是一次典型的长上下文任务中途换账号、换 Key、换模型都会让已经建立起来的上下文白费。不少人遇到的问题不是代码写错而是第三轮跑到一半提示额度或鉴权异常只能从头再来。1.2 TaoToken 在这件事里只负责 Key 和 Base URL把 TaoToken 接进来之后它在整个户型图流程里承担的角色非常单一提供一把可用的 API Key和一个统一的 Base URLhttps://taotoken.net/api。它不参与绘图不参与坐标计算也不知道 240 墙和 120 隔墙的区别。换句话说Claude Code 依然是那个帮你写 Python 的助手svgwrite 依然是那个真正画图的库中间只是多了一段稳定的兼容通道。理解了这一点配置的时候就不会纠结「要不要在 TaoToken 里配户型参数」——不需要。2. 在 ~/.claude/settings.json 里把 ANTHROPIC_BASE_URL 指向 TaoToken配置动作本身不到五分钟但坑都藏在细节里填哪个文件、末尾要不要/v1、Key 怎么生效。下面按顺序过一遍。2.1 先去官网创建一把 Key打开 TaoToken注册账号后进控制台新建一个 API Key复制出来先放一边。顺手在模型广场看一眼当前可用的模型 ID因为ANTHROPIC_MODEL要填的就是那里列出来的名字而不是凭印象写的字符串。这一步不要和接口地址混注册、创建 Key、看模型、看用量都在落地页做真正填进工具的是https://taotoken.net/api末尾没有/v1。提示Key 只在创建时完整显示一次建议先粘到本地临时文件里配完 settings.json 再删。2.2 两种等价写法环境变量与 settings.jsonClaude Code 读配置有两条路。临时用直接在终端里导出环境变量export ANTHROPIC_BASE_URLhttps://taotoken.net/api export ANTHROPIC_AUTH_TOKENYOUR_API_KEY export ANTHROPIC_MODEL模型广场里列出的模型 ID想长期生效就写进配置文件。macOS 和 Linux 下是~/.claude/settings.jsonWindows 下是%USERPROFILE%\.claude\settings.json{ env: { ANTHROPIC_BASE_URL: https://taotoken.net/api, ANTHROPIC_AUTH_TOKEN: YOUR_API_KEY, ANTHROPIC_MODEL: 模型广场里列出的模型 ID } }注意键名里的env这三个变量必须放在env对象内部写成顶层字段 Claude Code 不会读。2.3 三个容易填错的位置第一ANTHROPIC_BASE_URL不要带/v1。带了之后工具会在后面再拼一次版本号请求路径变成/api/v1/v1/messages这类四不像的地址直接 404 或 401。第二不要把带查询参数的官网地址填进 Base URL。settings.json里只需要https://taotoken.net/api这个干净地址UTM 参数是给人点的网页用的不是给接口用的。第三ANTHROPIC_AUTH_TOKEN填的是占位符YOUR_API_KEY对应的真实 Key不要带引号外的空格也不要在前面手动加Bearer。工具自己会处理鉴权头。注意改完 settings.json 后要重开一个 Claude Code 会话旧进程不会自动加载新配置。3. 让 Claude Code 先交 FloorPlanDrawer1:50 与 mm_to_px通道通了第一轮提示词可以发了。这一轮的目标只有一个拿到一个能跑、能保存、能继续扩展的绘制框架别急着让它画户型。3.1 第一轮提示词怎么说可以用接近原文的说法但把约束讲清楚用 Python 的 svgwrite 写一个 FloorPlanDrawer 类作为户型图绘制框架。 要求 1. 图纸比例 1:50所有对外接口的输入坐标和尺寸都用毫米(mm) 2. 内部提供 mm_to_px(mm) 方法做单位换算 3. 依次提供 draw_wall墙体、draw_door门弧、draw_window窗三个方法 4. 用 Drawing 的 group 把墙体、门、窗、家具分层方便后续单独导出 5. 先不要写具体户型只给类定义和一个最小可运行的示例。把「先不要写具体户型」写进提示词是有意为之。第一轮如果让它同时考虑七个房间模型很容易把坐标算错而你还得回头去猜是哪一步错了。3.2 墙体双线、门弧 A 命令、窗三线拿到类定义后先检查三件事。墙体是不是按双线画的内墙 120、外墙 240都按厚度的一半向两侧偏移门弧是不是用了 path 的A命令而不是圆弧近似窗户是不是三条平行线。import svgwrite class FloorPlanDrawer: 1:50 住宅平面图绘制框架输入单位统一为毫米(mm)。 SCALE 50 def __init__(self, width_mm, height_mm, filename): self.dwg svgwrite.Drawing( filename, size(self.mm_to_px(width_mm), self.mm_to_px(height_mm)), ) self.walls self.dwg.add(self.dwg.g(idwalls, strokeblack)) self.doors self.dwg.add(self.dwg.g(iddoors, fillnone, strokeblack)) self.windows self.dwg.add(self.dwg.g(idwindows, strokeblack)) self.furniture self.dwg.add(self.dwg.g(idfurniture)) def mm_to_px(self, mm): return mm / self.SCALE def draw_wall(self, x1, y1, x2, y2, thickness240): half self.mm_to_px(thickness) / 2 if y1 y2: for dy in (-half, half): self.walls.add(self.dwg.line( start(self.mm_to_px(x1), self.mm_to_px(y1) dy), end(self.mm_to_px(x2), self.mm_to_px(y2) dy), stroke_width2)) else: for dx in (-half, half): self.walls.add(self.dwg.line( start(self.mm_to_px(x1) dx, self.mm_to_px(y1)), end(self.mm_to_px(x2) dx, self.mm_to_px(y2)), stroke_width2)) def draw_door(self, x, y, width900): w self.mm_to_px(width) px, py self.mm_to_px(x), self.mm_to_px(y) self.doors.add(self.dwg.path( dfM {px} {py} L {px w} {py} A {w} {w} 0 0 1 {px} {py w}, stroke_width2)) def draw_window(self, x, y, length, thickness240, horizontalTrue): t self.mm_to_px(thickness) for offset in (-t / 2, 0, t / 2): if horizontal: self.windows.add(self.dwg.line( start(self.mm_to_px(x), self.mm_to_px(y) offset), end(self.mm_to_px(x length), self.mm_to_px(y) offset), stroke_width2)) else: self.windows.add(self.dwg.line( start(self.mm_to_px(x) offset, self.mm_to_px(y)), end(self.mm_to_px(x) offset, self.mm_to_px(y length)), stroke_width2))A命令的参数顺序是rx ry x轴旋转 大弧标志 扫向标志 终点x 终点y。门弧一般是 90 度小弧所以大弧标志写 0、扫向写 1。这段如果模型写错了你会在浏览器里看到一根横线或者一个夸张的半圆很直观。4. 第二轮补 design_two_bedroom_apartment()11000×8000 怎么拆成七个房间第二轮最容易翻车。七个房间、内外墙、门洞位置全靠模型在脑子里做几何划分一不留神就会出现两个房间重叠、或者外墙长度加起来不是 11000。4.1 先把房间清单写成表格再让它落代码比起让它「自己设计一个两室一厅」更稳的做法是先用文字把分区方案定死再让它翻译成代码。例如让整个户型按 11000×8000 的外轮廓划分房间起点 (x, y)宽×深 (mm)面积主卧(0, 0)3600×400014.40 m²次卧(3600, 0)3000×400012.00 m²卫生间(6600, 0)1800×24004.32 m²厨房(8400, 0)2600×24006.24 m²客厅(6600, 2400)4400×560024.64 m²餐厅(0, 4000)3600×400014.40 m²书房(3600, 4000)3000×400012.00 m²这七块正好铺满 11000×8000加起来 88 平方米后面做面积汇总时能直接对上。把这张表原样贴给 Claude Code让它据此写design_two_bedroom_apartment()比让它自由发挥可靠得多。4.2 内外墙厚 240 与 120 的处理户型定义函数里画墙这一步要显式区分厚度贴外轮廓的墙传thickness240房间之间和卫生间、厨房的隔墙传thickness120。如果提示词里不写模型很可能全部按 240 画图出来之后墙线挤在一起看着就假。def design_two_bedroom_apartment(filenametwo_bedroom_apartment.svg): W, H 11000, 8000 d FloorPlanDrawer(W, H, filename) # 外墙240 厚 d.draw_wall(0, 0, W, 0, thickness240) d.draw_wall(W, 0, W, H, thickness240) d.draw_wall(W, H, 0, H, thickness240) d.draw_wall(0, H, 0, 0, thickness240) # 内墙120 厚 d.draw_wall(3600, 0, 3600, 4000, thickness120) d.draw_wall(6600, 0, 6600, 8000, thickness120) d.draw_wall(8400, 0, 8400, 2400, thickness120) d.draw_wall(0, 4000, 6600, 4000, thickness120) d.draw_wall(6600, 2400, W, 2400, thickness120) return d墙画完之后再补门弧主卧、次卧的开在朝向餐厅一侧卫生间和厨房的门开向客厅方向。draw_door(x, y, width900)的(x, y)是门扇的轴心轴心位置和门洞位置对齐弧线才不会压在墙线上。5. 第三轮 FurnitureLibrary沙发、双人床、L 型橱柜、马桶家具这一轮看着轻松其实是整张图最花时间的地方。原因不在 svgwrite而在于每个符号都要定义一套自己的坐标基准模型如果每换一个家具就换一种基准最后摆放位置会乱套。5.1 家具符号的坐标基准要统一提示词里明确要求所有家具方法的第一个坐标参数都是「家具外接矩形的左下角」第二、三个参数是宽和深单位毫米。这样在客厅里摆沙发就是sofa(6800, 2600, 2000, 900)这种一眼能读懂的调用。class FurnitureLibrary: 家具符号库坐标基准统一为外接矩形左下角。 staticmethod def sofa(dwg, x, y, w2000, d900): g dwg.dwg.g(strokeblack, fillnone, stroke_width2) g.add(dwg.dwg.rect(insert(dwg.mm_to_px(x), dwg.mm_to_px(y)), size(dwg.mm_to_px(w), dwg.mm_to_px(d)))) # 靠背 g.add(dwg.dwg.line( start(dwg.mm_to_px(x), dwg.mm_to_px(y d - 150)), end(dwg.mm_to_px(x w), dwg.mm_to_px(y d - 150)))) dwg.furniture.add(g) staticmethod def double_bed(dwg, x, y, w1800, d2000): dwg.furniture.add(dwg.dwg.rect( insert(dwg.mm_to_px(x), dwg.mm_to_px(y)), size(dwg.mm_to_px(w), dwg.mm_to_px(d)), strokeblack, fillnone, stroke_width2)) # 两个枕头 for i in range(2): dwg.furniture.add(dwg.dwg.rect( insert(dwg.mm_to_px(x 100 i * (w / 2)), dwg.mm_to_px(y d - 500)), size(dwg.mm_to_px(w / 2 - 200), dwg.mm_to_px(350)), strokeblack, fillnone, stroke_width1.5)) staticmethod def l_shaped_counter(dwg, x, y, long_side2400, short_side1800, depth600): pts [(x, y), (x long_side, y), (x long_side, y depth), (x depth, y depth), (x depth, y short_side), (x, y short_side)] dwg.furniture.add(dwg.dwg.polygon( points[(dwg.mm_to_px(px), dwg.mm_to_px(py)) for px, py in pts], strokeblack, fillnone, stroke_width2)) staticmethod def toilet(dwg, x, y): dwg.furniture.add(dwg.dwg.rect( insert(dwg.mm_to_px(x), dwg.mm_to_px(y)), size(dwg.mm_to_px(400), dwg.mm_to_px(200)), strokeblack, fillnone, stroke_width2)) dwg.furniture.add(dwg.dwg.ellipse( center(dwg.mm_to_px(x 200), dwg.mm_to_px(y 500)), r(dwg.mm_to_px(180), dwg.mm_to_px(280)), strokeblack, fillnone, stroke_width2))沙发用矩形加一条靠背线双人床用矩形加两个枕头L 型橱柜用polygon走六个点马桶用水箱矩形加椭圆。四个符号各有各的画法但坐标基准是统一的后面摆放就不会互相打架。5.2 让 Claude Code 自己写一个摆放校验家具摆完之后可以让它再补一个小函数遍历所有家具的包围盒检查有没有超出所在房间的边界或者两件家具互相重叠。这个校验不需要精确粗略的矩形相交判断就够用但能帮你省掉大量肉眼找问题的时间。6. 第四轮汇总面积并导出 two_bedroom_apartment.svg最后一轮把散落的东西收口算面积、加标注、保存文件。6.1 面积汇总顺便当一次自检ROOMS [ (主卧, 0, 0, 3600, 4000), (次卧, 3600, 0, 3000, 4000), (卫生间, 6600, 0, 1800, 2400), (厨房, 8400, 0, 2600, 2400), (客厅, 6600, 2400, 4400, 5600), (餐厅, 0, 4000, 3600, 4000), (书房, 3600, 4000, 3000, 4000), ] def summarize_area(rooms): total 0.0 for name, _, _, w, h in rooms: area w * h / 1_000_000 total area print(f{name}: {area:.2f} m2) print(f合计: {total:.2f} m2) return total这个函数顺便是一次几何自检。如果算出来的合计明显小于 88 平方米说明房间列表里有重叠或者漏了一块如果大于 88说明某两块区域叠在一起了。这比盯着 SVG 一点点量要快得多。6.2 跑 python floor_plan_main.py 看两个信号入口文件建议叫floor_plan_main.py里面只做三件事实例化 FloorPlanDrawer、调用 design_two_bedroom_apartment()、把家具摆上去、dwg.save()。from floor_plan_drawer import FloorPlanDrawer from furniture import FurnitureLibrary if __name__ __main__: d FloorPlanDrawer(11000, 8000, two_bedroom_apartment.svg) d.draw_wall(0, 0, 11000, 0, thickness240) # ... 其余墙体与门弧 FurnitureLibrary.double_bed(d, 300, 300) FurnitureLibrary.sofa(d, 6800, 2600) FurnitureLibrary.l_shaped_counter(d, 8400, 300) FurnitureLibrary.toilet(d, 6800, 900) d.dwg.save() print(saved:, two_bedroom_apartment.svg)终端里敲python floor_plan_main.py看两个信号就够了。一是看 Claude Code 那边这一轮对话有没有正常返回中途有没有鉴权类的报错二是看当前目录下two_bedroom_apartment.svg有没有落盘、文件大小是不是 0 字节。两个都正常用浏览器打开 SVG墙体双线、门弧、窗三线应该都在。7. 401 和 /v1 路径拼接两个报错怎么回查 settings.json这套流程里代码报错通常好定位难定位的是通道报错。两种最常见。7.1 401 优先查 Key 有没有真正生效401 基本可以断定 Key 没被工具读到。排查顺序先确认settings.json里是env对象内的ANTHROPIC_AUTH_TOKEN不是写成了别的键名再确认这个 Key 是从 https://taotoken.net/?utm_sourcetaotoken_aicg_blog_end 的控制台里新建并复制完整的没有多出空格或换行最后确认改完之后重开了会话。如果用的是一次性的环境变量注意新开一个终端标签页就失效了。7.2 请求路径被拼成 /v1 说明 Base URL 写多了另一种报错长这样请求地址里出现了/api/v1/v1/messages或者/v1/messages前面重复了一段。原因几乎都是 Base URL 里手滑加了/v1。回到~/.claude/settings.json把ANTHROPIC_BASE_URL改回https://taotoken.net/api末尾不要斜杠、不要/v1、不要任何查询参数。顺带提醒一个容易混淆的点ModuleNotFoundError: No module named svgwrite这类报错跟通道无关是 Python 环境没装依赖回到原文那一步执行pip install svgwrite cairosvg就行。搞清楚报错属于「通道层」还是「代码层」能省下大量瞎改配置的时间。8. 导出成功后去控制台对一下这次调用two_bedroom_apartment.svg落在目录里说明通道和代码两头都通了。这时候值得回 https://taotoken.net/?utm_sourcetaotoken_aicg_blog_end 的控制台看一眼用量确认刚才那四轮提示词是不是都记在了同一个 Key 上——如果只记到一两轮多半是中途换了 Key 或者会话被意外重开下一套户型图开始之前最好统一一下。想先验证模型 ID 和 Base URL 有没有填错可以在 TaoToken 模型对话 里用同一把 Key 发一条测试消息。这套户型图流程属于典型的长上下文多轮任务如果打算长期拿 Claude Code 画图可以先看 Coding Plan 的套餐是否够用Key 随时在 控制台 API Keys 里补建环境变量的完整对照表在 Claude Code 接入文档。真正把这套跑顺之后你会发现户型图能不能画好取决于提示词里房间坐标写得够不够死、内外墙厚度有没有区分、家具基准有没有统一而 Base URL 和 Key 这两样配一次就不用再动。