[AI] LLM 의 temperature 테스트 - 1

늘 공부하는 괴짜·2025년 5월 5일
0

AI : mcp

목록 보기
8/9
post-thumbnail

모델은 exaone3.5:2.4b 로 테스트 했으며, temperature 값을 변경할 때마다 서버를 재시작한 후 첫 요청에 대한 응답값을 포스팅 하였다. 늘 그렇듯이 모델의 응답은 정확하지는 않을 것이며 참고 정도로만 할 것이다.

오늘의 테스트 항목은 temperature 속성값이다.

1. 사용자 인증 테스트 코드

xyz 사용자인증 > 주민등록번호 > 휴대폰번호 순으로 이어지는 간단한 인증 프로그램이다.
authenticate_username 도구만 사용될 것이다.

from flask import Flask, request, jsonify, render_template
from langchain.chat_models import ChatOllama
from langchain.agents import Tool, initialize_agent
from langchain.tools import tool
from langchain.memory import ConversationBufferMemory
import re

app = Flask(__name__)

# ✅ LangChain LLM 설정 (Ollama)
llm = ChatOllama(model="exaone3.5:2.4b", temperature=0.0)

# ✅ 인증 대상 사용자 목록
VALID_USERS = {
    "kim": {"ssn": "121223-2234567", "phone": "010-1234-5678"},
    "lee": {"ssn": "121223-1234567", "phone": "010-2234-5678"},
    "park": {"ssn": "121223-3234567", "phone": "010-0234-5678"}
}

# ✅ 대화 상태 메모리 설정
memory = ConversationBufferMemory(memory_key="chat_history", return_messages=True)

# ✅ 도구 정의: 사용자명 인증
@tool
def authenticate_username(input: str) -> str:
    """
        사용자명을 입력하면 등록 여부를 확인하고 상태를 갱신합니다.

        예시 : lee 사용자인증
    """
    match = re.search(r"[가-힣a-zA-Z0-9_]+", input)
    if not match:
        return "사용자명을 추출할 수 없습니다. 다시 입력해주세요."

    username = match.group(0).lower()
    if username in VALID_USERS:
        memory.chat_memory.add_user_message("STEP:USERNAME_OK")
        memory.chat_memory.add_user_message(f"CURRENT_USER:{username}")
        return f"{username}님이 확인되었습니다. 주민등록번호를 입력해주세요. (예: 123456-1234567)"
    else:
        return f"{username}은(는) 등록되지 않은 사용자입니다."


# ✅ 도구 정의: 주민등록번호 인증
@tool
def authenticate_ssn(input: str) -> str:
    """
    주민등록번호를 입력하면 등록 여부를 확인하고 상태를 갱신합니다.

    예시 : 123456-1234567 주민등록번호인증
    """
    match = re.search(r"\d{6}-\d{7}", input)
    if not match:
        return "주민등록번호를 추출할 수 없습니다. 다시 입력해주세요."

    ssn = match.group(0)

    # 대화 히스토리에서 CURRENT_USER 찾기
    history = memory.load_memory_variables({})["chat_history"]
    user_match = re.search(r"CURRENT_USER:(\w+)", str(history))
    if not user_match:
        return "현재 사용자 정보가 없습니다. 사용자명부터 인증해주세요."

    username = user_match.group(1)

    # 인증 대상 이름의 주민등록번호와 일치하는지 확인
    if VALID_USERS.get(username, {}).get("ssn") == ssn:
        memory.chat_memory.add_user_message("STEP:SSN_OK")
        memory.chat_memory.add_user_message(f"CURRENT_SSN:{ssn}")
        return f"{ssn} 주민등록번호가 확인되었습니다. 휴대폰번호를 입력해주세요. (예: 010-1234-5678)"
    else:
        return f"{ssn} 주민등록번호는 등록되지 않은 번호입니다."


# ✅ 도구 정의: 휴대폰번호 인증
@tool
def authenticate_phone(input: str) -> str:
    """
    휴대폰번호를 입력하면 등록 여부를 확인하고 상태를 갱신합니다.

    예시 : 010-1234-5678 휴대폰번호인증
    """
    match = re.search(r"\d{3}-\d{4}-\d{4}", input)
    if not match:
        return "휴대폰번호를 추출할 수 없습니다. 다시 입력해주세요."

    phone = match.group(0)

    # 대화 히스토리에서 CURRENT_USER 찾기
    history = memory.load_memory_variables({})["chat_history"]
    user_match = re.search(r"CURRENT_USER:(\w+)", str(history))
    
    if not user_match:
        return "현재 사용자 정보가 없습니다. 사용자명부터 인증해주세요."

    username = user_match.group(1)

    # 인증 대상 이름의 휴대폰번호와 일치하는지 확인
    if VALID_USERS.get(username, {}).get("phone") == phone:
        memory.chat_memory.add_user_message("STEP:PHONE_OK")
        memory.chat_memory.add_user_message(f"CURRENT_PHONE:{phone}")
        return f"{phone} 휴대폰번호가 확인되었습니다. 인증이 완료되었습니다. 축하합니다."
    else:
        return f"{phone} 휴대폰번호는 등록되지 않은 번호입니다."



# ✅ 도구 목록
tools = [
    Tool.from_function(authenticate_username, name="authenticate_username", description="사용자명을 인증합니다."),
    Tool.from_function(authenticate_ssn, name="authenticate_ssn", description="주민등록번호를 인증합니다."),
    Tool.from_function(authenticate_phone, name="authenticate_phone", description="휴대폰번호를 인증합니다.")
]

# ✅ LangChain ReAct Agent 생성
agent = initialize_agent(
    tools=tools,
    llm=llm,
    agent="zero-shot-react-description",
    memory=memory,
    verbose=True,
    handle_parsing_errors=True
)

# ✅ 웹 라우팅
@app.route("/")
def index():
    return render_template("index.html")  # HTML UI가 있는 경우

@app.route("/mcp-auth", methods=["POST"])
def mcp_auth():
    user_input = request.json.get("message", "")
    if not user_input:
        return jsonify({"error": "메시지가 제공되지 않았습니다"}), 400

    try:
        response = agent.run(user_input)
        return jsonify({"response": response})
    except Exception as e:
        return jsonify({"error": str(e)}), 500

# ✅ 서버 실행
if __name__ == "__main__":
    app.run(debug=True, host="0.0.0.0", port=5001)

2. temperature 0.0~1.0 Test

authenticate_username 도구만 가지고 테스트 해보겠다.
"XXX 사용자인증" 이라고 요청을 내려보겠다.

2-1. 0.0

나름 깔끔한 응답을 해줬다.

2-2. 0.1

잡설이 좀 늘었지만 이해할 수준의 문장이다.

2-3. 0.2

0.1 보다는 깔끔하지만 0.0에 비하면 좀 조잡한 응답이다.

2-4. 0.3

음... 잘 모르겠다.

2-5. 0.4

점점 잡소리를 많이 갈아넣는듯...

2-6. 0.5

2-7. 0.6

2-8. 0.7

2-9. 0.8

2-10. 0.9

2-11. 1.0

Finally

0.0 을 제외한 나머지는 적당량의 잡소리를 섞어가며 응답을 해줬는데 그마저도 거의 랜덤이었다. 검색을 좀 해보니 0에 가까울수록 직관적이며 1에 가까울수록 창의적(인 잡소리)으로 응답을 해준다고 한다.

값 범위의미사용 가능 여부
0완전히 결정적 (무작위 없음)✅ 예
0 ~ 1일반적인 무작위성 조절✅ 예
>1매우 무작위함⚠️ 가능하지만 품질 저하
< 0 (음수)수학적으로 무의미 / 에러❌ 불가능
profile
인공지능이라는 옷을 입었습니다. 뭔가 멋지면서도 잘 맞습니다.

0개의 댓글