-
Notifications
You must be signed in to change notification settings - Fork 0
[Feat] Connect GPT API #9
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. Weβll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
μλ΅νμ λ³κ²½ ν둬ννΈ λΈλ‘ λ³λ νμΌμ μμ±
|
""" WalkthroughGPT API μ°λμ μν μ£Όμ λ°±μλ κΈ°λ₯μ΄ μΆκ°λμμ΅λλ€. FastAPI μλν¬μΈνΈ, μλΉμ€ λ μ΄μ΄, ν둬ννΈ μμ±, μμ λ°μ΄ν°, μ€μ κ΄λ¦¬, λͺ¨λΈ μ μ λ±μ΄ μ κ·λ‘ λμ λμκ³ , λ°°ν¬ μν¬νλ‘μ μμ‘΄μ±λ 보κ°λμμ΅λλ€. κΈ°μ‘΄ λΌμ°ν°λ μμ λ° κ²½λ‘κ° λ³κ²½λμμ΅λλ€. Changes
Sequence Diagram(s)sequenceDiagram
participant Client
participant FastAPI (fraud_analysis)
participant GPTService
participant OpenAI API
Client->>FastAPI (fraud_analysis): POST /api/fraud-analysis (FraudRequest)
FastAPI (fraud_analysis)->>GPTService: call_gpt(request)
GPTService->>OpenAI API: GPT-4o-mini λͺ¨λΈλ‘ ν둬ννΈ μμ²
OpenAI API-->>GPTService: JSON μλ΅ λ°ν
GPTService-->>FastAPI (fraud_analysis): FraudResponse νμ±/λ°ν
FastAPI (fraud_analysis)-->>Client: FraudResponse λ°ν
Estimated code review effortπ― 3 (Moderate) | β±οΈ ~18 minutes Poem
Note β‘οΈ Unit Test Generation is now available in beta!Learn more here, or try it out under "Finishing Touches" below. π Recent review detailsConfiguration used: CodeRabbit UI π Files selected for processing (6)
π§ Files skipped from review as they are similar to previous changes (6)
β° Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
β¨ Finishing Touches
π§ͺ Generate unit tests
πͺ§ TipsChatThere are 3 ways to chat with CodeRabbit:
SupportNeed help? Create a ticket on our support page for assistance with any issues or questions. Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments. CodeRabbit Commands (Invoked using PR comments)
Other keywords and placeholders
CodeRabbit Configuration File (
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 9
π§Ή Nitpick comments (8)
app/models/fraud_request.py (1)
8-8: imageContent νλμ λν κ²μ¦ μΆκ°λ₯Ό κ³ λ €νμΈμ.
imageContentκ° λ¬Έμμ΄λ‘ μ μλμ΄ μμ§λ§ base64 μΈμ½λ©λ μ΄λ―Έμ§ λ°μ΄ν°μΈμ§ URLμΈμ§ λͺ ννμ§ μμ΅λλ€. μ μ ν κ²μ¦μ μΆκ°νλ κ²μ κΆμ₯ν©λλ€.from pydantic import BaseModel, Field, validator from typing import List, Optional import base64 class FraudRequest(BaseModel): messageContent: str keywords: List[str] additionalDescription: Optional[str] = None - imageContent: Optional[str] = None + imageContent: Optional[str] = Field(None, description="Base64 encoded image or image URL") + + @validator('imageContent') + def validate_image_content(cls, v): + if v and not (v.startswith('data:image/') or v.startswith('http')): + # Check if it's valid base64 + try: + base64.b64decode(v) + except Exception: + raise ValueError('imageContent must be base64 encoded image, data URL, or HTTP URL') + return v.coderabbit/config.yml (1)
1-2: νμΌ λμ κ°ν λ¬Έμλ₯Ό μΆκ°νμΈμ.YAML νμΌμ λͺ¨λ² μ¬λ‘μ λ°λΌ νμΌ λμ κ°ν λ¬Έμκ° νμν©λλ€.
features: - docstrings: false + docstrings: false +.github/workflows/deploy.yml (1)
64-64: νμΌ λμ κ°ν λ¬Έμλ₯Ό μΆκ°νμΈμ.YAML νμΌμ λͺ¨λ² μ¬λ‘μ λ°λΌ νμΌ λμ κ°ν λ¬Έμκ° νμν©λλ€.
-e GPT_API_KEY="${{ env.GPT_API_KEY }}" \ - ${{ env.DOCKER_REPO }}:latest + ${{ env.DOCKER_REPO }}:latest +app/config/setting.py (1)
9-9: μ€μ μΈμ€ν΄μ€ μ΄κΈ°ν μ μμΈ μ²λ¦¬ κ³ λ €νκ²½λ³μκ° λλ½λκ±°λ μλͺ»λ κ²½μ°λ₯Ό λλΉν μμΈ μ²λ¦¬λ₯Ό μΆκ°νλ κ²μ΄ μ’μ΅λλ€.
λ€μκ³Ό κ°μ΄ κ°μ ν μ μμ΅λλ€:
-settings = Settings() +try: + settings = Settings() +except Exception as e: + raise RuntimeError(f"μ€μ μ΄κΈ°ν μ€ν¨: {e}")app/models/fraud_response.py (1)
1-1: μ¬μ©νμ§ μλ import μ κ±°
conintκ° importλμμ§λ§ μ¬μ©λμ§ μμ΅λλ€.-from pydantic import BaseModel, conint +from pydantic import BaseModel, Field, validatorapp/prompts/fraud_example.py (1)
4-9: νλ κ²μ¦ λ° λ¬Έμν κ°μνμ¬ λͺ¨λ νλκ° κΈ°λ³Έ νμ μΌλ‘λ§ μ μλμ΄ μμ΄ κ²μ¦μ΄ λΆμ‘±ν©λλ€. νΉν λΉ κ°μ΄λ μλͺ»λ λ°μ΄ν°μ λν μ²λ¦¬κ° νμν©λλ€.
λ€μκ³Ό κ°μ΄ κ°μ ν μ μμ΅λλ€:
-from pydantic import BaseModel +from pydantic import BaseModel, Field, validator from typing import List class FraudExample(BaseModel): - type_name: str - message_content: str - keywords: List[str] - additional_description: str - image_content: str + type_name: str = Field(..., min_length=1, description="μ¬κΈ° μ νλͺ ") + message_content: str = Field(..., min_length=1, description="λ©μμ§ λ΄μ©") + keywords: List[str] = Field(..., min_items=1, description="ν€μλ λͺ©λ‘") + additional_description: str = Field(default="", description="μΆκ° μ€λͺ ") + image_content: str = Field(default="", description="μ΄λ―Έμ§ λ΄μ©") + + @validator('type_name', 'message_content') + def validate_required_fields(cls, v): + if not v.strip(): + raise ValueError('νμ νλλ λΉ κ°μΌ μ μμ΅λλ€') + return v.strip()app/services/gpt_service.py (1)
6-8: OpenAI ν΄λΌμ΄μΈνΈ λΉλκΈ° μ΄κΈ°ν κ³ λ €νμ¬ λκΈ° ν΄λΌμ΄μΈνΈλ₯Ό μ¬μ©νκ³ μμ§λ§, λΉλκΈ° ν¨μμμ μ¬μ©νλ―λ‘
AsyncOpenAIλ₯Ό μ¬μ©νλ κ²μ΄ λ μ μ ν©λλ€.-from openai import OpenAI, OpenAIError +from openai import AsyncOpenAI, OpenAIError -client = OpenAI( +client = AsyncOpenAI( api_key = settings.gpt_api_key )app/prompts/fraud_prompts.py (1)
10-10: λλμ μμ λ°μ΄ν° μ²λ¦¬ μ μ±λ₯μ κ³ λ €νμΈμ.κΈ°λ³Έκ°μΌλ‘
FRAUD_EXAMPLESμ 체λ₯Ό μ¬μ©νκ³ μλλ°, ν₯ν 60-70κ° μμκ° λͺ¨λ μΆκ°λλ©΄ ν ν° μ¬μ©λμ΄ ν¬κ² μ¦κ°ν μ μμ΅λλ€. PR λͺ©νμμλ μΈκΈλ μ°λ €μ¬νμ λλ€.μμ κ°μλ₯Ό μ ννλ λ§€κ°λ³μλ₯Ό μΆκ°νλ κ²μ κ³ λ €ν΄ λ³΄μΈμ:
def get_fraud_detection_prompt( message_content: str, additional_description: str, keywords: List[str], image_content: str, examples: List[FraudExample] = FRAUD_EXAMPLES, max_examples: int = 10 # μμ κ°μ μ ν ) -> List[Dict[str, str]]: # μμ κ°μ μ ν λ‘μ§ μΆκ° limited_examples = examples[:max_examples] if max_examples else examples
π Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
π Files selected for processing (13)
.coderabbit/config.yml(1 hunks).github/workflows/deploy.yml(2 hunks)app/api/fraud_analysis.py(1 hunks)app/config/setting.py(1 hunks)app/main.py(1 hunks)app/models/fraud_request.py(1 hunks)app/models/fraud_response.py(1 hunks)app/prompts/data/fraud_examples.py(1 hunks)app/prompts/fraud_example.py(1 hunks)app/prompts/fraud_prompts.py(1 hunks)app/routers/fraud_analysis.py(0 hunks)app/services/gpt_service.py(1 hunks)requirements.txt(1 hunks)
π€ Files with no reviewable changes (1)
- app/routers/fraud_analysis.py
π§° Additional context used
𧬠Code Graph Analysis (5)
app/main.py (1)
app/api/fraud_analysis.py (1)
fraud_analysis(13-20)
app/services/gpt_service.py (2)
app/models/fraud_request.py (1)
FraudRequest(4-8)app/prompts/fraud_prompts.py (1)
get_fraud_detection_prompt(5-52)
app/prompts/data/fraud_examples.py (1)
app/prompts/fraud_example.py (1)
FraudExample(4-9)
app/api/fraud_analysis.py (3)
app/services/gpt_service.py (1)
call_gpt(10-32)app/models/fraud_request.py (1)
FraudRequest(4-8)app/models/fraud_response.py (1)
FraudResponse(4-8)
app/prompts/fraud_prompts.py (1)
app/prompts/fraud_example.py (1)
FraudExample(4-9)
πͺ YAMLlint (1.37.1)
.coderabbit/config.yml
[error] 2-2: no new line character at the end of file
(new-line-at-end-of-file)
.github/workflows/deploy.yml
[error] 64-64: no new line character at the end of file
(new-line-at-end-of-file)
πͺ Ruff (0.12.2)
app/services/gpt_service.py
28-28: Within an except clause, raise exceptions with raise ... from err or raise ... from None to distinguish them from errors in exception handling
(B904)
app/models/fraud_response.py
1-1: pydantic.conint imported but unused
Remove unused import: pydantic.conint
(F401)
app/api/fraud_analysis.py
20-20: Within an except clause, raise exceptions with raise ... from err or raise ... from None to distinguish them from errors in exception handling
(B904)
πͺ GitHub Actions: CI/CD pipeline test
requirements.txt
[error] 4-4: pip install failed: No matching distribution found for click==8.2.1. The required version requires Python >=3.10 but the environment uses Python 3.9.
π Additional comments (10)
app/main.py (2)
2-2: LGTM! λͺ¨λ ꡬ쑰 κ°μ μ΄ μ λ°μλμμ΅λλ€.
app.routersμμapp.apiλ‘μ import κ²½λ‘ λ³κ²½μ΄ μλ‘μ΄ νλ‘μ νΈ κ΅¬μ‘°λ₯Ό μ λ°μνκ³ μμ΅λλ€.
7-7: LGTM! REST API λͺ λͺ κ·μΉμ μ€μν©λλ€.λΌμ°ν° prefixμ tagμμ μΈλμ€μ½μ΄λ₯Ό νμ΄νμΌλ‘ λ³κ²½ν κ²μ΄ REST API λͺ¨λ² μ¬λ‘λ₯Ό μ λ°λ₯΄κ³ μμ΅λλ€.
requirements.txt (1)
3-22: κ²μ¦ κ²°κ³Ό: λͺ¨λ μ ν¨ν€μ§λ Python 3.9μ νΈνλ©λλ€.
- certifi
- distro
- dotenv
- httpcore
- httpx
- jiter
- openai
- pydantic-settings
- tqdm
μ ν¨ν€μ§λ€ λͺ¨λ Python 3.9μμ μꡬμ¬ν μ€λ₯ μμ΄ μ€μΉ κ°λ₯ν¨μ νμΈνμ΅λλ€.
λ°λΌμ μΆκ° μ‘°μΉλ νμνμ§ μμ΅λλ€..github/workflows/deploy.yml (2)
17-17: LGTM! API ν€ λ³΄μ μ²λ¦¬κ° μ μ ν©λλ€.GitHub Secretsλ₯Ό ν΅ν GPT API ν€ κ΄λ¦¬κ° 보μ λͺ¨λ² μ¬λ‘λ₯Ό μ λ°λ₯΄κ³ μμ΅λλ€.
60-64: LGTM! Docker 컨ν μ΄λμ νκ²½ λ³μ μ λ¬μ΄ μ¬λ°λ¦ λλ€.Docker run λͺ λ Ήμ΄μμ νκ²½ λ³μλ₯Ό μμ νκ² μ λ¬νλ λ°©μμ΄ μ μ ν©λλ€.
app/prompts/data/fraud_examples.py (2)
5-28: μ¬κΈ° μμ λ°μ΄ν° κ΅¬μ‘°κ° μ μ€κ³λμμ΅λλ€.κ° μ¬κΈ° μ νλ³λ‘ μ μ ν μμ λ°μ΄ν°κ° μ 곡λκ³ μμΌλ©°, νκ΅μ΄ 컨ν μ€νΈμ λ§λ νμ€μ μΈ μ¬κΈ° μλ리μ€λ₯Ό λ°μνκ³ μμ΅λλ€. ν€μλμ μΆκ° μ€λͺ μ΄ ν둬ννΈ μμ§λμ΄λ§μ μ μ©ν 컨ν μ€νΈλ₯Ό μ 곡ν κ²μΌλ‘ 보μ λλ€.
27-27: λ°μ΄ν° μμ±λ νμΈμ΄ νμν©λλ€.μ£Όμμμ μΈκΈλ 18κ° μ ν Γ 3
4κ° μμ (μ΄ 6070κ° νλͺ©)κ° μμ§ μμ±λμ§ μμ μνμ λλ€.μ 체 λ°μ΄ν°μ μμ± κ³νκ³Ό νμλΌμΈμ νμΈν΄ μ£ΌμΈμ. νμ¬ 3κ° μμλ§μΌλ‘λ GPT λͺ¨λΈμ μ±λ₯μ΄ μ νλ μ μμ΅λλ€.
app/prompts/fraud_prompts.py (3)
5-11: ν¨μ μκ·Έλμ²κ° μ μ€κ³λμμ΅λλ€.λ§€κ°λ³μ νμ ννΈμ κΈ°λ³Έκ° μ€μ μ΄ μ μ νλ©°, λ°ν νμ λ λͺ ννκ² μ μλμ΄ μμ΅λλ€.
13-28: μμ€ν ν둬ννΈκ° λͺ ννκ³ κ΅¬μ²΄μ μ λλ€.JSON μΆλ ₯ νμμ λͺ μνκ³ νκ΅μ΄λ‘ λͺ νν μ§μμ¬νμ μ 곡νκ³ μμ΄ GPT λͺ¨λΈμ΄ μΌκ΄λ μλ΅μ μμ±ν μ μμ κ²μΌλ‘ 보μ λλ€.
54-68: μμ λ°μ΄ν° ν¬λ§·ν λ‘μ§μ΄ ν¨μ¨μ μ λλ€.
build_example_linesν¨μκ° μμ λ°μ΄ν°λ₯Ό μΌκ΄λ νμμΌλ‘ λ³ννκ³ μμΌλ©°, JSON μμλ ν¬ν¨νμ¬ λͺ¨λΈμ μ΄ν΄λ₯Ό λκ³ μμ΅λλ€.
app/api/fraud_analysis.py
Outdated
| try: | ||
| answer = await call_gpt(request) | ||
| response = FraudResponse.model_validate_json(answer) | ||
| return response | ||
|
|
||
| except Exception as e: | ||
| raise HTTPException(status_code=500, detail=f"μ¬κΈ°λΆμ μ€ν¨: {e}") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
μμΈ μ²λ¦¬ λ° μ€λ₯ λ‘κΉ κ°μ νμ
νμ¬ μμΈ μ²λ¦¬μμ μλ³Έ μμΈ μ λ³΄κ° μμ€λκ³ , λ‘κΉ μ΄ μμ΄ λλ²κΉ μ΄ μ΄λ ΅μ΅λλ€. λν JSON νμ± μ€ν¨μ GPT API νΈμΆ μ€ν¨λ₯Ό ꡬλΆνμ¬ μ²λ¦¬νλ κ²μ΄ μ’μ΅λλ€.
λ€μκ³Ό κ°μ΄ κ°μ ν μ μμ΅λλ€:
+import logging
+
+logger = logging.getLogger(__name__)
+
async def fraud_analysis(request: FraudRequest):
try:
answer = await call_gpt(request)
+ logger.info(f"GPT μλ΅ μμ : {len(answer)} κΈμ")
+ except Exception as e:
+ logger.error(f"GPT API νΈμΆ μ€ν¨: {e}", exc_info=True)
+ raise HTTPException(status_code=500, detail=f"GPT API νΈμΆ μ€ν¨: {e}") from e
+
+ try:
response = FraudResponse.model_validate_json(answer)
return response
-
except Exception as e:
- raise HTTPException(status_code=500, detail=f"μ¬κΈ°λΆμ μ€ν¨: {e}")
+ logger.error(f"μλ΅ νμ± μ€ν¨: {e}, μλ³Έ μλ΅: {answer}", exc_info=True)
+ raise HTTPException(status_code=500, detail=f"μλ΅ νμ± μ€ν¨: {e}") from eπ Committable suggestion
βΌοΈ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| try: | |
| answer = await call_gpt(request) | |
| response = FraudResponse.model_validate_json(answer) | |
| return response | |
| except Exception as e: | |
| raise HTTPException(status_code=500, detail=f"μ¬κΈ°λΆμ μ€ν¨: {e}") | |
| import logging | |
| logger = logging.getLogger(__name__) | |
| async def fraud_analysis(request: FraudRequest): | |
| try: | |
| answer = await call_gpt(request) | |
| logger.info(f"GPT μλ΅ μμ : {len(answer)} κΈμ") | |
| except Exception as e: | |
| logger.error(f"GPT API νΈμΆ μ€ν¨: {e}", exc_info=True) | |
| raise HTTPException(status_code=500, detail=f"GPT API νΈμΆ μ€ν¨: {e}") from e | |
| try: | |
| response = FraudResponse.model_validate_json(answer) | |
| return response | |
| except Exception as e: | |
| logger.error(f"μλ΅ νμ± μ€ν¨: {e}, μλ³Έ μλ΅: {answer}", exc_info=True) | |
| raise HTTPException(status_code=500, detail=f"μλ΅ νμ± μ€ν¨: {e}") from e |
π§° Tools
πͺ Ruff (0.12.2)
20-20: Within an except clause, raise exceptions with raise ... from err or raise ... from None to distinguish them from errors in exception handling
(B904)
π€ Prompt for AI Agents
In app/api/fraud_analysis.py around lines 14 to 20, the current exception
handling loses the original error details and lacks logging, making debugging
difficult. Improve this by adding proper logging of the caught exceptions and
differentiate between JSON parsing errors and GPT API call failures using
separate except blocks. This will help provide clearer error context and
maintain the original exception information in the HTTPException detail.
| from pydantic_settings import BaseSettings | ||
|
|
||
| class Settings(BaseSettings): | ||
| gpt_api_key: str |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
π οΈ Refactor suggestion
API ν€ νλμ λν κ²μ¦ κ°ν νμ
API ν€λ νμ νλμ΄λ―λ‘ λͺ μμ μΌλ‘ μ€μ νκ³ κΈ°λ³Έκ°μ μ κ±°νλ κ²μ΄ μ’μ΅λλ€. λν λΉ λ¬Έμμ΄ κ²μ¦λ μΆκ°ν΄μΌ ν©λλ€.
λ€μκ³Ό κ°μ΄ κ°μ ν μ μμ΅λλ€:
+from pydantic import Field, validator
+
class Settings(BaseSettings):
- gpt_api_key: str
+ gpt_api_key: str = Field(..., min_length=1, description="OpenAI GPT API ν€")
+
+ @validator('gpt_api_key')
+ def validate_api_key(cls, v):
+ if not v or not v.strip():
+ raise ValueError('API ν€λ νμμ
λλ€')
+ return v.strip()π Committable suggestion
βΌοΈ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| gpt_api_key: str | |
| from pydantic import Field, validator | |
| class Settings(BaseSettings): | |
| gpt_api_key: str = Field(..., min_length=1, description="OpenAI GPT API ν€") | |
| @validator('gpt_api_key') | |
| def validate_api_key(cls, v): | |
| if not v or not v.strip(): | |
| raise ValueError('API ν€λ νμμ λλ€') | |
| return v.strip() |
π€ Prompt for AI Agents
In app/config/setting.py at line 4, the gpt_api_key field currently lacks
validation and a default value. To fix this, explicitly mark gpt_api_key as a
required field without a default and add validation to ensure it is not an empty
string. This will enforce that the API key must be provided and cannot be empty.
app/models/fraud_request.py
Outdated
| class FraudRequest(BaseModel): | ||
| messageContent: str | ||
| keywords: List[str] | ||
| additionalDescription: str | ||
| imageContent: str No newline at end of file |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
π οΈ Refactor suggestion
νλ κ²μ¦ λ° μ νμ νλ κ³ λ €κ° νμν©λλ€.
νμ¬ λͺ¨λ νλκ° νμλ‘ μ€μ λμ΄ μμ΄ API μ¬μ©μ±μ΄ μ νλ μ μμ΅λλ€. νΉν additionalDescriptionκ³Ό imageContentλ μ νμ μΌλ‘ λ§λλ κ²μ κ³ λ €ν΄λ³΄μΈμ.
from pydantic import BaseModel
from typing import List
+from typing import Optional
class FraudRequest(BaseModel):
messageContent: str
keywords: List[str]
- additionalDescription: str
- imageContent: str
+ additionalDescription: Optional[str] = None
+ imageContent: Optional[str] = Noneπ Committable suggestion
βΌοΈ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| class FraudRequest(BaseModel): | |
| messageContent: str | |
| keywords: List[str] | |
| additionalDescription: str | |
| imageContent: str | |
| from pydantic import BaseModel | |
| from typing import List | |
| from typing import Optional | |
| class FraudRequest(BaseModel): | |
| messageContent: str | |
| keywords: List[str] | |
| additionalDescription: Optional[str] = None | |
| imageContent: Optional[str] = None |
π€ Prompt for AI Agents
In app/models/fraud_request.py around lines 4 to 8, all fields in the
FraudRequest model are currently required, which limits API usability. Modify
the model to make additionalDescription and imageContent optional by using
typing.Optional and providing default values such as None. Also, consider adding
validation to ensure required fields are properly checked while allowing these
two fields to be omitted.
app/models/fraud_response.py
Outdated
| class FraudResponse(BaseModel): | ||
| estimatedFraudType: str # λΆλ₯λ μ¬κΈ° μ ν | ||
| keywords: List[str] # μ£Όμ μν ν€μλ (μ΅λ 3κ°) | ||
| explanation: str # ν΄λΉ μ νμΌλ‘ νλ¨ν μ΄μ | ||
| score: float # μνλ(0~100) No newline at end of file |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
π οΈ Refactor suggestion
νλ κ²μ¦ λ‘μ§ κ°ν νμ
μ£Όμ νλλ€μ λν κ²μ¦μ΄ λΆμ‘±ν©λλ€. νΉν scoreλ 0-100 λ²μμ¬μΌ νκ³ , keywordsλ μ΅λ 3κ°λ‘ μ νλμ΄μΌ ν©λλ€.
λ€μκ³Ό κ°μ΄ κ²μ¦μ μΆκ°ν μ μμ΅λλ€:
class FraudResponse(BaseModel):
estimatedFraudType: str # λΆλ₯λ μ¬κΈ° μ ν
- keywords: List[str] # μ£Όμ μν ν€μλ (μ΅λ 3κ°)
+ keywords: List[str] = Field(..., min_items=1, max_items=3, description="μ£Όμ μν ν€μλ (μ΅λ 3κ°)")
explanation: str # ν΄λΉ μ νμΌλ‘ νλ¨ν μ΄μ
- score: float # μνλ(0~100)
+ score: float = Field(..., ge=0, le=100, description="μνλ(0~100)")
+
+ @validator('estimatedFraudType')
+ def validate_fraud_type(cls, v):
+ if not v.strip():
+ raise ValueError('μ¬κΈ° μ νμ νμμ
λλ€')
+ return v.strip()
+
+ @validator('explanation')
+ def validate_explanation(cls, v):
+ if not v.strip():
+ raise ValueError('μ€λͺ
μ νμμ
λλ€')
+ return v.strip()π Committable suggestion
βΌοΈ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| class FraudResponse(BaseModel): | |
| estimatedFraudType: str # λΆλ₯λ μ¬κΈ° μ ν | |
| keywords: List[str] # μ£Όμ μν ν€μλ (μ΅λ 3κ°) | |
| explanation: str # ν΄λΉ μ νμΌλ‘ νλ¨ν μ΄μ | |
| score: float # μνλ(0~100) | |
| class FraudResponse(BaseModel): | |
| estimatedFraudType: str # λΆλ₯λ μ¬κΈ° μ ν | |
| keywords: List[str] = Field( | |
| ..., | |
| min_items=1, | |
| max_items=3, | |
| description="μ£Όμ μν ν€μλ (μ΅λ 3κ°)" | |
| ) | |
| explanation: str # ν΄λΉ μ νμΌλ‘ νλ¨ν μ΄μ | |
| score: float = Field( | |
| ..., | |
| ge=0, | |
| le=100, | |
| description="μνλ(0~100)" | |
| ) | |
| @validator('estimatedFraudType') | |
| def validate_fraud_type(cls, v): | |
| if not v.strip(): | |
| raise ValueError('μ¬κΈ° μ νμ νμμ λλ€') | |
| return v.strip() | |
| @validator('explanation') | |
| def validate_explanation(cls, v): | |
| if not v.strip(): | |
| raise ValueError('μ€λͺ μ νμμ λλ€') | |
| return v.strip() |
π€ Prompt for AI Agents
In app/models/fraud_response.py around lines 4 to 8, the FraudResponse model
lacks validation for key fields. Add validation to ensure the score field is
constrained between 0 and 100, and limit the keywords list to a maximum of 3
items. Use Pydantic validators or field constraints to enforce these rules,
raising appropriate errors if the conditions are not met.
| try: | ||
| response = client.responses.create( | ||
| model="gpt-4o-mini", | ||
| input = messages, | ||
| temperature = 0.5, # μμ±λ ν μ€νΈμ 무μμμ±μ κ²°μ | ||
| max_output_tokens = 200 | ||
| ) | ||
| print(response) | ||
|
|
||
| except OpenAIError as e: | ||
| raise RuntimeError(f"GPT API νΈμΆ μ€ν¨: {e}") | ||
| except Exception as e: | ||
| return f"μλ² μ€λ₯ λ°μ: {e}" | ||
|
|
||
| return response.output_text.strip() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
OpenAI API νΈμΆ λ°©μ λ° μμΈ μ²λ¦¬ μμ νμ
νμ¬ μ½λμμ μ¬λ¬ κ°μ§ μ€μν λ¬Έμ κ° μμ΅λλ€:
client.responses.createλ μ¬λ°λ₯Έ OpenAI API λ©μλκ° μλλλ€- μλ΅ κ°μ²΄μ
output_textμμ±λ μ‘΄μ¬νμ§ μμ΅λλ€ - μμΈ μ²λ¦¬μμ μλ³Έ μμΈ μ λ³΄κ° μμ€λ©λλ€
- νλ‘λμ μ½λμ λλ²κΉ μ© printλ¬Έμ΄ λ¨μμμ΅λλ€
λ€μκ³Ό κ°μ΄ μμ ν΄μΌ ν©λλ€:
+import logging
+
+logger = logging.getLogger(__name__)
+
async def call_gpt(request: FraudRequest):
messages = get_fraud_detection_prompt(
message_content = request.messageContent,
additional_description = request.additionalDescription,
keywords = request.keywords,
image_content = request.imageContent
)
try:
- response = client.responses.create(
+ response = await client.chat.completions.create(
model="gpt-4o-mini",
- input = messages,
+ messages=messages,
temperature = 0.5, # μμ±λ ν
μ€νΈμ 무μμμ±μ κ²°μ
- max_output_tokens = 200
+ max_tokens=200
)
- print(response)
+ logger.info(f"GPT API νΈμΆ μ±κ³΅, μ¬μ© ν ν°: {response.usage}")
except OpenAIError as e:
- raise RuntimeError(f"GPT API νΈμΆ μ€ν¨: {e}")
+ logger.error(f"GPT API νΈμΆ μ€ν¨: {e}", exc_info=True)
+ raise RuntimeError(f"GPT API νΈμΆ μ€ν¨: {e}") from e
except Exception as e:
- return f"μλ² μ€λ₯ λ°μ: {e}"
+ logger.error(f"μμμΉ λͺ»ν μλ² μ€λ₯: {e}", exc_info=True)
+ raise RuntimeError(f"μλ² μ€λ₯ λ°μ: {e}") from e
- return response.output_text.strip()
+ return response.choices[0].message.content.strip()π Committable suggestion
βΌοΈ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| try: | |
| response = client.responses.create( | |
| model="gpt-4o-mini", | |
| input = messages, | |
| temperature = 0.5, # μμ±λ ν μ€νΈμ 무μμμ±μ κ²°μ | |
| max_output_tokens = 200 | |
| ) | |
| print(response) | |
| except OpenAIError as e: | |
| raise RuntimeError(f"GPT API νΈμΆ μ€ν¨: {e}") | |
| except Exception as e: | |
| return f"μλ² μ€λ₯ λ°μ: {e}" | |
| return response.output_text.strip() | |
| import logging | |
| logger = logging.getLogger(__name__) | |
| async def call_gpt(request: FraudRequest): | |
| messages = get_fraud_detection_prompt( | |
| message_content=request.messageContent, | |
| additional_description=request.additionalDescription, | |
| keywords=request.keywords, | |
| image_content=request.imageContent | |
| ) | |
| try: | |
| response = await client.chat.completions.create( | |
| model="gpt-4o-mini", | |
| messages=messages, | |
| temperature=0.5, # μμ±λ ν μ€νΈμ 무μμμ±μ κ²°μ | |
| max_tokens=200 | |
| ) | |
| logger.info(f"GPT API νΈμΆ μ±κ³΅, μ¬μ© ν ν°: {response.usage}") | |
| except OpenAIError as e: | |
| logger.error(f"GPT API νΈμΆ μ€ν¨: {e}", exc_info=True) | |
| raise RuntimeError(f"GPT API νΈμΆ μ€ν¨: {e}") from e | |
| except Exception as e: | |
| logger.error(f"μμμΉ λͺ»ν μλ² μ€λ₯: {e}", exc_info=True) | |
| raise RuntimeError(f"μλ² μ€λ₯ λ°μ: {e}") from e | |
| return response.choices[0].message.content.strip() |
π§° Tools
πͺ Ruff (0.12.2)
28-28: Within an except clause, raise exceptions with raise ... from err or raise ... from None to distinguish them from errors in exception handling
(B904)
π€ Prompt for AI Agents
In app/services/gpt_service.py around lines 18 to 32, the code incorrectly uses
client.responses.create which is not a valid OpenAI API method, and attempts to
access a non-existent output_text attribute on the response. Additionally, the
exception handling loses original error details and there is a leftover print
statement. To fix this, replace client.responses.create with the correct method
for chat completions (e.g., client.chat.completions.create), access the
generated text from the proper response field (like
response.choices[0].message.content), remove the print statement, and update
exception handling to preserve and propagate original error information
properly.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 2
π Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
π Files selected for processing (1)
requirements.txt(1 hunks)
π Additional comments (1)
requirements.txt (1)
13-13: μ΄μ μμ: ꡬλ²μ OpenAI API νΈμΆ ν¨ν΄ λ―Έλ°κ²¬
μ μ κ²μ κ²°κ³Όopenai.ChatCompletion.createλλopenai.Completion.createνΈμΆμ΄ λͺ¨λ λ°κ²¬λμ§ μμμ΅λλ€. λ°λΌμ 1.x API λ§μ΄κ·Έλ μ΄μ μ΄ μλ£λ κ²μΌλ‘ νμΈλ©λλ€.
|
μκ³ νμ ¨μ΅λλ€.!! μ΅λν ν ν° μ κ² μ°λ λ°©μμΌλ‘ μ νμ΅μν€λ λ°©λ²μ μ°Ύμλ΄μΌν κ±°κ°λ€μ΅.. |
π» Related Issue
π Work Description
app.prompts.data.fraud_examplesμμ μ νλ³ μμ λ°μ΄ν°λ₯Ό κ΄λ¦¬νλ©°,app.prompts.fraud_promptsμμ ν둬ννΈμ μ§μμ¬νκ³Ό μμλ°μ΄ν°λ₯Ό μ£Όμ νμμ΅λλ€.ππ»ββοΈ To Reviewer
β Next
Summary by CodeRabbit
μ κ· κΈ°λ₯
νκ²½ μ€μ
λ²κ·Έ μμ λ° κΈ°ν