Files
conai/backend/app/services/ai_engine.py
sinmb79 2a4950d8a0 feat: CONAI Phase 1 MVP 초기 구현
소형 건설업체(100억 미만)를 위한 AI 기반 토목공사 통합관리 플랫폼

Backend (FastAPI):
- SQLAlchemy 모델 13개 (users, projects, wbs, tasks, daily_reports, reports, inspections, quality, weather, permits, rag, settings)
- API 라우터 11개 (auth, projects, tasks, daily_reports, reports, inspections, weather, rag, kakao, permits, settings)
- Services: Claude AI 래퍼, CPM Gantt 계산, 기상청 API, RAG(pgvector), 카카오 Skill API
- Alembic 마이그레이션 (pgvector 포함)
- pytest 테스트 (CPM, 날씨 경보)

Frontend (Next.js 15):
- 11개 페이지 (대시보드, 프로젝트, Gantt, 일보, 검측, 품질, 날씨, 인허가, RAG, 설정)
- TanStack Query + Zustand + Tailwind CSS

인프라:
- Docker Compose (PostgreSQL pgvector + backend + frontend)
- 한국어 README 및 설치 가이드

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-24 20:06:36 +09:00

52 lines
1.4 KiB
Python

"""
Core Claude API wrapper.
Shared by all AI-powered features: daily reports, inspection gen, report gen, RAG.
"""
import anthropic
from app.config import settings
_client: anthropic.AsyncAnthropic | None = None
def get_client() -> anthropic.AsyncAnthropic:
global _client
if _client is None:
_client = anthropic.AsyncAnthropic(api_key=settings.ANTHROPIC_API_KEY)
return _client
async def complete(
messages: list[dict],
system: str,
temperature: float = 0.3,
max_tokens: int | None = None,
) -> str:
"""
Call Claude and return the text response.
Logs token usage for cost monitoring.
"""
client = get_client()
response = await client.messages.create(
model=settings.CLAUDE_MODEL,
max_tokens=max_tokens or settings.CLAUDE_MAX_TOKENS,
temperature=temperature,
system=system,
messages=messages,
)
# Log token usage
usage = response.usage
print(f"[AI] input={usage.input_tokens} output={usage.output_tokens} total={usage.input_tokens + usage.output_tokens}")
return response.content[0].text
async def complete_json(
messages: list[dict],
system: str,
temperature: float = 0.3,
) -> str:
"""Call Claude with JSON output instruction."""
json_system = system + "\n\n반드시 유효한 JSON 형식으로만 응답하세요. 다른 텍스트를 포함하지 마세요."
return await complete(messages, json_system, temperature)