ข้ามไปที่เนื้อหา

Code Companion

Tutorial นี้พาไปดู examples/code_companion/ — สคริปต์สามตัวที่เน้นสำหรับนักพัฒนา ใช้เอเจนต์แบบ native_react (ReAct) เพื่อทำงานเขียนโค้ดที่พบบ่อยแบบอัตโนมัติ: รีวิว diff ของ pull request, สืบสวนข้อผิดพลาด และสร้างเทสต์ แต่ละสคริปต์ปรับรูปแบบหลักเดียวกันไปใช้กับเวิร์กโฟลว์ที่ต่างกัน ทำให้ต่อยอดไปใช้กับงาน code intelligence ของคุณเองได้ง่าย

สิ่งที่ต้องมีก่อน

  • Python 3.10 ขึ้นไป
  • ติดตั้ง OpenJarvis แล้ว: uv sync --extra dev จาก root ของ repository
  • มี inference engine กำลังรันอยู่ — Ollama ในเครื่อง หรือ cloud API key ใน .env
  • สำหรับ reviewer.py และ code_review.py: git repository ที่มีอย่างน้อยสอง branch หรือสอง commit

สคริปต์ทั้งสามตัว

สคริปต์ จุดประสงค์ Tools ที่ใช้
reviewer.py รีวิว git diff ระหว่างสอง branch git_diff, git_log, file_read, think
debugger.py สืบสวนข้อผิดพลาดและเสนอวิธีแก้ file_read, shell_exec, think
test_gen.py สร้างเทสต์แบบครอบคลุมสำหรับ Python module file_read, think, file_write

ทั้งสามตัวใช้เอเจนต์ native_react ด้วยรูปแบบ SDK เดียวกัน ความต่างอยู่ที่ tool ตัวไหนถูกส่งเข้าไปและ prompt ถูกจัดโครงสร้างอย่างไร

ลูปของเอเจนต์ ReAct

เอเจนต์ native_react implement วงจร Thought-Action-Observation แทนที่จะสร้างคำตอบครั้งเดียว มันจะวนซ้ำจนกว่าจะรวบรวมข้อมูลได้เพียงพอ:

stateDiagram-v2
    [*] --> Thought: Receive task prompt
    Thought --> Action: Decide which tool to call
    Action --> Observation: Execute tool, receive result
    Observation --> Thought: Feed result back into context
    Thought --> FinalAnswer: Sufficient information gathered
    FinalAnswer --> [*]

ลูปนี้ทำให้เอเจนต์สำรวจโค้ดเบสได้แบบปรับตัวได้ ตัวอย่างเช่น reviewer อาจอ่าน diff สังเกตเห็นการเรียกฟังก์ชันที่น่าสงสัย แล้วอ่านซอร์สของฟังก์ชันนั้นก่อนจะประเมินผล — โดยไม่ต้อง hardcode logic แบบแตกกิ่งเหล่านั้นไว้ในสคริปต์เลย

รูปแบบ SDK หลัก

สคริปต์ทั้งสามตัวใช้โครงสร้างเดียวกัน การเข้าใจรูปแบบนี้ทำให้คุณปรับไปใช้กับงาน code intelligence ใดก็ได้:

Core SDK pattern
from openjarvis import Jarvis

j = Jarvis(model="qwen3:8b", engine_key="ollama")  # (1)!
try:
    response = j.ask(
        prompt,                      # (2)!
        agent="native_react",        # (3)!
        tools=["git_diff", "think"], # (4)!
    )
    print(response)
finally:
    j.close()  # (5)!
  1. ทั้ง model และ engine_key เป็นตัวเลือกเสริม หากไม่ระบุจะใช้ค่าเริ่มต้นที่ตรวจจับอัตโนมัติจาก ~/.openjarvis/config.toml
  2. prompt อธิบายงานอย่างละเอียด รวมถึง tool ตัวไหนที่ควรใช้ ขั้นตอนไหนที่ควรทำตาม และโครงสร้างผลลัพธ์ควรเป็นอย่างไร
  3. "native_react" เลือก NativeReActAgent ใช้ alias "react" ก็ได้เช่นกัน
  4. รายการ tool ถูกส่งเข้าไปโดยตรง ชื่อ tool ที่ลงทะเบียนไว้ใดๆ ก็ใช้ได้ — รัน jarvis agent info native_react เพื่อดู tool ทั้งหมดที่มี
  5. เรียก j.close() เสมอเพื่อคืนทรัพยากรของ engine บล็อก try/finally รับประกันการเคลียร์ทรัพยากรแม้เอเจนต์จะสร้าง exception ก็ตาม

Code Review

สคริปต์ reviewer.py รีวิว diff ระหว่าง git ref สองตัว และสร้างผลตอบกลับแบบมีโครงสร้าง พร้อมปัญหาที่พบ ข้อเสนอแนะ และคำตัดสินโดยรวม

Terminal
# Review a feature branch against main (default)
python examples/code_companion/reviewer.py --branch feature-x

# Review a specific commit range
python examples/code_companion/reviewer.py --branch HEAD --base develop

# Use a cloud model for larger diffs
python examples/code_companion/reviewer.py \
    --branch feature-x --model gpt-4o --engine cloud

เอเจนต์ทำตามกระบวนการสี่ขั้นตอน:

  1. เรียก git_diff เพื่อดูว่าเปลี่ยนอะไรไปบ้างระหว่าง ref สองตัว
  2. เรียก git_log เพื่อเข้าใจประวัติ commit และเจตนา
  3. เรียก file_read กับไฟล์ใดๆ ที่ต้องการบริบทเพิ่มเติม
  4. เรียก think เพื่อให้เหตุผลเกี่ยวกับคุณภาพโค้ด บั๊ก และการตัดสินใจเชิงออกแบบ

ผลลัพธ์สุดท้ายมีโครงสร้างสี่ส่วน: Summary, Issues Found, Suggestions และ Overall Assessment (APPROVE, REQUEST CHANGES หรือ COMMENT)

Flag ค่าเริ่มต้น คำอธิบาย
--branch HEAD Branch หรือ commit ที่จะรีวิว
--base main Base branch ที่จะ diff เทียบด้วย
--model qwen3:8b Identifier ของโมเดล
--engine ollama Engine backend

Debug Assistant

สคริปต์ debugger.py รับข้อความ error, path ของไฟล์ (ถ้ามี) แล้วสร้างการวิเคราะห์สาเหตุที่แท้จริงพร้อมวิธีแก้ที่ชัดเจน

Terminal
# Investigate a TypeError
python examples/code_companion/debugger.py \
    --error "TypeError: NoneType has no attribute 'split'"

# Provide the file where the error occurred for faster analysis
python examples/code_companion/debugger.py \
    --error "KeyError: 'user_id'" \
    --file src/app/views.py

# Use a cloud model for complex stack traces
python examples/code_companion/debugger.py \
    --error "Segfault in libfoo.so" \
    --model gpt-4o --engine cloud

เอเจนต์ใช้ file_read ตรวจสอบซอร์สที่เกี่ยวข้อง, shell_exec รันคำสั่งวินิจฉัย (grep หา symbol, ตรวจ import, ดูเนื้อหาไดเรกทอรี) และ think เพื่อให้เหตุผลเกี่ยวกับสาเหตุที่แท้จริงก่อนเสนอวิธีแก้

ความปลอดภัยของ shell_exec

Tool shell_exec รันคำสั่งใน working directory ปัจจุบัน ในการ deploy จริง ToolExecutor บังคับใช้นโยบายความสามารถแบบ RBAC — ตรวจสอบว่าความสามารถ shell_exec ได้รับอนุญาตสำหรับ role ของเอเจนต์แล้ว ดู Architecture: Security

ผลลัพธ์มีสามส่วน: Root Cause, Proposed Fix (การเปลี่ยนโค้ดที่ชัดเจน) และ Prevention (type hint, การ validate, เทสต์)

Flag ค่าเริ่มต้น คำอธิบาย
--error (จำเป็น) ข้อความ error หรือ stack trace
--file (ไม่มี) Path ของไฟล์ที่เกิด error (ทางเลือกเสริม)
--model qwen3:8b Identifier ของโมเดล
--engine ollama Engine backend

Test Generator

สคริปต์ test_gen.py อ่าน Python module ให้เหตุผลเกี่ยวกับ public interface ของมัน แล้วเขียนไฟล์เทสต์แบบสมบูรณ์

Terminal
# Generate pytest tests for a module
python examples/code_companion/test_gen.py \
    --module src/openjarvis/tools/calculator.py

# Use unittest and specify the output file
python examples/code_companion/test_gen.py \
    --module src/openjarvis/tools/calculator.py \
    --framework unittest \
    --output tests/test_calculator_generated.py

เอเจนต์อ่าน module ด้วย file_read ใช้ think เพื่อวางแผน test case (happy path, edge case, การจัดการ error, boundary condition) อ่าน base class ที่เกี่ยวข้องเพื่อขอบริบทเพิ่มเติม แล้วเขียนไฟล์เทสต์แบบสมบูรณ์ด้วย file_write

Path ผลลัพธ์เริ่มต้น

หากไม่ระบุ --output ไฟล์ที่สร้างจะถูกบันทึกเป็น test_<module_name>.py ใน working directory ปัจจุบัน สคริปต์จะพิมพ์ path ผลลัพธ์เมื่อทำเสร็จ

เทสต์ที่สร้างขึ้นทำตามแนวทางเหล่านี้ (บังคับผ่าน prompt):

  • ทุก public function และ method มีเทสต์อย่างน้อยหนึ่งตัว
  • แต่ละเทสต์มี docstring อธิบายว่ากำลังตรวจสอบอะไร
  • ครอบคลุม edge case: input ว่าง, None, ค่าที่ใหญ่มาก, type ที่ไม่ถูกต้อง
  • Dependency ภายนอกถูก mock ด้วย unittest.mock
  • ไฟล์สมบูรณ์ในตัวเองและรันได้ด้วย pytest หรือ unittest โดยไม่ต้องแก้ไข
Flag ค่าเริ่มต้น คำอธิบาย
--module (จำเป็น) Path ไปยัง Python module
--framework pytest Test framework (pytest หรือ unittest)
--output test_<name>.py Path ของไฟล์ผลลัพธ์
--model qwen3:8b Identifier ของโมเดล
--engine ollama Engine backend

การเลือก Engine

Terminal
ollama serve
ollama pull qwen3:8b
python examples/code_companion/reviewer.py --branch feature-x
Terminal
source .env  # load OPENAI_API_KEY or similar
python examples/code_companion/reviewer.py \
    --branch feature-x \
    --model gpt-4o \
    --engine cloud

การปรับแต่ง

เปลี่ยนชุด Tool

แก้รายการ tools ในสคริปต์ใดๆ เพื่อเพิ่มหรือลบ tool ตัวอย่างเช่น ให้ reviewer ค้นหาเว็บหาช่องโหว่ความปลอดภัยที่รู้จักของ dependency ที่เห็นใน diff ด้วย:

tools = ["git_diff", "git_log", "file_read", "think", "web_search"]

ปรับ Prompt

แต่ละสคริปต์มีสตริง prompt ที่สั่งเอเจนต์ว่าต้องทำอะไรและสร้างผลลัพธ์แบบไหน ปรับแก้ให้ตรงกับข้อตกลงของทีมคุณ — ส่วนรีวิวที่ต่างออกไป มาตรฐานการเขียนโค้ดเฉพาะ หรือรูปแบบผลลัพธ์เฉพาะสำหรับเครื่องมือขั้นถัดไป

เพิ่ม Memory

สำหรับเวิร์กโฟลว์ที่รันหลาย session (เช่น reviewer ที่จำการประเมินไฟล์เดิมจากครั้งก่อนได้) เพิ่ม "memory_store" และ "memory_search" เข้าไปในรายการ tool แล้วปรับ prompt ให้ใช้งานมัน:

tools = ["git_diff", "git_log", "file_read", "think",
         "memory_store", "memory_search"]

ดูเพิ่มเติม

  • Architecture: Agents — รายละเอียดภายในของ NativeReActAgent และลูป Thought-Action-Observation
  • Architecture: Tools and Memory — git tools, file tools, shell tools และ pipeline การส่งงานของ ToolExecutor
  • Architecture: Security — นโยบายความสามารถแบบ RBAC สำหรับ shell_exec และ tool สิทธิ์สูงอื่นๆ
  • Tutorials: Deep Research Assistant — รูปแบบ SDK เดียวกัน แต่ใช้ OrchestratorAgent และ tool ด้าน web/memory