Kimi K3.1 Pro API로 이미지-투-CAD 에이전트 만들기
이미지-투-CAD 에이전트는 부품 사진을 편집 가능한 CAD 모델로 변환합니다.
왜 Kimi K3.1 Pro와 CadQuery가 이미지-투-CAD에 적합한가
Kimi K3.1 Pro는 네 장의 이미지를 읽고, 자신의 코드가 만들어낸 결과에 반응할 수 있습니다. 앞서 언급한 Moonshot 블로그는 BenchCAD의 Vision2Code 작업에서 도구 사용 시 92.7%, 도구 없이 72.8%를 보고합니다. 이는 렌더링된 부품 뷰로부터 작성된 CAD 코드를 점수화하는 과제입니다. 이 수치는 max 노력도로 1,000건 하위셋에서 나온 것이며, 도구 사용 점수는 Claude Code 하니스를 사용했으므로, 점수의 일부는 하니스에 기인할 수 있습니다.
해당 벤치마크는 네 뷰를 한 이미지에 담고 채점 전에 모든 부품을 같은 크기로 스케일합니다. 제 테스트는 네 개의 별도 뷰와 실제 치수 하나를 함께 보내고, 노력도는 high입니다. 따라서 Moonshot의 수치는 결과라기보다 테스트를 시도할 이유로 받아들이면 됩니다. 제가 이 실험을 수행할 당시에는 오픈 웨이트를 내려받을 수 없었습니다.
출력 형식으로 CadQuery를 택한 이유는 CadQuery 스크립트 자체가 파라메트릭 모델이기 때문입니다. 구멍은 지름과 위치를 인자로 갖는 호출이며, 이후 편집은 수치 하나만 바꿔도 솔리드가 재생성됩니다. STL 파일은 삼각형만 제공하므로 바꿀 slot_width가 없습니다.
에이전트가 보는 것과 숨겨두는 것
Kimi는 네 장의 참조 이미지, 60 mm 폭, 그리고 시스템 프롬프트를 받습니다. 이 프롬프트는 단위를 밀리미터로 고정하고 좌표축을 정의하며, 부품을 X와 Y 중심에 두고 아래면을 Z=0에 위치시키도록 지정합니다. 또한 이름 있는 치수와 result에 최종 솔리드를 할당하도록 요구합니다.
그다음부터 Kimi는 도구가 보고하는 것만 알 수 있습니다. Kimi API는 CadQuery를 실행하지 않으므로, 네 가지 도구 모두 애플리케이션 안에 구현되어 있습니다:
-
execute_cad는 Docker 컨테이너에서 네트워크 없이 프로그램을 실행하고 결과를 후보로 저장합니다 -
inspect_cad는 유효성, 솔리드 개수, 바운딩 박스, 부피, 원기둥 면을 보고합니다 -
render_cad는 참조와 같은 네 카메라에서 후보를 렌더링합니다 -
submit_cad는 한 단계를 하나의 후보로 마무리합니다
Kimi는 참조 코드나 점수를 결코 보지 못합니다. 평가기는 에이전트가 끝난 뒤에만 저장된 STEP 파일을 읽으므로, 점수가 에이전트를 유도하거나 중단시키지 못합니다.
점수는 Kimi로 되돌아가지 않습니다. 이미지: 작성자.
Python에서 Kimi K3.1 Pro API 설정하기
Python에서 Kimi K3.1 Pro API를 사용하려면 네 가지가 필요합니다. 저는 Linux x86_64에서 다음 버전으로 테스트했습니다:
-
K3.1 Pro 퀵스타트에 따라 최소 $1 충전된 Kimi API 키
-
OpenAI SDK인
openai3.39.0과 Python 3.12.3 -
솔리드 생성과 점검을 위한
cadquery2.8.0 -
샌드박스를 위한 Docker 29.9.2
아래 스니펫은 다음에 클론할 GitHub 저장소의 전체 프로젝트에서 발췌했습니다.
CadQuery 설치와 Docker 샌드박스 빌드
CadQuery의 설치 가이드는 conda를 권장하지만, Python 3.12의 pip도 동작합니다. 저장소를 클론하고 설정하세요:
git clone https://github.com/KhalidAbdelaty/Kimi_K3.1_Pro_API_Tutorial.git
cd Kimi_K3.1_Pro_API_Tutorial
python -m venv .venv
source .venv/bin/activate # Windows: .venv\Scripts\Activate.ps1
pip install -r requirements.txt
cp .env.example .env # then add your MOONSHOT_API_KEY
docker build -t cad-sandbox:2.8.0 sandbox/
샌드박스 이미지는 동일한 CadQuery 버전을 설치하고 일반 사용자로 실행됩니다. Docker는 기본적으로 CPU나 메모리 제한을 설정하지 않는다고 리소스 제한 문서에 명시되어 있으므로, 러너가 이를 설정합니다. 저장소 첫 페이지에는 API 키나 Docker 없이 실행하고 점수 매기는 경로를 포함해 실험을 실행하는 명령이 정리되어 있습니다.
Kimi의 코드가 컨테이너에 도달하기 전에, 먼저 직접 깨뜨려 보세요. 제 테스트 프로그램은 API 키를 읽고, 네트워크에 접근하며, 스크래치 폴더 밖에 쓰기를 시도했지만 세 가지 모두 차단되었습니다.

샌드박스에서 차단된 세 가지 동작. 이미지: 작성자.
첫 Kimi K3.1 Pro API 호출 만들기
Moonshot 엔드포인트를 가리키는 일반 OpenAI SDK입니다. 모든 요청에 reasoning_effort를 설정하세요. 생략하면 max가 기본이며, 생각을 끌 수 없습니다.
client = OpenAI(api_key=os.environ["MOONSHOT_API_KEY"], base_url="https://api.moonshot.ai/v1")
response = client.chat.completions.create(
model="kimi-k3.1-pro",
reasoning_effort="high", # low, high, or max; the API default is max
max_completion_tokens=2048, # reasoning and answer share this cap
messages=[{"role": "user", "content": "In one sentence, what does a STEP file store?"}],
)
print(response.choices[0].message.content)
print("usage:", response.usage.model_dump(exclude_none=True))
temperature, top_p, n, 그리고 두 페널티는 퀵스타트에 고정이라고 되어 있으니 생략하세요. 한 문장 답변조차도 완성 토큰 대부분을 추론에 쓰므로, 그 점을 고려해 토큰 상한을 잡으세요.

한 번의 요청으로 키와 모델을 확인. 이미지: 작성자.
Kimi API가 처음이라면, 제 이전 Kimi K3 튜토리얼에서 스트리밍, 도구 호출, 캐싱, 비전 입력을 다룹니다.
참조 CAD 모델과 네 가지 테스트 뷰 만들기
참조 CAD 모델은 정답지입니다. 모든 점수는 정확히 비교할 대상을 가져야 합니다. 저는 첫 요청 전 카메라부터 채점 규칙까지 모두 고정했고, 결과를 본 뒤에도 변경하지 않았습니다.
브래킷 치수 정의
브래킷은 L자이며, 수직판이 베이스 뒤쪽에 결합되어 있습니다. 원점은 아래면의 중심에 있으며, X는 폭 방향, 앞쪽은 −Y, Z는 위쪽입니다:
|
피처 |
값 |
Kimi에 공개? |
|
전체 폭 (X) |
60 mm |
예 |
|
베이스 깊이 (Y) |
40 mm |
아니오 |
|
전체 높이 (Z) |
45 mm |
아니오 |
|
판 두께 |
6 mm |
아니오 |
|
장착 구멍 |
2 × Ø6.5 mm, 간격 34 mm, Y = −3 mm |
아니오 |
|
수직 슬롯 |
폭 6 mm, 끝단 간 길이 20 mm, X = 0, Z = 25.5 mm에 중심 |
아니오 |
구멍 열과 슬롯은 각 면의 중앙에 배치했고, 실제 브래킷에서 흔한 M6 여유치수인 6.5 mm 구멍을 사용했습니다. 이 선택이 이 브래킷의 약점으로 드러났고, 그 이유는 뒤에서 설명합니다.
빌드 함수 내부에서 w, dep, h, t는 각각 폭, 깊이, 높이, 두께를 의미합니다. 두 판을 결합하고 피처를 가공합니다:
base = cq.Workplane("XY").box(w, dep, t, centered=(True, True, False))
upright = cq.Workplane("XY").center(0, dep / 2 - t / 2).box(w, t, h, centered=(True, True, False))
holes = cq.Workplane("XY").pushPoints([(-17, -3), (17, -3)]).circle(3.25).extrude(t)
slot = (cq.Workplane("XZ", origin=(0, dep / 2 - t / 2, 0)).center(0, 25.5)
.slot2D(20, 6, 90) # end-to-end length, width, angle
.extrude(t, both=True))
result = base.union(upright).cut(holes).cut(slot)
스크립트는 STEP 파일로 내보내기 전에 기대한 크기의 유효한 단일 솔리드인지 확인합니다.
고정 카메라로 네 가지 뷰 렌더링
간단한 NumPy 렌더러가 참조와 모든 후보에 대해 동일한 고정 프레이밍으로 정면, 상면, 우측면, 아이소메트릭 뷰를 그립니다. 해상도 512 px에서는 픽셀당 약 0.19 mm에 해당하지만, 이미지 판독 오차는 그 이상일 수 있습니다. 고정 프레이밍 덕분에 후보가 너무 크거나 위치가 어긋났을 때 재중심 대신 “이상해 보이도록” 합니다.

Kimi에 전송된 네 장의 이미지. 이미지: 작성자.
에이전트 실행 전 평가 규칙 고정
평가기는 내보낸 솔리드를 측정하므로, 매개변수 이름으로 속일 수 없습니다. 각 STEP 파일을 슬라이스해 구멍, 슬롯, 두 판의 두께를 찾고, 실제 크기에서 0.5 mm 격자의 복셀 IoU(두 솔리드가 공유하는 체적 비율)를 계산합니다. 허용오차는 픽셀 스케일을 따릅니다: 두께, 구멍 지름, 슬롯 폭은 ±0.5 mm, 이미지에서 읽은 길이와 위치는 ±1~±1.5 mm입니다.
IoU만으로는 충분하지 않습니다. 저는 이 수치를 다소 둔감하다고 느끼지만, 두 솔리드를 비교하는 더 단순한 방법이 없어 계속 사용합니다. 구멍과 슬롯이 없는 단순한 L도 0.96 이상을 기록하며, 크기가 20% 더 큰 정답 솔리드는 둘을 같은 크기로 스케일하면 IoU가 1.0이 됩니다.
그래서 여기의 모든 점수에는 13개의 통과/실패 체크가 함께합니다. 1.0이라는 완벽한 수치조차도 그 격자에서 일치한다는 뜻일 뿐, 마이크로미터 단위까지 일치한다는 의미는 아니며, 이 수치들은 제조 보증이 아닙니다.
Kimi K3.1 Pro로 이미지에서 CadQuery 코드 생성하기
첫 후보는 도구 없이 한 번의 요청으로 생성되며, 반환된 그대로 실행합니다.
네 가지 참조 뷰를 Kimi K3.1 Pro API로 전송
Kimi의 비전 입력은 content 배열 안에 base64 데이터 URL을 사용하며, 공개 이미지 URL은 허용하지 않습니다. 시스템 프롬프트에는 앞서 설명한 프레이밍과 명명 규칙이 들어가고, 사용자 메시지는 네 개의 PNG와 다음 프롬프트를 담습니다:
These four images show one mechanical part, a bracket. Each view uses orthographic
projection, and all four use the same scale. The camera for each view is written at the
top of the image, and a small axis triad sits in the lower-left corner.
The overall width of the part along X is 60 mm. No other dimension is given, so estimate
the rest from the images.
Write one CadQuery program that rebuilds this part as an editable parametric model.
Return the complete program in a single python code block.
요청 자체는 간단합니다:
images = [image_part(path) for path in view_paths] # four PNGs as base64 data URLs
messages.append({"role": "user", "content": images + [{"type": "text", "text": BASELINE_PROMPT}]})
response = client.chat.completions.create(
model="kimi-k3.1-pro", reasoning_effort="high",
max_completion_tokens=32_768, messages=messages,
)
결제 전에 입력 크기를 확인하려면 동일한 메시지를 토큰 추정 엔드포인트로 보내세요. 추정치는 실제 과금과 거의 일치했습니다. 512 px 이미지 네 장은 입력 토큰이 2,000 미만입니다.
첫 CadQuery 프로그램을 샌드박스에서 실행
러너는 코드를 스크래치 폴더에 기록하고 docker run 명령으로 1회용 컨테이너를 시작합니다:
cmd = ["docker", "run", "--rm", "--network", "none", "--read-only",
"--tmpfs", "/tmp:size=64m", "--cap-drop", "ALL",
"--security-opt", "no-new-privileges",
"--memory", "1g", "--cpus", "1", "--pids-limit", "128",
"-v", f"{work}:/work", "cad-sandbox:2.8.0"]
subprocess.run(cmd, capture_output=True, text=True, timeout=60)
첫 시도에서 Kimi의 응답은 약 1분이 걸렸습니다. 그 프로그램은 숨겨진 참조의 모든 치수를 이름을 붙여 선언했는데, bracket_depth = 40.0부터 slot_center_z = 25.5까지였습니다. 유효한 솔리드를 생성했고, 모든 검사를 통과했습니다.

같은 카메라, 같은 스케일, 일치하는 부품. 이미지: 작성자.
첫 시도가 완벽에 가까워 유출 여부를 점검했지만, PNG에는 메타데이터가 없고 프롬프트에도 숨은 값이 없었습니다. Kimi의 코드가 결과를 설명합니다. 앞서 브래킷을 정의할 때 말했듯이, 피처들은 디자이너가 둘 법한 위치에 있고, Kimi도 그렇게 두었습니다.

Kimi는 피처 위치를 중점에서 유도합니다. 이미지: 작성자.
Kimi K3.1 Pro로 자가 점검 도구 호출 에이전트 구축
도구 호출 에이전트는 루프에서 동작합니다. Kimi가 도구를 요청하면, 여러분의 코드가 이를 실행하고, 결과를 도구 메시지로 다시 보내는 과정을 Kimi가 완료할 때까지 반복합니다.

각 단계에 엄격한 한도가 있습니다. 이미지: 작성자.
CAD 실행, 점검, 렌더링용 도구 정의
다음은 execute_cad의 스키마입니다. 실패 시 마지막 트레이스백 몇 줄과 함께, 고정된 형식의 짧은 결과를 반환합니다:
{"type": "function", "function": {
"name": "execute_cad",
"description": "Run a complete CadQuery program in an isolated sandbox. Returns a "
"candidate id, whether it ran, and a short error if it did not.",
"parameters": {"type": "object", "properties": {
"code": {"type": "string",
"description": "The complete program. It must assign the final solid to result."}},
"required": ["code"]}}}
render_cad는 동일한 ‘다시 보기’ 패턴으로 도구 메시지 자체에 네 장의 이미지를 포함해 반환합니다. 이는 Gemini를 사용한 에이전틱 비전 튜토리얼에서도 사용했습니다. Kimi 문서에 이 예시는 없으므로 관찰된 동작으로 보시면 됩니다. 세 번의 시도 모두에서 role: "tool" 메시지가 image_url 파트를 담고 있었고, 모델이 이를 읽었습니다.
도구 루프에서 보조 메시지를 온전히 유지
여기서 중요한 점이 세 가지 있습니다. 처음 두 가지는 Kimi의 사고 모델 가이드와 퀵스타트에서 가져왔습니다:
-
매 턴 전체 보조(assistant) 메시지를 다시 보내세요.
reasoning_content와tool_calls를 포함합니다 -
도구 호출마다 하나의 도구 메시지를 추가하고, 일치하는
tool_call_id를 포함합니다 -
model_dump()로 메시지를 직렬화하세요. OpenAI SDK에는 타입이 지정된reasoning_content필드가 없습니다
아래 루프는 이 세 가지를 모두 따릅니다:
message = response.choices[0].message.model_dump(exclude_none=True)
messages.append(message) # all of it, or the next turn quietly loses its reasoning
for call in message.get("tool_calls") or []:
content = run_tool(call["function"]["name"], json.loads(call["function"]["arguments"]))
messages.append({"role": "tool", "tool_call_id": call["id"], "content": content})
여기에서 실수를 API가 잡아줄 것이라 기대하지 마세요. 기록에서 reasoning_content를 제거해도 요청은 성공합니다. 문서에는 필수라고 되어 있지만, 이를 누락하면 이후 턴의 진행이 달라질 수 있습니다. 조용히 실패하는 버그보다는 400 오류가 더 낫겠습니다.
예산은 Kimi가 바꿀 수 없는 루프 코드 내부에 있습니다. 세 번의 수정 기회를 다 쓰면 execute_cad는 오류로 응답하고, submit_cad는 유효한 단일 솔리드가 아니면 거부합니다.
수정 단계에서 일어난 일
거의 없습니다. 이 섹션을 뺄까도 했습니다. 저는 수정 루프가 핵심 역할을 할 것으로 기대했지만, Kimi는 거의 손대지 않았습니다. 첫 후보를 점검하고 렌더링한 뒤, 네 참조 뷰와 일치한다는 확신에 찬 요약을 쓰고, 처음 작성한 프로그램 그대로 제출했습니다.
그 요약이 항상 맞지는 않았습니다. 한 번은 inspect_cad가 구멍 반지름을 3.0 mm로 보고해, 참조의 6.5 mm 대신 6.0 mm 구멍이었지만 Kimi는 그대로 제출했습니다. 이 뷰에서 0.5 mm는 3픽셀도 안 됩니다(저라도 눈으로는 자신 없었을 겁니다). 그리고 피드백에는 올바른 지름이 얼마인지 나와 있지 않았습니다.

도구는 반지름 3.0 mm를 보고했습니다. 이미지: 작성자.
Kimi K3.1 Pro로 파라메트릭 CAD 모델 편집
수정 루프가 움직이지 않자, 디자인 변경이 더 의미 있는 테스트가 되었습니다. 다만 이는 순한 테스트이며, 두 피처 이상이 함께 움직이는 변경은 훨씬 더 어려운 시험이 될 것입니다.
Kimi에게 슬롯을 넓혀 달라고 요청
편집은 같은 대화를 이어가며, 제 참조 코드가 아니라 Kimi가 제출한 후보에서 시작합니다:
Increase the width of the vertical slot in the upright plate from 6 mm to 9 mm.
Keep the slot's center position and its end-to-end length as they are in your model.
Do not change the mounting holes, the plate thickness, or the outer dimensions.
Kimi는 허용된 3개의 프로그램 중 하나를 사용했습니다. 변경(diff)은 한 줄, slot_width = 6.0에서 slot_width = 9.0로 바뀌었고, 이후 점검과 렌더링 한 턴, 제출로 마무리했습니다.
내보낸 기하로 편집 확인
코드의 숫자가 바뀌었다고 해서 솔리드가 변했음을 보장하지는 않습니다. 평가는 편집 전후 솔리드를 복셀 단위로 비교하고, 넓어진 슬롯이 차지해도 되는 공간만 무시했습니다:
- 슬롯은 폭 9 mm이며, 길이와 중심은 동일합니다
- 구멍, 판 두께, 외곽 크기는 불변입니다
- 슬롯 영역 밖의 재질은 변하지 않았습니다
모든 편집 검사를 매번 통과했습니다.
편집이 깔끔히 동작한 이유는 slot2D()가 길이를 끝단 간 거리로 취급하기 때문입니다. 슬롯은 20 mm 길이를 유지했고, 직선 구간이 짧아졌습니다. 두 원호 중심 간 거리를 저장했다면 슬롯이 3 mm 길어졌을 것입니다.

편집은 슬롯만 변경했습니다. 이미지: 작성자.
Kimi K3.1 Pro CAD 에이전트의 정확도는?
사전에 고정한 허용오차 내에서 세 번의 시도 모두 숨겨진 모든 검사를 통과했습니다. 아래 표는 요약입니다:
|
검사 항목 |
세 번의 시도 결과 |
|
숨겨진 기하 검사 통과 |
항상 13/13 |
|
참조 대비 복셀 IoU(0.5 mm 격자) |
0.998 ~ 1.0 |
|
구멍 지름(실제 6.5 mm) |
두 번 6.5 mm, 한 번 6.0 mm(자가 검토에서 통과) |
|
사용한 수정 횟수(허용 3회) |
0 |
|
편집 검사 통과 |
항상 8/8 |
세 번의 시도만으로 성공률을 말할 수는 없으며, 한 브래킷에 대해 결과가 유지되었다는 신호일 뿐입니다. 수정 단계의 6.0 mm 구멍은 ±0.5 mm 구멍 허용오차의 경계에 정확히 있었기에 통과했으며, 더 엄격했다면 실패했을 것입니다.
자가 수정은 고칠 것이 없었다
루프가 모델을 개선하는지 보여줄 테스트는 결함 주입 러닝입니다. 즉, 알려진 오류가 있는 프로그램으로 에이전트를 시작하는 것입니다. 이 글과는 별개로 보고할 사안입니다.
시도당 토큰 비용과 실행 시간
각 시도는 여섯 번의 요청과 일곱 번의 도구 호출로 6.3~7.3센트가 들었습니다. 이는 API 비용만이며, 렌더링과 Docker는 제 머신에서 수행했습니다.
각 요청 비용은 usage 필드로 계산하고, 게시된 요금을 적용하세요. kimi-k3.1-pro의 백만 토큰당 가격은 입력 $2.00, 출력 $10.00, 캐시 히트 $0.20, 5분 캐시 기록 $2.00입니다.
|
단계 |
요청 수 |
비용 비중 |
|
첫 요청 |
1 |
약 절반 |
|
수정 검토 |
2 |
약 4분의 1 |
|
편집 |
3 |
약 4분의 1 |
가장 비용이 큰 단계는 Kimi가 추론하는 첫 요청입니다. 청구의 절반 이상은 출력이며, 캐시 기록이 23~35%를 차지하는 반면, 캐시 히트 비용은 거의 없습니다. 앞서 링크한 Chat Completions 레퍼런스에 따른 세 입력 필드의 합산 방식은 다음과 같으며, 트래커가 이미 캐시 기록을 분리 집계한다면 건너뛰어도 됩니다:
uncached = u.prompt_tokens - cached - written # the three parts sum to prompt_tokens
cost = (uncached * 2.00 + cached * 0.20 + written * 2.00 + u.completion_tokens * 10.00) / 1e6
추론 토큰은 이미 completion_tokens에 포함되어 있으므로, 두 번 더하지 마세요. 5분 캐시 기록은 비캐시 입력과 같은 비용이므로, 프롬프트 캐싱은 접두부를 다시 읽을 때만 이득입니다. 도구 루프는 매 턴 같은 히스토리를 재전송하므로, 여기서는 입력 요금을 일반 요금의 40% 미만으로 낮췄습니다.
한 번의 시도는 약 3분이 걸립니다. 대부분 대기 시간이며, 클라이언트가 FAQ에서 다룰 속도 제한 때문에 요청 간격을 21초로 두었기 때문입니다.
이미지 기반 AI CAD 생성의 한계
가장 큰 한계는 이미지가 모든 치수를 담을 수 없다는 점입니다. 제 테스트는 다음 몇 가지를 더합니다:
- 렌더링은 픽셀보다 작은 디테일을 보여줄 수 없습니다. 중요한 치수는 텍스트로 제공하거나 도구로 측정하세요.
- 이 브래킷은 추측하기 쉬웠습니다. 중심에서 벗어난 구멍이나 특이한 크기는 Kimi가 픽셀을 읽는지 디자인 관습을 따르는지 시험할 것입니다.
- Docker 플래그는 지정한 것만 차단합니다. 설정 섹션의 악의적 프로그램은 막았지만, 모델 코드가 CPU를 1분 꽉 채워 쓰는 것은 여전히 가능합니다. 컨테이너 내 AI 에이전트 보안을 다룬 가이드에서 다음 단계를 확인하세요.
- 이 검사를 통과해도 강도(내력)에 대해서는 아무것도 말해주지 못합니다. 하중, 재질, 실제 부품이 필요로 할 내측 라운드, 볼트 끼움, 공차 누적 등은 이 테스트 범위를 벗어납니다.
쉬운 브래킷은 Kimi의 한계라기보다 제 테스트의 한계입니다.
마무리
우리는 네 장의 이미지에서 파라메트릭 CadQuery 코드를 작성하고, 도구로 자체 솔리드를 점검하며, 요청 시 한 피처를 편집하는 에이전트를 만들었습니다. 이 브래킷에 한해, 서두의 질문에 대한 답은 ‘예’입니다. 세 번의 시도 모두 제가 정한 허용오차 내에서 첫 요청에 통과했고, 슬롯 편집은 나머지 부품에 영향을 주지 않았습니다.
수정 루프는 보증하기 어렵습니다. Kimi가 고칠 것을 찾지 못했기 때문입니다. 자가 검토는 유효 지름이 아닌 픽셀만 보았기에 0.5 mm 오차를 통과시켰습니다. 특이한 치수의 부품이나 실제 사진으로 일반화하기는 어렵습니다.
이식 가능한 것은 참조를 숨기고, 채점 규칙을 첫 요청 전에 고정하며, 코드를 아니라 내보낸 솔리드를 채점하는 방법론입니다. Kimi는 세 번 모두 후보가 일치한다고 말했고, 평가기만이 두 번은 정확했고 한 번은 근접했다는 것을 판별했습니다. 제가 유지하길 권하는 것은 이 평가기이며, 첫 확장 실험으로는 결함 주입 러닝을 추천합니다.
모델을 자체 도구에 연결하는 방법은 Developing AI Systems with the OpenAI API 과정에서 이 에이전트가 사용하는 것과 같은 SDK로 함수 호출을 다룹니다.
FAQs
Kimi K3.1 Pro API에 어떤 이미지 형식과 크기를 보낼 수 있나요?
PNG, JPEG, GIF, WebP, BMP, HEIC, HEIF는 base64 데이터 URL로 동작하며, SVG는 인코딩해도 거부됩니다. 따라서 SVG 도면은 XML을 텍스트로 보내세요. 한 요청에는 본문 100 MB 내에서 임의의 개수의 이미지를 담을 수 있으며, 앞서 링크한 비전 가이드는 4096×2160 이하를 권장합니다. Kimi가 동영상으로 디코딩하고 과금할 수 있으므로, 애니메이션 GIF와 WebP는 피하는 것을 권합니다.
Kimi의 3D Make가 이런 CAD 에이전트를 대체할 수 있나요?
출시 블로그 기준으로, 파라메트릭 작업을 대체하기는 어렵습니다. 3D Make는 Kimi 앱과 웹사이트에 있으며, 모델을 편집하고 3D 프린팅용으로 다운로드할 수 있습니다. 블로그에는 API 접근이나 STEP 내보내기에 대한 언급이 없으므로, 변경 가능한 slot_width 를 원한다면 자체 도구 루프가 여전히 필요합니다.
Kimi K3.1 Pro 에이전트가 HTTP 429 오류를 받는 이유는 무엇인가요?
먼저 error.type 을 확인하세요. Kimi는 429를 세 가지 문제에 공통으로 사용합니다. rate_limit_reached_error는 등급별 요청 속도 제한을 초과했음을 의미합니다(잔액 $1에서 분당 3건, $10에서 200건까지 증가). exceeded_current_quota_error 는 잔액이 소진되었음을 뜻하고, engine_overloaded_error는 서버 과부하를 의미하므로, 충전 대신 백오프 후 재시도하세요.
Kimi K3.1 Pro CAD 에이전트 비용을 줄이려면?
기본 5분 캐시는 이 루프에 이미 적합합니다. 매 히트가 무료로 갱신되며, 제 요청은 21초 간격으로 도착했습니다. 사람이 턴 사이 렌더를 검토해 5분을 넘길 수 있다면, 컨텍스트 캐싱 가이드에 1시간 TTL 설정 방법이 있습니다. 백만 토큰당 $4.00의 기록 비용은 두 번의 히트부터 이득입니다. 비용이 걱정이라면 Highspeed는 피하세요. 속도는 2~3배지만, 가격은 두 배가 됩니다.
CAD 재구성에는 high와 max 중 어떤 reasoning effort를 써야 하나요?
제가 전반에 사용한 high로 시작하세요. max 를 시도한다면(이 브래킷에는 시도하지 않았습니다), 응답을 스트리밍하세요. 비스트리밍 요청이 900초 동안 응답이 없으면 게이트웨이가 504를 반환합니다. 완성 토큰 상한은 기본 131,072이며 추론을 포함하므로, 저는 32,768로 제한해 단일 응답이 출력 비용 약 33센트를 넘지 않게 했습니다.
벽에 선반을 고정하는 L자형 금속 브래킷 사진 네 장만 있고, 그에 해당하는 CAD(Computer-Aided Design) 파일은 없다고 가정해 보세요. 엔지니어는 정확한 치수를 담는 CAD 파일을 편집해 공방에 보냅니다. CAD 파일이 있으면 구멍을 옮기거나 슬롯을 넓혀도 올바른 부품을 얻을 수 있지만, 사진만으로는 불가능합니다.
필요한 것은
hole_diameter = 6.5와 같이 이름 붙은 치수로부터 브래킷을 생성하고, CAD 도구 간에 표준으로 쓰이는 STEP 파일로 저장하는 간단한 Python 프로그램입니다. Moonshot의 기술 블로그에 따르면 Kimi K3.1 Pro는 이런 공간적 작업에 강점을 보입니다. 그래서 이를 검증해 보았습니다. Kimi K3.1 Pro가 네 장의 사진을 편집 가능한 CAD 모델로 바꾸고, 도구로 스스로를 점검한 뒤, 다른 부분을 깨뜨리지 않고 한 가지 피처만 변경할 수 있을까요?공정성을 위해, 저는 CadQuery라는 CAD 모델링용 Python 라이브러리로 직접 브래킷을 만들었습니다. 그 모델에서 네 장의 이미지를 렌더링하고, 원본 CAD 파일은 Kimi에게 보여주지 않았습니다. 이 Kimi K3.1 Pro API 튜토리얼에서는, 사진만으로 Kimi가 프로그램을 작성하고, 제 코드가 이를 실행해 생성물을 측정합니다.
CAD 경험이 없어도 따라오실 수 있습니다. 다만 코드는 Python과 Docker에 익숙하다고 가정하며, 필요한 기하 개념은 등장할 때 설명합니다. 다음을 다룹니다:
출시, 벤치마크, 가격, 접근 방법은 Kimi K3.1 Pro 개요에 정리되어 있으니, 여기서는 에이전트 구현에 집중하겠습니다.
요약
저는 Kimi K3.1 Pro에게 네 장의 금속 브래킷 사진을 편집 가능한 3D 모델로 변환하라고 세 번 요청했고,
reasoning_effort="high"를 사용했습니다. 매번 거의 같은 결과를 얻었고, 예외는 하나뿐이었습니다: