Files
Pier_v1/.hmcmkit/tools/ambiguity_checker.py
T
ahnyongjooandClaude Sonnet 5.5 964a841de1 chore(rebar): Pier_T_rebar 작업 폴더 초기 구성 및 외부 의존 파일 통합
- Code\rebar_pipeline, review_pipeline, pier-program을 정션에서 실제 폴더로 전환
- Code\rhino_mcp 및 CLAUDE_rhino배경.md 추가, .mcp.json은 PYTHONPATH로 새 위치 사용
- pier-program 내부 .git 제거(이력은 backup\pier-program_20261028.bundle에 보관)
- worktree 가이드 반영(CLAUDE.local.md, HANDOFF.md)
- D:\Rhino-MCP 경로 참조를 새 위치로 치환

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-28 11:20:18 +09:00

93 lines
3.3 KiB
Python

import re
import sys
import json
def calculate_ambiguity_score(user_request, context={}):
score = 0
factors = []
# Factor 1: No file path (higher ambiguity)
file_path_pattern = r'(\/[\w.-]+\/[\w.-]+)|([A-Z]:\\[\w.-]+\\[\w.-]+)|(\.\/[\w.-]+)|(\.(js|ts|py|go|rs|java|tsx|jsx|vue|svelte|md|json|yaml|yml)$)'
if not re.search(file_path_pattern, user_request, re.IGNORECASE):
factors.append('no_file_path')
score += 0.15
# Factor 2: No technical terms
tech_terms = [
'api', 'database', 'server', 'client', 'component', 'module',
'function', 'class', 'interface', 'type', 'schema', 'endpoint',
'authentication', 'authorization', 'middleware', 'controller',
'service', 'repository', 'model', 'view', 'hook', 'context'
]
if not any(term in user_request.lower() for term in tech_terms):
factors.append('no_technical_terms')
score += 0.1
# Factor 3: No specific nouns (PascalCase or camelCase)
if not re.search(r'("[^"]+")|(\'[^\']+\')|([A-Z][a-z]+[A-Z][a-z]+)|([a-z]+[A-Z][a-z]+)', user_request):
factors.append('no_specific_nouns')
score += 0.15
# Factor 4: No scope definition
scope_patterns = [
r'only|just|specifically|exactly',
r'all|every|entire|whole',
r'from\s+\w+\s+to\s+\w+',
r'in\s+the\s+\w+\s+(?:file|folder|directory|module)'
]
if not any(re.search(p, user_request, re.IGNORECASE) for p in scope_patterns):
factors.append('no_scope')
score += 0.1
# Factor 5: Multiple interpretations
ambiguous_patterns = [
r'maybe|perhaps|or|either',
r'it|this|that|those|these',
r'stuff|things|something',
r'fix|update|change|modify'
]
pronoun_count = len(re.findall(r'\b(it|this|that)\b', user_request, re.IGNORECASE))
if pronoun_count >= 2 or any(re.search(p, user_request, re.IGNORECASE) for p in ambiguous_patterns):
factors.append('multiple_interpretations')
score += 0.2
# Factor 6: Short request
if len(user_request) < 30:
factors.append('short_request')
score += 0.15
# Factor 7: Context Conflict (New in v2)
# Check if request contradicts current phase
current_phase = context.get('current_feature_phase', 'PLAN')
phase_keywords = {
'PLAN': ['implement', 'code', 'build', 'deploy'],
'DESIGN': ['deploy', 'test', 'release'],
'DO': ['plan', 'design', 'architecture']
}
conflict_keywords = phase_keywords.get(current_phase, [])
for keyword in conflict_keywords:
if keyword in user_request.lower():
factors.append(f'context_conflict_with_{current_phase}')
score += 0.15
break
score = min(1.0, max(0.0, score))
return {"score": score, "factors": factors}
if __name__ == "__main__":
if len(sys.argv) < 2:
print(json.dumps({"error": "No request provided"}))
sys.exit(1)
request = sys.argv[1]
# Simulate context from arg 2 if present
context = {}
if len(sys.argv) > 2:
try:
context = json.loads(sys.argv[2])
except:
pass
result = calculate_ambiguity_score(request, context)
print(json.dumps(result, indent=2))