Skip to main content
Glama
token-estimator.ts3.96 kB
/** * 휴리스틱 기반 토큰 추정기 * Zero dependency로 텍스트의 토큰 수를 추정합니다. * 한국어, 영어, 코드가 혼합된 BaaS 문서에 최적화되어 있습니다. * Toss MCP의 TokenEstimator를 참고하여 구현했습니다. */ export class TokenEstimator { // 기본 문자당 토큰 비율 (평균적으로 문자 1개당 0.75 토큰) private static readonly CHAR_TO_TOKEN_RATIO = 0.75; // 한국어 가중치 (한국어는 토큰 비율이 높음) private static readonly KOREAN_WEIGHT = 0.8; // 코드 블록 비율 (코드는 토큰 효율이 좋음) private static readonly CODE_BLOCK_RATIO = 0.3; // URL당 평균 토큰 수 private static readonly URL_TOKENS = 8; // 인라인 코드 가중치 private static readonly INLINE_CODE_RATIO = 0.4; /** * 텍스트의 토큰 수를 추정합니다. * @param text 토큰 수를 추정할 텍스트 * @returns 추정된 토큰 수 */ static estimate(text: string): number { if (!text || text.length === 0) return 0; // 기본 문자 수 기반 추정 let estimate = text.length * this.CHAR_TO_TOKEN_RATIO; // 한국어 문자 가중치 적용 estimate += this.calculateKoreanWeight(text); // 코드 블록 최적화 estimate += this.calculateCodeBlockWeight(text); // 인라인 코드 최적화 estimate += this.calculateInlineCodeWeight(text); // URL 가중치 적용 estimate += this.calculateUrlWeight(text); // 마크다운 헤더 가중치 (헤더는 보통 짧지만 중요) estimate += this.calculateHeaderWeight(text); return Math.ceil(Math.max(estimate, 1)); // 최소 1 토큰 } /** * 한국어 문자에 대한 가중치 계산 */ private static calculateKoreanWeight(text: string): number { const koreanChars = (text.match(/[ㄱ-ㅎ|ㅏ-ㅣ|가-힣]/g) || []).length; return koreanChars * this.KOREAN_WEIGHT; } /** * 코드 블록에 대한 가중치 계산 (토큰 효율이 좋음) */ private static calculateCodeBlockWeight(text: string): number { const codeBlocks = text.match(/```[\s\S]*?```/g) || []; let adjustment = 0; for (const block of codeBlocks) { // 코드 블록은 일반 텍스트보다 토큰 효율이 좋음 const normalEstimate = block.length * this.CHAR_TO_TOKEN_RATIO; const codeEstimate = block.length * this.CODE_BLOCK_RATIO; adjustment += codeEstimate - normalEstimate; } return adjustment; } /** * 인라인 코드에 대한 가중치 계산 */ private static calculateInlineCodeWeight(text: string): number { // 코드 블록을 제거한 후 인라인 코드 찾기 const withoutCodeBlocks = text.replace(/```[\s\S]*?```/g, ""); const inlineCodes = withoutCodeBlocks.match(/`[^`]+`/g) || []; let adjustment = 0; for (const code of inlineCodes) { const normalEstimate = code.length * this.CHAR_TO_TOKEN_RATIO; const codeEstimate = code.length * this.INLINE_CODE_RATIO; adjustment += codeEstimate - normalEstimate; } return adjustment; } /** * URL에 대한 가중치 계산 */ private static calculateUrlWeight(text: string): number { const urls = text.match(/https?:\/\/[^\s]+/g) || []; let adjustment = 0; for (const url of urls) { // URL은 일반적으로 많은 토큰을 차지하므로 추가 가중치 적용 const normalEstimate = url.length * this.CHAR_TO_TOKEN_RATIO; const urlEstimate = Math.max(this.URL_TOKENS, normalEstimate); adjustment += urlEstimate - normalEstimate; } return adjustment; } /** * 마크다운 헤더에 대한 가중치 계산 */ private static calculateHeaderWeight(text: string): number { const headers = text.match(/^#{1,6}\s+.+$/gm) || []; // 헤더는 보통 중요한 키워드가 포함되어 있어 약간의 가중치 추가 return headers.length * 2; } }

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/mbaas-inc/BaaS-MCP'

If you have feedback or need assistance with the MCP directory API, please join our Discord server