Few-shot esimerkit pipeline-prompteissa: manageri, koodari, QA
Pienet mallit tuottavat huomattavasti parempaa koodia kun promptissa on konkreettinen esimerkki oikeasta vastauksesta. Lisätty: - Manageri: esimerkki tiedostolistasta - Koodari: esimerkki main.py ja models.py -tiedostoista - QA: esimerkki pytest + TestClient -testeistä Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -2152,7 +2152,11 @@ CONSTRAINTS — the coder can only generate ~400 tokens per file:
|
|||||||
- Only .py and pyproject.toml files
|
- Only .py and pyproject.toml files
|
||||||
- No directories, no paths, just filenames
|
- No directories, no paths, just filenames
|
||||||
- List dependencies first, then main app
|
- List dependencies first, then main app
|
||||||
- Prefer fewer, focused files over many small ones
|
|
||||||
|
EXAMPLE for "FastAPI todo app with SQLite":
|
||||||
|
pyproject.toml: project metadata and dependencies
|
||||||
|
models.py: SQLAlchemy models and database setup
|
||||||
|
main.py: FastAPI app with CRUD endpoints
|
||||||
|
|
||||||
Project: ${task}`;
|
Project: ${task}`;
|
||||||
termLog(`\n<span style="color:#d29922;font-weight:bold">[1] Manageri</span> — projektin suunnittelu`);
|
termLog(`\n<span style="color:#d29922;font-weight:bold">[1] Manageri</span> — projektin suunnittelu`);
|
||||||
@@ -2223,9 +2227,48 @@ start = "uvicorn main:app --reload"`;
|
|||||||
extraInstructions = '\nList one dependency per line. No version pins unless necessary.';
|
extraInstructions = '\nList one dependency per line. No version pins unless necessary.';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const coderExample = file.name.includes('main') || file.name.includes('app')
|
||||||
|
? `\nEXAMPLE output for a main.py:
|
||||||
|
from fastapi import FastAPI, Depends
|
||||||
|
from sqlalchemy.orm import Session
|
||||||
|
from models import get_db, User
|
||||||
|
|
||||||
|
app = FastAPI()
|
||||||
|
|
||||||
|
@app.get("/users")
|
||||||
|
def list_users(db: Session = Depends(get_db)):
|
||||||
|
return db.query(User).all()
|
||||||
|
|
||||||
|
@app.post("/users")
|
||||||
|
def create_user(name: str, db: Session = Depends(get_db)):
|
||||||
|
user = User(name=name)
|
||||||
|
db.add(user)
|
||||||
|
db.commit()
|
||||||
|
return {"id": user.id, "name": user.name}`
|
||||||
|
: file.name.includes('model')
|
||||||
|
? `\nEXAMPLE output for a models.py:
|
||||||
|
from sqlalchemy import create_engine, Column, Integer, String
|
||||||
|
from sqlalchemy.orm import sessionmaker, declarative_base
|
||||||
|
|
||||||
|
engine = create_engine("sqlite:///app.db")
|
||||||
|
SessionLocal = sessionmaker(bind=engine)
|
||||||
|
Base = declarative_base()
|
||||||
|
|
||||||
|
class User(Base):
|
||||||
|
__tablename__ = "users"
|
||||||
|
id = Column(Integer, primary_key=True)
|
||||||
|
name = Column(String)
|
||||||
|
|
||||||
|
Base.metadata.create_all(engine)
|
||||||
|
|
||||||
|
def get_db():
|
||||||
|
db = SessionLocal()
|
||||||
|
try: yield db
|
||||||
|
finally: db.close()`
|
||||||
|
: '';
|
||||||
const coderPrompt = `${context}Project: ${task}
|
const coderPrompt = `${context}Project: ${task}
|
||||||
Write ONLY the file "${file.name}"${file.desc ? ': ' + file.desc : ''}.${extraInstructions}
|
Write ONLY the file "${file.name}"${file.desc ? ': ' + file.desc : ''}.${extraInstructions}${coderExample}
|
||||||
IMPORTANT: Keep the code SHORT and focused. Max ~50 lines. No comments, no docstrings, no type hints unless essential. Write minimal, working code.`;
|
IMPORTANT: Keep the code SHORT. Max ~50 lines. No comments, no docstrings. Write minimal, working code. Output ONLY code.`;
|
||||||
const code = await kpnRun(agentPrompts.coder.model, coderPrompt);
|
const code = await kpnRun(agentPrompts.coder.model, coderPrompt);
|
||||||
if (!code) {
|
if (!code) {
|
||||||
termLog(` ✗ Pipeline keskeytyi (${file.name})`, '#f85149');
|
termLog(` ✗ Pipeline keskeytyi (${file.name})`, '#f85149');
|
||||||
@@ -2274,8 +2317,24 @@ Write the corrected code.`;
|
|||||||
const step5 = fileList.length + (review && !review.toLowerCase().includes('lgtm') ? 5 : 3);
|
const step5 = fileList.length + (review && !review.toLowerCase().includes('lgtm') ? 5 : 3);
|
||||||
termLog(`\n<span style="color:#3fb950;font-weight:bold">[${step5}] QA</span> — testit`);
|
termLog(`\n<span style="color:#3fb950;font-weight:bold">[${step5}] QA</span> — testit`);
|
||||||
pipelineStep('qa', 'Testit', 'active', 'Kirjoitetaan testejä');
|
pipelineStep('qa', 'Testit', 'active', 'Kirjoitetaan testejä');
|
||||||
const qaPrompt = `Write a short test file (test_app.py) for this project. Use pytest. Max 3 test functions. Keep it minimal.
|
const qaPrompt = `Write test_app.py using pytest and FastAPI TestClient. Max 3 tests. Output ONLY code.
|
||||||
|
|
||||||
|
EXAMPLE:
|
||||||
|
from fastapi.testclient import TestClient
|
||||||
|
from main import app
|
||||||
|
|
||||||
|
client = TestClient(app)
|
||||||
|
|
||||||
|
def test_create():
|
||||||
|
r = client.post("/users", params={"name": "Test"})
|
||||||
|
assert r.status_code == 200
|
||||||
|
|
||||||
|
def test_list():
|
||||||
|
r = client.get("/users")
|
||||||
|
assert r.status_code == 200
|
||||||
|
assert isinstance(r.json(), list)
|
||||||
|
|
||||||
|
PROJECT CODE:
|
||||||
${Object.entries(generatedFiles).map(([n, c]) => `--- ${n} ---\n${c}`).join('\n\n')}`;
|
${Object.entries(generatedFiles).map(([n, c]) => `--- ${n} ---\n${c}`).join('\n\n')}`;
|
||||||
const tests = await kpnRun(agentPrompts.qa.model, qaPrompt, false, 512);
|
const tests = await kpnRun(agentPrompts.qa.model, qaPrompt, false, 512);
|
||||||
if (tests) generatedFiles['test_app.py'] = tests;
|
if (tests) generatedFiles['test_app.py'] = tests;
|
||||||
|
|||||||
Reference in New Issue
Block a user