AI Code Assistant Workflow

Learn how to effectively use AI code assistants for Half-Stack development

วิธีการใช้งาน AI Code Assistant (GitHub Copilot, ChatGPT, Claude) ให้มีประสิทธิภาพสูงสุดสำหรับ Half-Stack Development

Choosing Your AI Assistant

✅ ข้อดี:
├─ Integrated ใน VS Code
├─ Real-time suggestions
├─ เข้าใจ context ของโค้ด
└─ Support หลายภาษา

❌ ข้อเสีย:
├─ ต้องจ่าย subscription
├─ บางที suggest ผิด
└─ จำกัดการสนทนายาวๆ

ChatGPT Plus

✅ ข้อดี:
├─ สามารถสนทนายาวๆ
├─ อธิบายโค้ดได้ดี
├─ Debugging ดีเยี่ยม
└─ Support ภาษาไทย

❌ ข้อเสีย:
├─ ต้อง copy-paste
├─ ไม่ integrated กับ editor
└─ จำกัด context length

Claude

✅ ข้อดี:
├─ โค้ดสะอาดและถูกต้อง
├─ Long context window
├─ Good at documentation
└─ Less "hallucination"

❌ ข้อเสีย:
├─ ช้ากว่า ChatGPT
├─ ไม่ค่อย support ภาษาไทย
└─ ยังใหม่กว่า

Setup Your Environment

VS Code + Extensions

{
  "recommendations": [
    "github.copilot",
    "github.copilot-chat",
    "bradlc.vscode-tailwindcss",
    "esbenp.prettier-vscode",
    "ms-vscode.vscode-typescript-next",
    "humao.rest-client"
  ]
}

Environment Variables

# .env
OPENAI_API_KEY=your-openai-key
ANTHROPIC_API_KEY=your-claude-key
GITHUB_TOKEN=your-github-token

Prompt Engineering Best Practices

1. Be Specific

❌ Bad:
"Write a function to process LINE messages"

✅ Good:
"Write a TypeScript function to process LINE webhook messages. 
Extract user message text, detect intent (greeting, price, appointment), 
and return appropriate response in Thai. Handle errors gracefully."

2. Provide Context

✅ Good Context:
"I'm building a LINE chatbot for a dental clinic in Thailand.
The system uses n8n for workflow automation and needs to:
1. Handle appointment bookings
2. Provide clinic information
3. Schedule reminders
Target users are Thai patients who prefer casual language."

3. Define Requirements

✅ Good Requirements:
"Create an Express.js API endpoint with these specifications:
- Method: POST /api/appointment
- Input: {name, phone, date, time}
- Validation: Thai phone number format
- Database: Save to Supabase
- Response: Confirmation in Thai
- Error handling: Duplicate booking detection"

Workflow Examples

Example 1: Thai Language Processing

// Prompt: "Create a TypeScript function to detect Thai keywords in customer messages"

interface MessageIntent {
  intent: 'greeting' | 'price' | 'appointment' | 'contact' | 'unknown';
  confidence: number;
  entities: Record<string, any>;
}

function detectThaiIntent(message: string): MessageIntent {
  const normalizedMessage = message.toLowerCase().trim();
  
  const keywords = {
    greeting: ['สวัสดี', 'ดี', 'หวัดดี', 'เฮ็ลโล', 'ดีครับ', 'ดีคะ'],
    price: ['ราคา', 'เท่าไหร่', 'กี่บาท', 'ค่าใช้จ่าย', 'ราคาเท่าไร'],
    appointment: ['นัด', 'ว่าง', 'เวลา', 'วัน', 'จอง', 'นัดหมาย'],
    contact: ['ติดต่อ', 'โทร', 'อีเมล', 'ที่อยู่', 'เบอร์']
  };
  
  let maxScore = 0;
  let detectedIntent: MessageIntent['intent'] = 'unknown';
  
  for (const [intent, words] of Object.entries(keywords)) {
    const score = words.filter(word => normalizedMessage.includes(word)).length;
    if (score > maxScore) {
      maxScore = score;
      detectedIntent = intent as MessageIntent['intent'];
    }
  }
  
  return {
    intent: detectedIntent,
    confidence: maxScore > 0 ? Math.min(maxScore / 2, 1) : 0,
    entities: extractEntities(normalizedMessage)
  };
}

function extractEntities(message: string): Record<string, any> {
  const entities: Record<string, any> = {};
  
  // Extract phone numbers
  const phoneMatch = message.match(/0[689]\d{8}/);
  if (phoneMatch) {
    entities.phone = phoneMatch[0];
  }
  
  // Extract dates
  const dateMatch = message.match(/(\d{1,2})\/(\d{1,2})/);
  if (dateMatch) {
    entities.date = dateMatch[0];
  }
  
  return entities;
}

Example 2: API Integration

// Prompt: "Create a service to connect with Thai government business registration API"

interface BusinessRegistration {
  businessId: string;
  businessName: string;
  address: string;
  status: 'active' | 'inactive' | 'suspended';
  registrationDate: string;
}

class DBDService {
  private apiKey: string;
  private baseUrl = 'https://api.dbd.go.th/api/v1';
  
  constructor(apiKey: string) {
    this.apiKey = apiKey;
  }
  
  async searchBusiness(businessId: string): Promise<BusinessRegistration | null> {
    try {
      const response = await fetch(`${this.baseUrl}/business/${businessId}`, {
        headers: {
          'Authorization': `Bearer ${this.apiKey}`,
          'Content-Type': 'application/json'
        }
      });
      
      if (!response.ok) {
        throw new Error(`DBD API Error: ${response.status}`);
      }
      
      const data = await response.json();
      
      return {
        businessId: data.business_id,
        businessName: data.business_name_th,
        address: data.full_address,
        status: data.status.toLowerCase(),
        registrationDate: data.registration_date
      };
      
    } catch (error) {
      console.error('Error searching business:', error);
      return null;
    }
  }
  
  async validateBusiness(businessId: string): Promise<boolean> {
    const business = await this.searchBusiness(businessId);
    return business?.status === 'active';
  }
}

Example 3: Data Processing

// Prompt: "Create a function to process sales data for Thai business reports"

interface SalesData {
  date: string;
  productId: string;
  quantity: number;
  price: number;
  customerId: string;
}

interface SalesReport {
  period: string;
  totalRevenue: number;
  totalOrders: number;
  averageOrderValue: number;
  topProducts: Array<{
    productId: string;
    quantity: number;
    revenue: number;
  }>;
}

class SalesProcessor {
  generateReport(sales: SalesData[], period: 'daily' | 'weekly' | 'monthly'): SalesReport {
    const filteredSales = this.filterByPeriod(sales, period);
    
    const totalRevenue = filteredSales.reduce((sum, sale) => sum + (sale.quantity * sale.price), 0);
    const totalOrders = new Set(filteredSales.map(s => s.date)).size;
    const averageOrderValue = totalRevenue / totalOrders;
    
    const productSales = this.aggregateByProduct(filteredSales);
    const topProducts = Object.entries(productSales)
      .map(([productId, data]) => ({
        productId,
        quantity: data.quantity,
        revenue: data.revenue
      }))
      .sort((a, b) => b.revenue - a.revenue)
      .slice(0, 10);
    
    return {
      period: this.getPeriodLabel(period),
      totalRevenue,
      totalOrders,
      averageOrderValue,
      topProducts
    };
  }
  
  private filterByPeriod(sales: SalesData[], period: string): SalesData[] {
    const now = new Date();
    const cutoffDate = new Date();
    
    switch (period) {
      case 'daily':
        cutoffDate.setDate(now.getDate() - 1);
        break;
      case 'weekly':
        cutoffDate.setDate(now.getDate() - 7);
        break;
      case 'monthly':
        cutoffDate.setMonth(now.getMonth() - 1);
        break;
    }
    
    return sales.filter(sale => new Date(sale.date) >= cutoffDate);
  }
  
  private aggregateByProduct(sales: SalesData[]): Record<string, {quantity: number, revenue: number}> {
    return sales.reduce((acc, sale) => {
      if (!acc[sale.productId]) {
        acc[sale.productId] = { quantity: 0, revenue: 0 };
      }
      acc[sale.productId].quantity += sale.quantity;
      acc[sale.productId].revenue += sale.quantity * sale.price;
      return acc;
    }, {});
  }
  
  private getPeriodLabel(period: string): string {
    const labels = {
      daily: 'รายวัน',
      weekly: 'รายสัปดาห์',
      monthly: 'รายเดือน'
    };
    return labels[period] || period;
  }
}

Debugging with AI

1. Error Analysis

Prompt: "I'm getting this error in my n8n function node:
'Cannot read property 'message' of undefined'
Here's my code: [paste code]
The input data looks like: [paste sample data]
What's wrong and how do I fix it?"

2. Performance Issues

Prompt: "My LINE chatbot is slow to respond. Here's the workflow:
[paste workflow description]
Response time is 3-5 seconds. How can I optimize it?
Consider Thai language processing and database queries."

3. Integration Problems

Prompt: "I'm trying to connect n8n with Supabase but getting:
'Invalid API key' error. I've set the environment variables
and double-checked the credentials. What else could be wrong?"

Code Review Process

1. Self-Review with AI

Prompt: "Review this TypeScript function for:
1. TypeScript best practices
2. Error handling
3. Performance issues
4. Security vulnerabilities
5. Thai language support

Function: [paste code]"

2. Refactoring Suggestions

Prompt: "How can I refactor this code to be:
- More readable
- More maintainable
- More testable
- More performant

Current code: [paste code]"

3. Testing Help

Prompt: "Write unit tests for this function using Jest.
Test cases should include:
- Normal scenarios
- Edge cases
- Error conditions
- Thai language inputs

Function: [paste code]"

Common Pitfalls

1. Over-reliance on AI

  • ❌ Copy-paste โดยไม่เข้าใจ
  • ❌ ไม่ตรวจสอบความถูกต้อง
  • ❌ พึ่งพอ AI มากเกินไป

2. Poor Prompts

  • ❌ Prompt สั้นเกินไป
  • ❌ ไม่ให้ context พอ
  • ❌ ไม่ระบุ requirements ชัดเจน

3. Ignoring Context

  • ❌ ไม่บอกว่าใช้กับ n8n
  • ❌ ไม่ระบุว่าเป็นธุรกิจไทย
  • ❌ ไม่ระบุ constraints ที่มี

Best Practices Summary

✅ Do's

  • เขียน prompt ที่ชัดเจนและละเอียด
  • ให้ context เกี่ยวกับโปรเจกต์
  • ตรวจสอบความถูกต้องของโค้ด
  • ใช้ AI สำหรับ learning ไม่ใช่ cheating
  • ทบทวนและปรับปรุงโค้ดด้วยตนเอง

❌ Don'ts

  • ไม่ตรวจสอบความถูกต้องของโค้ด
  • พึ่งพอ AI 100%
  • ใช้ AI สำหรับ mission critical code โดยไม่ทบทวน
  • เปิดเผย sensitive data ใน prompts
  • คัดลอกโค้ดโดยไม่เข้าใจ

Next Steps


ต้องการคำแนะนำ? ติดต่อเราได้ที่ ShantiLink.com 💬