Практычныя прытамулі: Найкращыя практыкі команды MiniMax Agent: Агент ШІ — это цікл While.
Практычныя прыказкі: Найлепшыя практыкі команды MiniMax Agent: Агент AI — це цикл While. Паспісы, перакантовкі та слоты для коду для команд, якіе викорыстоўваюць гэты патэрн.
Існавайце гэта як перапрацоўку ідэй з даследжэння “MiniMax Agent Team Best Practice: An AI Agent Is a While Loop. A Reliable One Is a State Machine.” для аператараў: чыстыя этапы, арранжаваныя блакі коду і прыметкі па вяснаванню, якія застаюцца пасля перадачы. Этап Апглэву лепш працюе, калі яго спрыяваць як вимерную паверхню. Запісайце адна ідеальная транскрыпцыю, адзін кейс неудачы і прыметкі па адвярненню перад тым, як расшырваць масштаб. Спрыяйце гэты этап як кантракт межа вхіднымі дадзеннямі і паверыльнымі выходнымі рэзултатамі. Дайце назвы артыфактам, задаце критэрыя успеху і адмовіцеся ад безсловеснага частковага завершэння.
# naive_loop.py -- a single-agent tool loop,
# Mini-Agent style: summarize if needed ->
# llm.generate(messages, tools) -> execute
# tool_calls -> append results -> repeat.
import json
import subprocess
from openai import OpenAI
client = OpenAI()
MODEL = "gpt-4o-mini"
MAX_HISTORY = 40 # crude context budget
def read_file(path: str) -> str:
with open(path) as f:
return f.read()[:4000]
def run_cmd(cmd: str) -> str:
p = subprocess.run(
cmd, shell=True, timeout=30,
capture_output=True, text=True)
out = p.stdout + p.stderr
return f"exit={p.returncode}\n{out[-2000:]}"
TOOLS = {"read_file": read_file,
"run_cmd": run_cmd}
def schema(name, desc, arg):
return {
"type": "function",
"function": {
"name": name,
"description": desc,
"parameters": {
"type": "object",
"properties": {
arg: {"type": "string"},
},
"required": [arg],
},
},
}
SCHEMAS = [
schema("read_file",
"Read a local text file.", "path"),
schema("run_cmd",
"Run a shell command.", "cmd"),
]
def summarize(msgs):
# Mini-Agent compresses old turns with an
# LLM summary call when the context nears
# its limit; hard truncation is the v0.
if len(msgs) <= MAX_HISTORY:
return msgs
return [msgs[0]] + msgs[-MAX_HISTORY:]
def run(task: str, max_steps: int = 20):
msgs = [{"role": "user", "content": task}]
for _ in range(max_steps):
msgs = summarize(msgs)
r = client.chat.completions.create(
model=MODEL,
messages=msgs,
tools=SCHEMAS,
)
msg = r.choices[0].message
msgs.append(msg)
if not msg.tool_calls:
return msg.content # model says done
for call in msg.tool_calls:
fn = TOOLS[call.function.name]
args = json.loads(
call.function.arguments)
try:
out = fn(**args)
except Exception as e:
out = f"tool error: {e}"
msgs.append({
"role": "tool",
"tool_call_id": call.id,
"content": out,
})
return "hit max_steps -- gave up"
if __name__ == "__main__":
print(run("Count the .py files here, then "
"summarize naive_loop.py."))
# team_engine.py -- the loop promoted to a
# state machine. One task lifecycle is one
# Session; deterministic code owns every
# transition: producing -> verifying -> done.
from dataclasses import dataclass, field
PRODUCING = "producing"
VERIFYING = "verifying"
DONE = "done"
FAILED = "failed"
@dataclass
class Session:
goal: str
state: str = PRODUCING
attempts: int = 0
artifact: str = ""
reviews: list = field(default_factory=list)
def run_session(s, worker, verifier,
max_retries: int = 3):
while s.state not in (DONE, FAILED):
if s.state == PRODUCING:
s.attempts += 1
s.artifact = worker(
s.goal, s.reviews)
s.state = VERIFYING
elif s.state == VERIFYING:
ok, report = verifier(
s.goal, s.artifact)
s.reviews.append(report)
if ok:
s.state = DONE
elif s.attempts >= max_retries:
s.state = FAILED
else:
# Reject: wake the worker with
# the review log in context.
s.state = PRODUCING
return s
def run_team(goals, worker, verifier):
# Leader's job: split the goal, run the
# sessions (a thread pool in real use),
# then merge N artifacts into 1 result.
done, failed = [], []
for g in goals:
s = run_session(Session(g),
worker, verifier)
if s.state == DONE:
done.append(s.artifact)
else:
failed.append(s.goal)
return done, failed
if __name__ == "__main__":
# Stub roles so the engine runs anywhere;
# swap in LLM calls for the real thing.
def worker(goal, reviews):
v = len(reviews) + 1
return f"draft v{v}: {goal}"
def verifier(goal, artifact):
ok = "v2" in artifact
return ok, f"review {artifact!r}: {ok}"
done, failed = run_team(
["intro", "benchmarks", "faq"],
worker, verifier)
print("delivered:", done)
print("failed:", failed)
# grounded_verifier.py -- evidence over vibes.
# The verdict comes from exit codes and logs,
# never from the model's self-assessment.
import subprocess
import sys
PY = sys.executable
# pytest exit codes: 0 = all passed,
# 1 = failures, 5 = no tests collected
# (acceptable for a docs-only change).
PYTEST_OK = (0, 5)
CHECKS = [
("diff", ["git", "diff", "--stat"], (0,)),
("build", [PY, "-m", "compileall",
"-q", "."], (0,)),
("tests", [PY, "-m", "pytest", "-q",
"--maxfail", "1"], PYTEST_OK),
]
def run_check(name, cmd, ok_codes, cwd):
p = subprocess.run(
cmd, cwd=cwd,
capture_output=True, text=True)
tail = (p.stdout + p.stderr)[-2000:]
return {
"check": name,
"cmd": " ".join(cmd),
"exit_code": p.returncode,
"ok": p.returncode in ok_codes,
"output_tail": tail,
}
def verify(repo: str):
evidence = []
for name, cmd, ok_codes in CHECKS:
e = run_check(name, cmd, ok_codes, repo)
evidence.append(e)
if not e["ok"]:
# Reject with logs attached: the
# worker retries against real
# errors, not "please improve".
return False, evidence
return True, evidence
if __name__ == "__main__":
ok, ev = verify(".")
for e in ev:
print(f"{e['check']:>6} exit "
f"{e['exit_code']} ok={e['ok']}")
print("verdict:", "pass" if ok else "fail")
Чэк-ліст для аператыўнай роботы
Калі працуеце над этапам чэк-ліста для аператыўнай роботы, спачатку запісайце кантракт: неабходныя вхідныя даны, сігнал успеху і тое, што выканаецца у разы частковай неудачы. Гэты чэк-ліст дапамагае заставіць пасляўшыя змены коду быць чыстымі.
Лепшыя маленькія, тэставаныя елементы, чым велікія скрыпты. Калі якісь крок не выйшаў, адказчыкам за гэта павінен быць адзін элемент, а не заплутаны ланцюг задач.
Зробіце контрольную точку пасля дорогіх крокаў. Продакт, які продовжае роботу, не павінен знова ставіць плату за той самы вызов LLM, калі аператар праказвае пазнейшы вузел.
Фіксуйце версіі залежнасцяў і запішыце хэш адобраза, які выканаў дэманстрацыю. Возможнасць перадарабаткі прыважней за традыцыйныя знаёмства.
Спрытывайце гэты этап як кантракт між вхіднымі даннымі і перакананымі выходнымі рэзультатамі. Дайце назвы артыфактам, задаць критэрыя успеху і адмовіцеся ад безсловеснага частковага завершэння.
Зробіце контрольную точку пасля дорогіх крокаў. Продакт, які продовжае роботу, не павінен знова ставіць плату за той самы вызов LLM, калі аператар праказвае пазнейшы вузел.
Перш чым запускать даную систему, заморозьце версіі, зафіксавце критычныя моменты для аналізу і паказвайце крокі з вярнення да пачатковага стану. У спільных средах неабяжна наявнае ліміты на частоту запуска, пераконтроўванні прав на выкорыстанне ресурсаў і чысткая адпаведальнасць за зміну секрэтных даных. Лепш выбіраць простую надзею на надзейнасць, чым хітрыя експерыментальныя дэманстрацыі.
Прыметка для e49728a65412: не кладзіце ключы прадаўцаў у репазітарый, задаце ліміт токена на кожную сесію і зберагачыце фіксаціі дзейнасці рядом з інструментамі для адгукнення, каб пазнейшыя замены модэляў заставаліся пораўнанымі.
Для пункту 0 стадзіі забезпечэння надзейнасці, перш чым зменяць код, неабяжна адзначыце вхідныя даны, адпаведальную особу за выконанне кроку і критэрыя завершэння. Аперацыйныя працавнікі павінны магчымае перзапускаць крок з вядомай точкі контролю, не падозрываючы прыхованы стан системы. Лепш выбіраць маленькія, тэставаныя елементы коду, чым велікія скрыпты. Калі крок не выйшаў, прычына неудачы павінна быць адносна конкрэтной адпаведальнасці, а не сложнай сіткі крокаў.
Дзеянне паўжасткі 0/726: звярніце увагу на час выканання, класы памылак і витрату токенаў для гэтага зьвісткі, а пасля, на аднойчынай базе фіксаванага набору пытанняў, а не на індывідуальных прыкладах, выявіце, чы рэшацца застаўляць змяну.
Калі працуеце над першым этапам зьвісткі паўжасткі, спачатку запісайце контракт: неабходныя даны, сігнал успеху і тое, што выходзіць на частым нявыпанні. Такі список контроля дапамагае заставаць пазнейшыя змяны ў кодзе чыстымі. Запісвайце час выканання і вартасьць токенаў або запыткаў па боку функцыйнаых рэзультаатаў. Відразы вартасцей з самага пачатку запобегае неспакойным рахункам, калі працэс пераходзіць з дэмаверсіі ў спяльныя среды.
Дзеянне паўжасткі 1/726: звярніце увагу на час выканання, класы памылак і витрату токенаў для гэтага зьвісткі, а пасля, на аднойчынай базе фіксаванага набору пытанняў, а не на індывідуальных прыкладах, выявіце, чы рэшацца застаўляць змяну.
Этап 2 прыткага зміцнення работае наяўна, калі яго спрыяваць як вимерную паверхню. Запісаўце адна «золатая» транскрыпцыя, адзін прыклад неудачы і запіс перадвороту, прычым расшырюючы сферу дзеяння. Дакументаваць трэба як шлях успеху, так і шлях вяснавання. Перапрыбуткі, людзкія контралі і обработка некоректных паведамленняў є часткай продукту, а не наступным этапам дапрацоўкі.
Дзеянне прыткага зміцнення 2/726: вимеравайце час выканання, класію памылак і витрату токенав для гэтага запісу, а потым вынікайце, чы рашыцца застаўляць змяну, адпаведна фіксаванаму набору пытанняў, а не лячбовым прыкладам.
Для этапа 3 прыткага зміцнення, перш чым зменяць код, задаце вхідныя даны, адпаведальнага за крок і критэрыя завершэння. Аперацыёныя працавнікі павінны магчымае перазваляць крок з вядомай точкі контролю, не спадзяваючыся на схованы стан. Спрыявайце гэты этап як кантракт між вхіднымі данымі і паўнастацэннымі выходамі. Дайце назвы артыфактам, задаце перакананні на успех і адмовіцеся ад тыхоўскага частковага завершэння.
Дзеянне паўжасткі 3/726: звярніце увагу на час выканання, клас памылкі і колькасць викорыстоўваных токенаў для гэтага зазначэння, а пасля, на аднойчынай сутнасці пытанняў, а не на індывідуальных прыкладах, выявіце, чы хацяце застаўіць змены.
Працюючы над 4-й стадзіяю зазначэння паўжасткі, спачатку запісайце контракт: неабходныя даны, сігнал успеху і тое, што выканаецца у разе частковай памылкі. Такі список контроля дапамагае заставіць пасляэтапныя змены ў кодзе чыстымі. Зберагаюце канфігурацыю праза код аплікацыі. Файлы сяродавысці, хранільнікі секрэтных дадзеных і флагі функцыйяў должны знаходзіцца ў аднам месцы, якое аператары можаць пераглядаць без неабяжнага чытання всей структуры.
Дзеянне паўжасткі 4/726: звярніце увагу на час выканання, клас памылкі і колькасць викорыстоўваных токенаў для гэтага зазначэння, а пасля, на аднойчынай сутнасці пытанняў, а не на індывідуальных прыкладах, выявіце, чы хацяце застаўіць змены.
Этап 5 прынцыпа зміцнення работае наяўна, калі яго розглядаць як вимерную паверхню. Запісаўце адна «золатая» транскрыпцыя, адин прыклад неудачы і запіс перадвороту рэшэнняя пры расширэнні масштаба. Валіце маленькія, тэставаныя елементы замест большых скрыптов. Калі якісьць крок не выйшла, прычына неудачы павінна вказываць на адную адпаведальнасць, а не на заплутаны ланцюг задач.
Дакладнасць прынцыпа зміцнення 5/726: вимеравайце час выканання, класію памылак і колькасць выкорыстоўваных токенав для гэтага запісу, а пасля рашыце, чы хацяце застаўіць змяну, стварыўшы фіксаваны набор пытанняў, а не спакойнае аналізаванне.
Для 6-й стадзіі процэсу змяржвання неабяжна ўскладнення: перш чым зменіць код, неабяжна визначыць параметры вводу, адпаведальнага за даную стадзію і крэтыры завершэння. Аператары должны магчымаць перзапуск стадзіі з вядомай точкі контролю, не прабуючы спадарожваць схованы стан системы. Неабяжна фіксаваць час выканання, а таксама вартасць токенаў чы запытанняў праза рэзультаты функцыйнасці. Відразліва візуалізацыя вартасцей запобегае неспакоўным рашчыткам, калі працэс пераходзіць з дэмовай среды ў спакульную.
Дзеянне змяржвання 6/726: неабяжна змерыць час выканання, класі каштоўкаў і вартасць токенаў для данай стадзіі, а пасля — на базе фіксаванага набору пытанняў, а не індывідуальных спазырэнняў, вырашыць, чы застаўляць змены.
Калі працуеце над 7-й стадзіяю прыемкі з паўнейшага захавання, спачатку запісайце угоду: неабходныя даны, сігнал успеху і тое, што выходзіць на падчасныя неудачы. Такі чарт дапамагае залічваць пазнейшыя змены ў кодзе чыста.
Документавайце як шлях успеху, так і шлях вярнення да нормальнага стану. Перапрыбуткі, людзкія контралі і обработка некоректных паведамленняў є частью продукту, а не пазнейшым дапрацоўкам.
Дзялей 7/726 прыемкі з паўнейшага захавання: вымерайце час выконання, класію памылак і колькасць выкорыстоўваных токенав для гэтай прыемкі, а пасля выберайце, чы робіць змену на адной пазначанай базе пытанняў, а не на адной лічбе прыкладаў.
7-я стадзія прыемкі з паўнейшага захавання работае лепей, калі яе спрыямаць як вымерную плошчу. Запісайце адну ідеальную транскрыпцыю, адзін прыклад неудачы і запіс пра вярненне да пачатковага стану, перш чым расширваць масштабы.
Спрыяйце гэтай стадзіі як угоды межа данымі і перакананымі выходамі. Дайце назвы артыфактам, задаць критэрыяі успеху і не падтрымайце тыхню частковую завершэння.
Дзеянне паўжасткі 8/726: звярніце увагу на час выканання, класы памылак і витрату токенаў для гэтага запісу, а пасля, на аднойчынай базе фіксаванага набору пытанняў, а не на індывідуальных прыкладах, выявіце, чы рашыцца застаўіць змяну.
Для 9-го этапа паўжасткі неабходна перад змянай коду адзначыць вхідныя даны, адпаведальнага за крок і критэрыя завершэння. Аператары должны магчымае перадзвігнуць крок з вядомага пункта контролю, не спрабоўваючы здагадвацца пра схованы стан. Канфігурацыю трэба залічыць праз аплявацыйны код; файлы сераўіса, хранілішча секрэтных дадзенняў і флагі функцыйяй должны знаходзіцца ў аднам месцы, якое аператары можаць пераглядаць, не чытаючы весь код.
Дзеянне паўжасткі 9/726: звярніце увагу на час выканання, класы памылак і витрату токенаў для гэтага запісу, а пасля, на аднойчынай базе фіксаванага набору пытанняў, а не на індывідуальных прыкладах, выявіце, чы рашыцца застаўіць змяну.
Калі працуеце над 10-ю стадзіяй ударожэння, спачатку запісайце шаблон кантракта: неабяжныя вхідныя даны, сігнал успеху і тое, што выходзіць у разе частковага нявыпання. Такі список контроля дапамагае залічыць пазнейшыя змены ў кодзе адкрыта і прозрачна. Валіце маленькія, тэставаныя елементы замест вялікіх скрыптав. Калі якась стадзія не выйшла, прычына нявыпання павінна вказваць на адную адпаведальнасць, а не на заплутаны ланцужок задач.
Дзеянні ўдарожэння 10/726: звярніце увагу на час выканання, класы каштоўкаў і витрату токенаў для гэтай стадзіі, а пасля вырашыце, чы робіць змену на адной пазначанай базе пытанняў, а не на адной лічбе.