ریفکتور کد با هوش مصنوعی؛ آموزش بازآرایی Legacy Code و ساخت AI Refactoring Assistant

در این آموزش یاد می‌گیرید Legacy Code را بدون تغییر ناخواسته رفتار با AI ریفکتور کنید و ابزاری بسازید که کد و تست‌ها را تحلیل، برنامه مرحله‌ای و Patch پیشنهادی تولید و نتیجه را ارزیابی می‌کند.

Share
ریفکتور کد با هوش مصنوعی؛ آموزش بازآرایی Legacy Code و ساخت AI Refactoring Assistant

رفکتور کد با هوش مصنوعی؛ بازآرایی ایمن Legacy Code

رفکتور یا Refactoring به معنی تغییر ساختار داخلی کد بدون تغییر رفتار قابل مشاهده آن است.

هدف رفکتور معمولاً یکی از این موارد است:

  • خواناترشدن کد
  • کاهش تکرار
  • کوچک‌کردن تابع‌های پیچیده
  • جداکردن مسئولیت‌ها
  • بهبود نام‌گذاری
  • ساده‌کردن شرط‌ها
  • کاهش وابستگی میان ماژول‌ها
  • آماده‌کردن کد برای توسعه قابلیت جدید
  • ساده‌ترکردن تست
  • حذف مسیرهای منسوخ

هوش مصنوعی می‌تواند یک تابع ۳۰۰ خطی را در چند ثانیه به چند تابع کوچک‌تر تبدیل کند. اما سؤال اصلی این نیست که آیا کد جدید زیباتر است؛ سؤال اصلی این است:

آیا رفتار سیستم پس از رفکتور دقیقاً حفظ شده است؟

اگر مدل در حین بازآرایی یکی از این موارد را تغییر دهد، دیگر فقط Refactor انجام نداده‌ایم:

  • ترتیب Validation
  • نوع Exception
  • متن خطا
  • گردکردن مبلغ
  • رفتار ورودی خالی
  • ترتیب خروجی
  • مقدار پیش‌فرض
  • Mutation ورودی
  • تعداد فراخوانی Dependency
  • Contract عمومی تابع
  • اثر جانبی ثبت‌شده

در این مقاله یک روش عملی برای Refactoring با AI پیاده می‌کنیم:

  1. رفتار فعلی و رفتار مورد انتظار را جدا می‌کنیم.
  2. Code Smellها را شناسایی می‌کنیم.
  3. Characterization Test می‌سازیم.
  4. برنامه رفکتور مرحله‌ای تولید می‌کنیم.
  5. هر مرحله را با Patch کوچک انجام می‌دهیم.
  6. تست‌ها و ابزارهای قطعی را اجرا می‌کنیم.
  7. Diff نهایی را از نظر تغییر رفتار بررسی می‌کنیم.
  8. یک AI Refactoring Assistant با پایتون و API درواره می‌سازیم.

تفاوت Refactor، Rewrite و Feature Change

این سه مفهوم نباید در یک Pull Request با یکدیگر مخلوط شوند.

Refactor

ساختار داخلی تغییر می‌کند، اما رفتار عمومی حفظ می‌شود.

مثال:

def calculate_total(items):
    subtotal = sum(
        item.price * item.quantity
        for item in items
    )
    return subtotal

به:

def calculate_subtotal(items):
    return sum(
        item.price * item.quantity
        for item in items
    )


def calculate_total(items):
    return calculate_subtotal(items)

Rewrite

بخش مهمی از پیاده‌سازی از ابتدا نوشته می‌شود. احتمال تغییر رفتار و ایجاد خطای جدید بیشتر است.

Feature Change

قابلیت یا رفتار جدیدی اضافه می‌شود:

از این پس برای خریدهای بالاتر از مبلغ مشخص تخفیف اعمال شود.

این تغییر Refactor نیست، حتی اگر کد هم‌زمان تمیزتر شود.

هوش مصنوعی در رفکتور چه کارهایی انجام می‌دهد؟

شناسایی Code Smell

  • تابع طولانی
  • شرط‌های تو در تو
  • مسئولیت‌های متعدد
  • تکرار منطق
  • پارامترهای زیاد
  • Boolean Flagهای متعدد
  • Mutation پنهان
  • Dependency مستقیم
  • نام‌گذاری مبهم
  • Magic Number
  • Comment توضیح‌دهنده کد پیچیده
  • Data Clump
  • Primitive Obsession

پیشنهاد مرزهای استخراج تابع

مدل می‌تواند بخش‌هایی را که مسئولیت مستقلی دارند پیشنهاد کند:

  • Validation
  • Calculation
  • Transformation
  • Persistence
  • Formatting
  • Notification

ساخت برنامه مرحله‌ای

به‌جای تولید یک Patch بزرگ، مراحل کوچک پیشنهاد می‌شود:

  1. افزودن تست رفتار فعلی
  2. استخراج Constantها
  3. استخراج Validation
  4. استخراج محاسبه
  5. حذف تکرار
  6. بهبود نام‌ها
  7. اجرای کامل تست‌ها

تولید Characterization Test

برای کد قدیمی که Specification کامل ندارد، AI می‌تواند به ثبت رفتار فعلی کمک کند.

پیشنهاد Patch کوچک

هر Patch باید فقط یک هدف ساختاری داشته باشد.

توضیح اثر Refactor

مدل می‌تواند قبل و بعد را مقایسه و تغییرهای احتمالی Contract را مشخص کند.

مهم‌ترین ریسک: زیباترشدن کد همراه با تغییر رفتار

کد قدیمی:

if customer_type == "vip":
    discount = subtotal * Decimal("0.10")
elif subtotal > Decimal("10000000"):
    discount = subtotal * Decimal("0.05")

مدل ممکن است این منطق را به دو شرط مستقل تبدیل کند:

if customer_type == "vip":
    discount += subtotal * Decimal("0.10")

if subtotal > Decimal("10000000"):
    discount += subtotal * Decimal("0.05")

کد دوم خوانا به نظر می‌رسد، اما رفتار تغییر کرده است. مشتری VIP با خرید بزرگ اکنون هر دو تخفیف را دریافت می‌کند.

برای جلوگیری از چنین خطاهایی، قبل از رفکتور باید رفتارهای مرزی با Test ثبت شوند.

Characterization Test چیست؟

Characterization Test رفتار فعلی کد را ثبت می‌کند، حتی اگر هنوز ندانیم آن رفتار از نظر محصول کاملاً صحیح است یا خیر.

این تست پاسخ می‌دهد:

کد فعلی برای این ورودی چه خروجی یا اثر جانبی دارد؟

نکته مهم: Characterization Test با Acceptance Test یکسان نیست.

  • Characterization Test رفتار فعلی را ثبت می‌کند.
  • Acceptance Test رفتار مورد انتظار محصول را تعریف می‌کند.

اگر میان این دو اختلاف وجود دارد، باید ابتدا درباره رفتار صحیح تصمیم گرفته شود. Refactor نباید مخفیانه این اختلاف را حل کند.

پرامپت آماده برای تحلیل رفکتور

تو یک مهندس ارشد نرم‌افزار هستی.

کد زیر را برای Refactoring تحلیل کن، اما هنوز Patch نساز.

خروجی:
1. مسئولیت‌های فعلی
2. API عمومی که باید حفظ شود
3. اثرهای جانبی
4. Code Smellهای قابل اثبات
5. رفتارهای مرزی
6. تست‌های موجود
7. تست‌های لازم پیش از Refactor
8. برنامه Refactor مرحله‌ای
9. معیار پایان هر مرحله
10. ریسک تغییر رفتار

قواعد:
- Feature جدید پیشنهاد نده.
- تغییر رفتار را Refactor معرفی نکن.
- بازنویسی کامل پیشنهاد نده.
- هر مرحله باید کوچک و مستقل باشد.
- ترتیب Validation و نوع Exception را حفظ کن.
- ابتدا تست و سپس تغییر ساختار پیشنهاد بده.

Specification:
[SPECIFICATION]

Source:
[SOURCE CODE]

Existing tests:
[TESTS]

پروژه عملی: رفکتور سرویس قیمت‌گذاری سفارش

کدی داریم که چند مسئولیت را در یک تابع انجام می‌دهد:

  • Validation
  • محاسبه Subtotal
  • اعمال تخفیف
  • محاسبه مالیات
  • Formatting خروجی

ایجاد پروژه

mkdir ai-refactoring-assistant
cd ai-refactoring-assistant

python -m venv .venv

فعال‌سازی در Linux و macOS:

source .venv/bin/activate

فعال‌سازی در Windows:

.venv\Scripts\Activate.ps1

نصب وابستگی‌ها:

pip install \
  openai \
  python-dotenv \
  pydantic \
  pytest \
  pytest-cov

ساخت پوشه‌ها:

mkdir app tests refactor_assistant plans output specifications

فایل‌های زیر را ایجاد کنید:

app/__init__.py
app/pricing.py
tests/__init__.py
tests/test_pricing.py
refactor_assistant/__init__.py
refactor_assistant/schemas.py
refactor_assistant/collector.py
refactor_assistant/planner.py
refactor_assistant/patch_generator.py
refactor_assistant/renderer.py
plan_refactor.py
generate_refactor_patch.py

کد Legacy نمونه

فایل app/pricing.py:

from decimal import (
    Decimal,
    ROUND_HALF_UP,
)


def calculate_order_price(
    items,
    customer_type,
    tax_rate,
):
    if not isinstance(items, list):
        raise TypeError(
            "items must be a list"
        )

    if customer_type not in {
        "regular",
        "vip",
    }:
        raise ValueError(
            "unsupported customer type"
        )

    if tax_rate < 0 or tax_rate > 1:
        raise ValueError(
            "tax rate must be between 0 and 1"
        )

    subtotal = Decimal("0")

    for item in items:
        if "price" not in item:
            raise ValueError(
                "item price is required"
            )

        if "quantity" not in item:
            raise ValueError(
                "item quantity is required"
            )

        price = Decimal(
            str(item["price"])
        )

        quantity = int(
            item["quantity"]
        )

        if price < 0:
            raise ValueError(
                "price cannot be negative"
            )

        if quantity < 0:
            raise ValueError(
                "quantity cannot be negative"
            )

        subtotal += price * quantity

    subtotal = subtotal.quantize(
        Decimal("0.01"),
        rounding=ROUND_HALF_UP,
    )

    discount = Decimal("0")

    if customer_type == "vip":
        discount = (
            subtotal * Decimal("0.10")
        ).quantize(
            Decimal("0.01"),
            rounding=ROUND_HALF_UP,
        )
    elif subtotal > Decimal("10000000"):
        discount = (
            subtotal * Decimal("0.05")
        ).quantize(
            Decimal("0.01"),
            rounding=ROUND_HALF_UP,
        )

    taxable_amount = (
        subtotal - discount
    ).quantize(
        Decimal("0.01"),
        rounding=ROUND_HALF_UP,
    )

    tax = (
        taxable_amount
        * Decimal(str(tax_rate))
    ).quantize(
        Decimal("0.01"),
        rounding=ROUND_HALF_UP,
    )

    total = (
        taxable_amount + tax
    ).quantize(
        Decimal("0.01"),
        rounding=ROUND_HALF_UP,
    )

    return {
        "subtotal": str(subtotal),
        "discount": str(discount),
        "taxable_amount": str(
            taxable_amount
        ),
        "tax": str(tax),
        "total": str(total),
    }

کد کار می‌کند، اما مسئولیت‌های مختلف در یک تابع قرار گرفته‌اند.

Specification رفتار

فایل specifications/pricing.md:

# Order pricing specification

## Public API

تابع calculate_order_price سه پارامتر دریافت می‌کند:

- items
- customer_type
- tax_rate

خروجی یک Dictionary شامل رشته‌های عددی با دو رقم اعشار است.

## Validation

- items باید list باشد.
- customer_type فقط regular یا vip است.
- tax_rate باید بین صفر و یک باشد.
- هر Item باید price و quantity داشته باشد.
- price و quantity نباید منفی باشند.
- مقدار quantity به int تبدیل می‌شود.
- Validationها باید قبل از محاسبه انجام شوند.

## Discount

- مشتری vip دقیقاً 10 درصد تخفیف می‌گیرد.
- مشتری regular فقط وقتی subtotal بزرگ‌تر از 10000000 است، 5 درصد تخفیف می‌گیرد.
- اگر subtotal دقیقاً 10000000 باشد، تخفیف regular اعمال نمی‌شود.
- تخفیف‌ها با یکدیگر جمع نمی‌شوند.

## Tax

- مالیات پس از تخفیف محاسبه می‌شود.
- tax_rate صفر و یک معتبرند.

## Money

- تمام مبالغ با ROUND_HALF_UP تا دو رقم اعشار گرد می‌شوند.

تست رفتار فعلی و مورد انتظار

فایل tests/test_pricing.py:

from decimal import Decimal

import pytest

from app.pricing import (
    calculate_order_price,
)


def test_empty_order_returns_zero_values():
    result = calculate_order_price(
        [],
        "regular",
        Decimal("0.10"),
    )

    assert result == {
        "subtotal": "0.00",
        "discount": "0",
        "taxable_amount": "0.00",
        "tax": "0.00",
        "total": "0.00",
    }


def test_vip_discount_is_applied_before_tax():
    result = calculate_order_price(
        [
            {
                "price": "100.00",
                "quantity": 1,
            }
        ],
        "vip",
        Decimal("0.20"),
    )

    assert result == {
        "subtotal": "100.00",
        "discount": "10.00",
        "taxable_amount": "90.00",
        "tax": "18.00",
        "total": "108.00",
    }


def test_regular_discount_above_threshold():
    result = calculate_order_price(
        [
            {
                "price": "10000001",
                "quantity": 1,
            }
        ],
        "regular",
        Decimal("0"),
    )

    assert result["discount"] == "500000.05"
    assert result["total"] == "9500000.95"


def test_regular_has_no_discount_at_threshold():
    result = calculate_order_price(
        [
            {
                "price": "10000000",
                "quantity": 1,
            }
        ],
        "regular",
        Decimal("0"),
    )

    assert result["discount"] == "0"
    assert result["total"] == "10000000.00"


def test_vip_does_not_stack_discounts():
    result = calculate_order_price(
        [
            {
                "price": "20000000",
                "quantity": 1,
            }
        ],
        "vip",
        Decimal("0"),
    )

    assert result["discount"] == "2000000.00"


@pytest.mark.parametrize(
    "customer_type",
    [
        "",
        "gold",
        None,
    ],
)
def test_rejects_unknown_customer_type(
    customer_type,
):
    with pytest.raises(
        ValueError,
        match="unsupported customer type",
    ):
        calculate_order_price(
            [],
            customer_type,
            Decimal("0"),
        )


@pytest.mark.parametrize(
    "tax_rate",
    [
        Decimal("-0.01"),
        Decimal("1.01"),
    ],
)
def test_rejects_invalid_tax_rate(
    tax_rate,
):
    with pytest.raises(
        ValueError,
        match=(
            "tax rate must be "
            "between 0 and 1"
        ),
    ):
        calculate_order_price(
            [],
            "regular",
            tax_rate,
        )

نکته مهم: خروجی تخفیف سبد خالی "0" است، نه "0.00". این رفتار فعلی شاید ایده‌آل نباشد، اما تغییر آن یک تصمیم Contract است و نباید مخفیانه در Refactor انجام شود.

اجرای تست و Coverage

pytest -q

سپس:

pytest \
  --cov=app \
  --cov-branch \
  --cov-report=term-missing

Coverage بالا به‌تنهایی کافی نیست. رفتارهای مهم مرزی باید با Assertion صریح ثبت شوند.

چه تست‌هایی پیش از Refactor کم هستند؟

  • items غیر از List
  • نبود price
  • نبود quantity
  • قیمت منفی
  • تعداد منفی
  • نرخ مالیات دقیقاً صفر
  • نرخ مالیات دقیقاً یک
  • گردکردن ROUND_HALF_UP
  • تبدیل Quantity رشته‌ای به int
  • تغییرنکردن فهرست ورودی
  • حفظ متن Exception
  • ترتیب Validation در ورودی دارای چند خطا

AI Refactoring Assistant باید ابتدا این Gapها را گزارش کند.

تعریف Schema برنامه رفکتور

فایل refactor_assistant/schemas.py:

from typing import Literal

from pydantic import BaseModel, Field


class BehaviorContract(BaseModel):
    name: str
    description: str
    source: Literal[
        "specification",
        "test",
        "source_code",
    ]
    must_preserve: bool


class CodeSmell(BaseModel):
    title: str
    evidence: str
    impact: str
    confidence: float = Field(
        ge=0,
        le=1,
    )


class MissingTest(BaseModel):
    title: str
    behavior: str
    reason: str
    priority: Literal[
        "high",
        "medium",
        "low",
    ]


class RefactorStep(BaseModel):
    order: int
    title: str
    goal: str
    files: list[str]
    transformations: list[str]
    preserved_behaviors: list[str]
    tests_to_run: list[str]
    completion_criteria: list[str]
    risk: Literal[
        "high",
        "medium",
        "low",
    ]


class RefactorPlan(BaseModel):
    target: str
    summary: str
    public_api: list[str]
    side_effects: list[str]
    behavior_contracts: list[
        BehaviorContract
    ]
    code_smells: list[CodeSmell]
    missing_tests: list[MissingTest]
    steps: list[RefactorStep]
    out_of_scope: list[str]
    unresolved_questions: list[str]

جمع‌آوری Context

فایل refactor_assistant/collector.py:

import subprocess
import sys
from pathlib import Path


def read_file(
    file_path: Path,
    max_chars: int = 50_000,
) -> str:
    content = file_path.read_text(
        encoding="utf-8"
    )

    if len(content) > max_chars:
        return (
            content[:max_chars]
            + "\n\n[CONTENT TRUNCATED]"
        )

    return content


def run_tests(
    timeout_seconds: int = 60,
) -> dict:
    command = [
        sys.executable,
        "-m",
        "pytest",
        "-q",
    ]

    try:
        result = subprocess.run(
            command,
            capture_output=True,
            text=True,
            timeout=timeout_seconds,
            check=False,
        )
    except subprocess.TimeoutExpired:
        return {
            "command": command,
            "return_code": None,
            "stdout": "",
            "stderr": "",
            "timed_out": True,
        }

    return {
        "command": command,
        "return_code": result.returncode,
        "stdout": result.stdout[-20_000:],
        "stderr": result.stderr[-10_000:],
        "timed_out": False,
    }


def collect_refactor_context() -> dict:
    return {
        "target_file": "app/pricing.py",
        "source": read_file(
            Path("app/pricing.py")
        ),
        "specification": read_file(
            Path(
                "specifications/pricing.md"
            )
        ),
        "tests": read_file(
            Path("tests/test_pricing.py")
        ),
        "test_run": run_tests(),
        "constraints": [
            "Public function signature must not change.",
            "Returned dictionary keys must not change.",
            "String formatting must remain unchanged.",
            "Exception types and messages must remain unchanged.",
            "No new third-party dependency is allowed.",
            "This task is refactoring, not feature development.",
        ],
    }

تولید برنامه رفکتور با API درواره

فایل refactor_assistant/planner.py:

import json
import os

from dotenv import load_dotenv
from openai import OpenAI
from pydantic import ValidationError

from refactor_assistant.schemas import (
    RefactorPlan,
)


load_dotenv()

api_key = os.getenv("DARVAREH_API_KEY")
model = os.getenv("DARVAREH_MODEL")

if not api_key:
    raise RuntimeError(
        "DARVAREH_API_KEY is not configured."
    )

if not model:
    raise RuntimeError(
        "DARVAREH_MODEL is not configured."
    )

client = OpenAI(
    api_key=api_key,
    base_url="https://api.darvareh.ir/v1",
)


SYSTEM_PROMPT = """
تو یک مهندس ارشد نرم‌افزار و متخصص Refactoring هستی.

در این مرحله فقط برنامه Refactor تولید کن و Patch نساز.

اولویت:
1. حفظ رفتار عمومی
2. ساخت تست‌های لازم
3. مراحل کوچک و قابل بازگشت
4. کاهش پیچیدگی
5. بهبود خوانایی

قواعد:
- Feature جدید پیشنهاد نده.
- تغییر رفتار را Refactor معرفی نکن.
- بازنویسی کامل پیشنهاد نده.
- API عمومی، نوع Exception، متن خطا و قالب خروجی را حفظ کن.
- رفتار Source Code را با Specification اشتباه نگیر.
- اختلاف میان Source، Test و Specification را گزارش کن.
- هر مرحله فقط یک هدف اصلی داشته باشد.
- قبل از تغییر پرریسک، Test لازم را پیشنهاد کن.
- خروجی فقط JSON معتبر باشد.
"""


OUTPUT_TEMPLATE = {
    "target": "app/pricing.py",
    "summary": "string",
    "public_api": [
        "calculate_order_price"
    ],
    "side_effects": [],
    "behavior_contracts": [
        {
            "name": "string",
            "description": "string",
            "source": "specification",
            "must_preserve": True,
        }
    ],
    "code_smells": [
        {
            "title": "Long Function",
            "evidence": "string",
            "impact": "string",
            "confidence": 0.95,
        }
    ],
    "missing_tests": [
        {
            "title": "string",
            "behavior": "string",
            "reason": "string",
            "priority": "high",
        }
    ],
    "steps": [
        {
            "order": 1,
            "title": "string",
            "goal": "string",
            "files": [
                "app/pricing.py"
            ],
            "transformations": [
                "string"
            ],
            "preserved_behaviors": [
                "string"
            ],
            "tests_to_run": [
                "pytest -q"
            ],
            "completion_criteria": [
                "string"
            ],
            "risk": "low",
        }
    ],
    "out_of_scope": [],
    "unresolved_questions": [],
}


def generate_refactor_plan(
    context: dict,
) -> RefactorPlan:
    prompt = (
        "Context پروژه:\n\n"
        + json.dumps(
            context,
            ensure_ascii=False,
            indent=2,
        )
        + "\n\nقالب خروجی:\n"
        + json.dumps(
            OUTPUT_TEMPLATE,
            ensure_ascii=False,
            indent=2,
        )
    )

    response = client.chat.completions.create(
        model=model,
        temperature=0.1,
        messages=[
            {
                "role": "system",
                "content": SYSTEM_PROMPT,
            },
            {
                "role": "user",
                "content": prompt,
            },
        ],
    )

    raw_output = (
        response.choices[0]
        .message.content
    )

    if not raw_output:
        raise RuntimeError(
            "The model returned an empty plan."
        )

    try:
        parsed = json.loads(raw_output)
    except json.JSONDecodeError as error:
        raise RuntimeError(
            f"Invalid JSON from model: "
            f"{error}"
        ) from error

    try:
        return RefactorPlan.model_validate(
            parsed
        )
    except ValidationError as error:
        raise RuntimeError(
            f"Refactor plan validation "
            f"failed: {error}"
        ) from error

اسکریپت ساخت Plan

فایل plan_refactor.py:

from pathlib import Path

from refactor_assistant.collector import (
    collect_refactor_context,
)
from refactor_assistant.planner import (
    generate_refactor_plan,
)


def main():
    context = collect_refactor_context()

    if (
        context["test_run"]["return_code"]
        != 0
    ):
        raise RuntimeError(
            "Existing tests must pass before "
            "starting refactoring."
        )

    plan = generate_refactor_plan(
        context
    )

    output_path = Path(
        "plans/refactor_plan.json"
    )

    output_path.parent.mkdir(
        parents=True,
        exist_ok=True,
    )

    output_path.write_text(
        plan.model_dump_json(indent=2),
        encoding="utf-8",
    )

    print(plan.model_dump_json(indent=2))
    print(f"\nPlan saved to {output_path}")


if __name__ == "__main__":
    main()

فایل .env:

DARVAREH_API_KEY=YOUR_API_KEY
DARVAREH_MODEL=MODEL_ID_DARVAREH

اجرا:

python plan_refactor.py

برای دریافت کلید API در درواره ثبت‌نام کنید. Model ID را از صفحه مدل‌های درواره انتخاب کنید.

برنامه Refactor مناسب برای مثال ما

یک Plan منطقی:

  1. تکمیل تست‌های Validation و Rounding
  2. استخراج Constant مربوط به دقت پول
  3. استخراج تابع round_money
  4. استخراج Validation پارامترهای اصلی
  5. استخراج Parse و Validation اقلام
  6. استخراج محاسبه Subtotal
  7. استخراج محاسبه Discount
  8. استخراج Tax
  9. حفظ تابع عمومی به‌عنوان Orchestrator
  10. اجرای Test Suite بعد از هر مرحله

نباید در یک مرحله تمام تابع بازنویسی شود.

اضافه‌کردن تست‌های کمبود

def test_rejects_non_list_items():
    with pytest.raises(
        TypeError,
        match="items must be a list",
    ):
        calculate_order_price(
            (),
            "regular",
            Decimal("0"),
        )


def test_requires_item_price():
    with pytest.raises(
        ValueError,
        match="item price is required",
    ):
        calculate_order_price(
            [
                {
                    "quantity": 1,
                }
            ],
            "regular",
            Decimal("0"),
        )


def test_requires_item_quantity():
    with pytest.raises(
        ValueError,
        match="item quantity is required",
    ):
        calculate_order_price(
            [
                {
                    "price": "10",
                }
            ],
            "regular",
            Decimal("0"),
        )


def test_rounds_money_half_up():
    result = calculate_order_price(
        [
            {
                "price": "1.005",
                "quantity": 1,
            }
        ],
        "regular",
        Decimal("0"),
    )

    assert result["subtotal"] == "1.01"

بعد از اضافه‌کردن تست‌ها:

pytest -q

تولید Patch برای فقط یک مرحله

نباید کل Plan را یک‌باره به مدل بدهیم و درخواست Patch کامل کنیم. یک Step انتخاب کنید.

فایل refactor_assistant/patch_generator.py:

import json
from pathlib import Path

from refactor_assistant.planner import (
    client,
    model,
)
from refactor_assistant.schemas import (
    RefactorPlan,
)


PATCH_SYSTEM_PROMPT = """
تو فقط یک مرحله تأییدشده Refactoring را اجرا می‌کنی.

قواعد:
- خروجی فقط Unified Diff باشد.
- Markdown و توضیح خارج از Diff تولید نکن.
- رفتار عمومی را تغییر نده.
- امضای تابع عمومی را تغییر نده.
- Type و متن Exceptionها را حفظ کن.
- قالب Dictionary خروجی را حفظ کن.
- Dependency جدید اضافه نکن.
- فایل خارج از Step را تغییر نده.
- Feature جدید اضافه نکن.
- Testها را حذف یا ضعیف نکن.
- اگر Step بدون تغییر رفتار قابل انجام نیست، Patch تولید نکن.
"""


def generate_patch_for_step(
    step_order: int,
) -> str:
    plan = RefactorPlan.model_validate_json(
        Path(
            "plans/refactor_plan.json"
        ).read_text(encoding="utf-8")
    )

    selected_step = next(
        (
            step
            for step in plan.steps
            if step.order == step_order
        ),
        None,
    )

    if selected_step is None:
        raise ValueError(
            f"Step {step_order} not found."
        )

    files = {}

    for file_name in selected_step.files:
        files[file_name] = Path(
            file_name
        ).read_text(encoding="utf-8")

    tests = Path(
        "tests/test_pricing.py"
    ).read_text(encoding="utf-8")

    prompt = {
        "approved_step": (
            selected_step.model_dump()
        ),
        "behavior_contracts": [
            contract.model_dump()
            for contract in (
                plan.behavior_contracts
            )
            if contract.must_preserve
        ],
        "files": files,
        "tests": tests,
    }

    response = client.chat.completions.create(
        model=model,
        temperature=0,
        messages=[
            {
                "role": "system",
                "content": (
                    PATCH_SYSTEM_PROMPT
                ),
            },
            {
                "role": "user",
                "content": json.dumps(
                    prompt,
                    ensure_ascii=False,
                    indent=2,
                ),
            },
        ],
    )

    patch = (
        response.choices[0]
        .message.content
    )

    if not patch:
        raise RuntimeError(
            "The model returned an "
            "empty patch."
        )

    return patch

ذخیره Patch بدون اعمال خودکار

فایل generate_refactor_patch.py:

import argparse
from pathlib import Path

from refactor_assistant.patch_generator import (
    generate_patch_for_step,
)


def main():
    parser = argparse.ArgumentParser()

    parser.add_argument(
        "--step",
        type=int,
        required=True,
    )

    arguments = parser.parse_args()

    patch = generate_patch_for_step(
        arguments.step
    )

    output_path = Path(
        f"output/refactor-step-"
        f"{arguments.step}.patch"
    )

    output_path.parent.mkdir(
        parents=True,
        exist_ok=True,
    )

    output_path.write_text(
        patch,
        encoding="utf-8",
    )

    print(patch)
    print(f"\nPatch saved to {output_path}")


if __name__ == "__main__":
    main()

اجرا:

python generate_refactor_patch.py --step 2

Patch را بخوانید و سپس اعتبار آن را بررسی کنید:

git apply --check output/refactor-step-2.patch

این دستور فقط بررسی می‌کند Patch قابل اعمال است و آن را اعمال نمی‌کند.

نمونه نتیجه رفکتور

یک نسخه بازآرایی‌شده می‌تواند چنین باشد:

from decimal import (
    Decimal,
    ROUND_HALF_UP,
)


MONEY_PRECISION = Decimal("0.01")
VIP_DISCOUNT_RATE = Decimal("0.10")
REGULAR_DISCOUNT_RATE = Decimal("0.05")
REGULAR_DISCOUNT_THRESHOLD = Decimal(
    "10000000"
)


def round_money(
    value: Decimal,
) -> Decimal:
    return value.quantize(
        MONEY_PRECISION,
        rounding=ROUND_HALF_UP,
    )


def validate_request(
    items,
    customer_type,
    tax_rate,
):
    if not isinstance(items, list):
        raise TypeError(
            "items must be a list"
        )

    if customer_type not in {
        "regular",
        "vip",
    }:
        raise ValueError(
            "unsupported customer type"
        )

    if tax_rate < 0 or tax_rate > 1:
        raise ValueError(
            "tax rate must be between 0 and 1"
        )


def calculate_subtotal(
    items,
) -> Decimal:
    subtotal = Decimal("0")

    for item in items:
        if "price" not in item:
            raise ValueError(
                "item price is required"
            )

        if "quantity" not in item:
            raise ValueError(
                "item quantity is required"
            )

        price = Decimal(
            str(item["price"])
        )
        quantity = int(
            item["quantity"]
        )

        if price < 0:
            raise ValueError(
                "price cannot be negative"
            )

        if quantity < 0:
            raise ValueError(
                "quantity cannot be negative"
            )

        subtotal += price * quantity

    return round_money(subtotal)


def calculate_discount(
    subtotal: Decimal,
    customer_type: str,
) -> Decimal:
    if customer_type == "vip":
        return round_money(
            subtotal * VIP_DISCOUNT_RATE
        )

    if (
        subtotal
        > REGULAR_DISCOUNT_THRESHOLD
    ):
        return round_money(
            subtotal
            * REGULAR_DISCOUNT_RATE
        )

    return Decimal("0")


def calculate_order_price(
    items,
    customer_type,
    tax_rate,
):
    validate_request(
        items,
        customer_type,
        tax_rate,
    )

    subtotal = calculate_subtotal(
        items
    )

    discount = calculate_discount(
        subtotal,
        customer_type,
    )

    taxable_amount = round_money(
        subtotal - discount
    )

    tax = round_money(
        taxable_amount
        * Decimal(str(tax_rate))
    )

    total = round_money(
        taxable_amount + tax
    )

    return {
        "subtotal": str(subtotal),
        "discount": str(discount),
        "taxable_amount": str(
            taxable_amount
        ),
        "tax": str(tax),
        "total": str(total),
    }

رفتار عجیب "discount": "0" عمداً حفظ شده است. اگر محصول تصمیم بگیرد همه مبالغ دو رقم اعشار داشته باشند، آن تغییر باید در یک Feature یا Contract Change جداگانه انجام شود.

آیا استخراج تابع همیشه مفید است؟

خیر. شکستن بیش از حد کد می‌تواند خوانایی را کاهش دهد.

تابع استخراج‌شده باید حداقل یکی از این ویژگی‌ها را داشته باشد:

  • مسئولیت مستقل
  • نامی که مفهوم را بهتر می‌کند
  • منطق تکراری
  • امکان تست مستقل معنادار
  • کاهش محسوس پیچیدگی
  • مرز مناسب Dependency

تابع زیر ارزش زیادی ندارد:

def subtract(a, b):
    return a - b

مگر اینکه مفهوم کسب‌وکار مشخصی مانند calculate_taxable_amount ایجاد کند.

رفکتور شرط‌های پیچیده

قبل:

if (
    user
    and user.is_active
    and order.total > 0
    and not order.cancelled
    and (
        user.is_vip
        or order.total > threshold
    )
):
    ...

به‌جای درخواست «ساده‌کردن شرط»، رفتارهای منطقی را ثبت کنید:

  • کاربر وجود ندارد.
  • کاربر غیرفعال است.
  • مبلغ صفر است.
  • سفارش لغوشده است.
  • کاربر VIP است.
  • کاربر عادی با مبلغ بالاتر از حد است.
  • کاربر عادی در مرز حد است.

سپس می‌توان Predicateهای نام‌گذاری‌شده استخراج کرد.

رفکتور کد دارای Side Effect

اگر تابع علاوه بر محاسبه این کارها را انجام دهد:

  • ثبت دیتابیس
  • ارسال پیام
  • نوشتن فایل
  • تغییر Cache
  • انتشار Event

ترتیب عملیات بخشی از رفتار است.

مدل باید این اطلاعات را ثبت کند:

{
  "side_effects": [
    {
      "operation": "save order",
      "order": 1
    },
    {
      "operation": "publish order_created event",
      "order": 2
    }
  ]
}

رفکتور نباید ترتیب Side Effectها را بدون تصمیم صریح تغییر دهد.

رفکتور کد بدون تست

ترتیب مناسب:

  1. مسیرهای اصلی اجرا را شناسایی کنید.
  2. API عمومی را ثبت کنید.
  3. ورودی و خروجی‌های واقعی را نمونه‌برداری کنید.
  4. Characterization Test بسازید.
  5. Side Effectها را Mock یا Capture کنید.
  6. تست‌ها را اجرا کنید.
  7. Refactor کوچک انجام دهید.
  8. دوباره تست کنید.

نباید مستقیماً از مدل بخواهید یک ماژول بدون تست را بازنویسی کند.

Golden Master Testing

برای تابعی با خروجی پیچیده می‌توان مجموعه‌ای از ورودی‌ها را اجرا و خروجی فعلی را ذخیره کرد.

import json

from app.legacy_report import (
    generate_report,
)


def test_report_matches_golden_master():
    input_data = {
        "customer_id": 42,
        "period": "monthly",
    }

    actual = generate_report(
        input_data
    )

    expected = json.loads(
        Path(
            "tests/fixtures/"
            "report-golden.json"
        ).read_text(
            encoding="utf-8"
        )
    )

    assert actual == expected

Golden Master رفتار فعلی را ثبت می‌کند، اما اگر خروجی شامل زمان، شناسه تصادفی یا ترتیب غیرقطعی باشد باید ابتدا نرمال شود.

رفکتور مرحله‌ای با Git

برای هر مرحله:

pytest -q

سپس Diff را بررسی کنید:

git diff --stat
git diff

اگر مرحله بیش از حد بزرگ شده است، آن را کوچک‌تر کنید.

Commitهای پیشنهادی:

test: characterize pricing validation behavior
refactor: extract money rounding helper
refactor: extract pricing validation
refactor: extract subtotal calculation
refactor: extract discount calculation

هر Commit باید مستقل و تست‌پذیر باشد.

بررسی تغییر رفتار با Differential Testing

می‌توان نسخه قدیمی و جدید را با ورودی‌های یکسان اجرا و خروجی را مقایسه کرد.

def compare_implementations(
    old_function,
    new_function,
    cases,
):
    differences = []

    for case in cases:
        try:
            old_result = old_function(
                **case
            )
            old_error = None
        except Exception as error:
            old_result = None
            old_error = (
                type(error).__name__,
                str(error),
            )

        try:
            new_result = new_function(
                **case
            )
            new_error = None
        except Exception as error:
            new_result = None
            new_error = (
                type(error).__name__,
                str(error),
            )

        if (
            old_result != new_result
            or old_error != new_error
        ):
            differences.append(
                {
                    "case": case,
                    "old_result": old_result,
                    "new_result": new_result,
                    "old_error": old_error,
                    "new_error": new_error,
                }
            )

    return differences

در Refactor خالص، Differences باید خالی باشند؛ مگر اختلافی که صریحاً تأیید شده باشد.

Property-based Testing برای حفظ رفتار

برای تولید ورودی‌های متنوع می‌توان از Hypothesis استفاده کرد:

pip install hypothesis

نمونه مقایسه نسخه قدیمی و جدید:

from decimal import Decimal

from hypothesis import (
    given,
    strategies as st,
)


@given(
    price=st.decimals(
        min_value="0",
        max_value="100000000",
        places=2,
        allow_nan=False,
        allow_infinity=False,
    ),
    quantity=st.integers(
        min_value=0,
        max_value=100,
    ),
    customer_type=st.sampled_from(
        ["regular", "vip"]
    ),
    tax_rate=st.decimals(
        min_value="0",
        max_value="1",
        places=2,
        allow_nan=False,
        allow_infinity=False,
    ),
)
def test_refactor_preserves_behavior(
    price,
    quantity,
    customer_type,
    tax_rate,
):
    items = [
        {
            "price": str(price),
            "quantity": quantity,
        }
    ]

    old_result = old_calculate(
        items,
        customer_type,
        Decimal(tax_rate),
    )

    new_result = new_calculate(
        items,
        customer_type,
        Decimal(tax_rate),
    )

    assert new_result == old_result

نسخه قدیمی و جدید باید هم‌زمان و با نام‌های جداگانه قابل اجرا باشند.

Refactor در برابر مهاجرت نسخه

مهاجرت Python، Framework یا Library معمولاً فقط Refactor نیست؛ زیرا Dependency جدید ممکن است رفتار متفاوتی داشته باشد.

برای Migration Plan این اطلاعات را آماده کنید:

  • نسخه فعلی و مقصد
  • Deprecationها
  • Breaking Changeهای مستند
  • APIهای استفاده‌شده
  • Test Suite
  • Lockfile
  • Runtime
  • محدودیت استقرار
  • مسیر Rollback

مراحل مناسب:

  1. Test Baseline
  2. Inventory وابستگی‌ها
  3. شناسایی APIهای Deprecated
  4. مهاجرت یک بخش
  5. اجرای تست
  6. مقایسه خروجی
  7. Benchmark در صورت نیاز
  8. مرحله بعد

مدل نباید فقط Syntax را تبدیل کند؛ تفاوت Semantics نیز باید بررسی شود.

استفاده از AI برای تبدیل کد بین زبان‌ها

تبدیل Python به TypeScript یا PHP به Python یک Rewrite محسوب می‌شود، نه Refactor.

برای کاهش خطا:

  • Contract مستقل تعریف کنید.
  • Test Fixtureهای مشترک بسازید.
  • ورودی و خروجی مرجع داشته باشید.
  • نوع خطاها را نگاشت کنید.
  • رفتار عدد، تاریخ و Null را مقایسه کنید.
  • Differential Testing اجرا کنید.
  • مهاجرت را ماژول‌به‌ماژول انجام دهید.

تشخیص Refactor خارج از محدوده

مواردی که باید متوقف شوند:

  • تغییر API عمومی
  • تغییر Schema داده
  • تغییر نوع خطا
  • اضافه‌کردن Dependency
  • تغییر رفتار Business Rule
  • حذف مسیر قدیمی بدون تصمیم
  • تغییر فرمت خروجی
  • تغییر ترتیب Side Effect
  • تغییر هم‌زمان چند ماژول نامرتبط

این موارد ممکن است ارزشمند باشند، اما باید Task و Review جداگانه داشته باشند.

اجرای Patch در محیط جدا

جریان پیشنهادی:

Source + Specification + Tests
              ↓
        Refactor Plan
              ↓
         Human Approval
              ↓
      One-step Patch Draft
              ↓
     Temporary Git Worktree
              ↓
   Static Checks + Full Tests
              ↓
  Differential and Coverage Check
              ↓
          Human Review

در نسخه اولیه، ابزار فقط Patch را ذخیره کند و آن را خودکار روی Branch اصلی اعمال نکند.

معیارهای کیفیت Refactor

Behavior Preservation

مهم‌ترین معیار؛ خروجی و اثر جانبی باید حفظ شوند.

Complexity

آیا پیچیدگی واقعاً کاهش یافته است؟

Cohesion

آیا هر تابع یا کلاس مسئولیت منسجم‌تری دارد؟

Coupling

آیا وابستگی میان اجزا کمتر یا روشن‌تر شده است؟

Testability

آیا رفتارهای مهم ساده‌تر تست می‌شوند؟

Diff Size

آیا تغییر مرحله‌ای و قابل Review است؟

Public API Stability

آیا Contract عمومی بدون تصمیم صریح تغییر نکرده است؟

Performance Baseline

اگر مسیر پرتکرار است، قبل و بعد Benchmark بگیرید.

ارزیابی AI Refactoring Assistant

Dataset پیشنهادی:

  • تابع طولانی
  • شرط تو در تو
  • منطق تکراری
  • کد دارای Side Effect
  • API عمومی حساس
  • کد بدون تست
  • Code Smell ظاهری اما قابل قبول
  • Refactor پیشنهادی با تغییر رفتار پنهان
  • Migration نسخه
  • تبدیل زبان

معیارها:

معیارتوضیح
Behavior Preservationدرصد Patchهای بدون تغییر رفتار
Test Pass Rateموفقیت تست‌های قبلی
Differential Matchبرابری خروجی قدیم و جدید
Patch Validityقابل اعمال بودن Patch
Minimalityمحدودبودن Diff
Scope Complianceعدم تغییر خارج از Step
Smell Reductionکاهش مشکل هدف
Human Acceptanceدرصد Patchهای پذیرفته‌شده
Review Timeزمان بررسی Patch
Regression Rateخطاهای ایجادشده پس از Refactor

مدیریت هزینه

تحلیل در سطح Symbol

فقط تابع، کلاس و تست مرتبط ارسال شوند.

Plan یک‌بار، Patch مرحله‌ای

Plan برای کل کار تولید و هر Patch فقط برای یک Step ساخته شود.

Cache کردن Plan

کلید Cache:

source_hash +
test_hash +
spec_hash +
model_id +
prompt_version

استفاده از ابزارهای قطعی

Formatter، Linter، Type Checker و Tests را به مدل نسپارید.

حذف فایل‌های Generated

Lockfile و Build Output معمولاً Context مفیدی برای Refactor ندارند.

انتخاب مدل مناسب

برای Refactoring، مدل باید در این زمینه‌ها مناسب باشد:

  • درک عمیق کد
  • پیروی از Constraint
  • حفظ API
  • تحلیل Test
  • تولید Patch کوچک
  • خروجی JSON معتبر
  • Context Window مناسب
  • شناخت Framework و زبان

برای استخراج نام یا تابع ساده ممکن است مدل سریع‌تر کافی باشد. برای Legacy Code چندفایلی، مدل قوی‌تر احتمالاً نتیجه بهتری می‌دهد.

مدل‌ها و هزینه به‌روز را در صفحه مدل‌های درواره بررسی کنید.

اشتباهات رایج

درخواست «این کد را تمیز کن»

هدف، Constraint و رفتارهای لازم برای حفظ مشخص نیستند.

Refactor بدون Test Baseline

ابتدا تست‌های فعلی باید موفق باشند.

مخلوط‌کردن Refactor و Feature

تغییر رفتار را در Task جدا انجام دهید.

Patch بزرگ

هر مرحله باید یک هدف و امکان بازگشت داشته باشد.

اعتماد به ظاهر کد

خوانایی بهتر، حفظ رفتار را تضمین نمی‌کند.

حذف رفتار عجیب بدون تصمیم

رفتار عجیب ممکن است بخشی از Contract مصرف‌کننده باشد.

تغییر تست برای هماهنگی با Patch

Specification تعیین می‌کند کد یا تست کدام‌یک باید تغییر کند.

اجرای مستقیم Patch مدل

Patch ابتدا باید بررسی و در محیط جدا آزمایش شود.

نادیده‌گرفتن Side Effect

فقط برابر بودن مقدار Return کافی نیست.

برنامه پیاده‌سازی در تیم

مرحله اول: تحلیل Code Smell

AI فقط مشکل و شواهد را گزارش کند.

مرحله دوم: Characterization Test

رفتارهای مهم و مرزی ثبت شوند.

مرحله سوم: Plan مرحله‌ای

هر Step مستقل و کوچک باشد.

مرحله چهارم: Patch پیشنهادی

Patch اعمال خودکار نشود.

مرحله پنجم: اجرای ایزوله

Test، Type Check، Linter و Differential Test اجرا شوند.

مرحله ششم: ارزیابی

Patchهای پذیرفته و ردشده برای بهبود Prompt ثبت شوند.

چک‌لیست رفکتور با AI

  • هدف Refactor مشخص است.
  • تغییر Feature داخل Task نیست.
  • تست‌های فعلی پیش از شروع موفق‌اند.
  • Specification موجود است.
  • API عمومی ثبت شده است.
  • Side Effectها شناخته شده‌اند.
  • رفتارهای مرزی تست دارند.
  • Characterization Test نوشته شده است.
  • Plan مرحله‌ای است.
  • هر Patch فقط یک هدف دارد.
  • Dependency جدید اضافه نشده است.
  • Exceptionها بدون تصمیم تغییر نکرده‌اند.
  • قالب خروجی حفظ شده است.
  • Differential Test اجرا شده است.
  • کل Test Suite موفق است.
  • Diff توسط توسعه‌دهنده بررسی شده است.
  • API Key فقط در Backend نگهداری می‌شود.

پرسش‌های متداول

آیا هوش مصنوعی می‌تواند کد را Refactor کند؟

بله. AI می‌تواند Code Smellها را شناسایی، برنامه Refactor و Patch پیشنهادی تولید کند. حفظ رفتار باید با تست و مقایسه خروجی تأیید شود.

تفاوت Refactor و بازنویسی چیست؟

در Refactor رفتار عمومی حفظ می‌شود. در Rewrite بخش مهمی از پیاده‌سازی دوباره نوشته می‌شود و احتمال تغییر رفتار بیشتر است.

آیا می‌توان Legacy Code بدون تست را با AI بازآرایی کرد؟

ابتدا باید Characterization Test ساخته شود. بازنویسی مستقیم کد قدیمی بدون ثبت رفتار فعلی ریسک زیادی دارد.

Characterization Test چیست؟

تستی است که رفتار فعلی کد را ثبت می‌کند. این تست الزاماً اثبات نمی‌کند رفتار فعلی از نظر محصول صحیح است.

چگونه مطمئن شویم رفتار تغییر نکرده است؟

Test Suite، Differential Testing، Property-based Testing و بررسی Side Effectها را اجرا کنید.

آیا AI می‌تواند کد را بین دو زبان تبدیل کند؟

بله، اما این کار معمولاً Rewrite یا Migration است، نه Refactor. Contract و تست‌های مرجع برای مقایسه دو نسخه ضروری‌اند.

آیا Patch تولیدشده را خودکار اعمال کنیم؟

در شروع خیر. Patch باید ذخیره، بررسی و در محیط جدا اجرا شود. خودکارسازی فقط پس از ارزیابی و با محدودیت‌های روشن مناسب است.

بهترین مدل برای Refactoring چیست؟

به زبان، اندازه Context، کیفیت تست و پیچیدگی کد بستگی دارد. مدل‌های موجود و قیمت آن‌ها را در صفحه مدل‌های درواره بررسی کنید.

API درواره چگونه به ابزار Refactor متصل می‌شود؟

در Backend، base_url را برابر https://api.darvareh.ir/v1 قرار دهید و Source، Test، Specification و Step تأییدشده را برای مدل ارسال کنید.

جمع‌بندی

رفکتور با هوش مصنوعی می‌تواند سرعت بهبود کدهای قدیمی را افزایش دهد، اما فقط زمانی که حفظ رفتار در مرکز فرایند قرار داشته باشد.

روش درست این نیست که کل فایل را به مدل بدهیم و بگوییم «تمیزش کن». ابتدا باید API عمومی، Side Effectها، رفتارهای مرزی و اختلاف میان Source و Specification ثبت شوند. سپس Characterization Testها تکمیل و یک Plan مرحله‌ای ساخته شود.

در پروژه این مقاله یک AI Refactoring Assistant با Python، Pytest، Pydantic و API درواره ساختیم. ابزار ابتدا Context و تست‌ها را تحلیل می‌کند، Code Smellها و کمبود تست را گزارش می‌دهد و یک برنامه کوچک و قابل بازگشت می‌سازد. سپس فقط برای یک Step تأییدشده، Patch پیشنهادی تولید می‌کند.

برای شروع، در درواره ثبت‌نام و API Key دریافت کنید. مدل مناسب را نیز از صفحه مدل‌های درواره انتخاب و ابزار را ابتدا روی یک تابع کوچک، دارای تست و بدون Side Effect پیچیده آزمایش کنید.

مقالات مرتبط

برای مطالعه شرایط استفاده و محدودیت‌های مسئولیت، صفحه «سلب مسئولیت» را مشاهده کنید.

Read more

اتوماسیون هوش مصنوعی چیست؟ کاربردها و آموزش ساخت AI Automation

اتوماسیون هوش مصنوعی چیست؟ کاربردها و آموزش ساخت AI Automation

اتوماسیون هوش مصنوعی با ترکیب گردش‌کارهای خودکار و مدل‌های هوش مصنوعی، پردازش متن، دسته‌بندی، استخراج اطلاعات و تصمیم‌های پیشنهادی را خودکار می‌کند. در این راهنما، معماری و ساخت نمونه عملی آن با API درواره را می‌آموزید.

Agentic Commerce چیست؟ آینده خرید با ایجنت هوش مصنوعی

Agentic Commerce چیست؟ آینده خرید با ایجنت هوش مصنوعی

Agentic Commerce شیوه‌ای جدید برای خرید اینترنتی است که در آن ایجنت هوش مصنوعی می‌تواند نیاز کاربر را بفهمد، محصولات را جست‌وجو و مقایسه کند و فرایند خرید را پیش ببرد. در این راهنما با معماری، UCP، ACP و پیاده‌سازی آن با API درواره آشنا می‌شوید.