Практычныя прытамкі: Harness Engineering: The Naked Agent: Чаму ваша палатка керуе
Практычныя прыказкі: Harness Engineering: The Naked Agent – чаму ваша палатка прыемліе контракты, перакрыццяі та слоты для коду для команд, якія выкарыстоўваюць гэты шаблон.
Існавайце гэта як пераклад ідэй з кнігі “Harness Engineering: The Naked Agent: Why Your Framework Hands You a Loop, Not a Harness — I” для аператараў: чыстыя этапы, аранжаваныя блакіты коду і прыметкі па вяснаванню, якія застаюцца пасля перадачы.
Частка 1: Проста петля агента здаецца моцной, пакуль да яго не дасяў рэальны трафік. У гэтым секрет, чаму збоі ў працы зазвычай выходзяць з нехваткі “ Harness-а” абоўшчы модэлю, а не з самога модэля.
У частцы 1 просты этап работае найкраща, калі яго спрыяваць як вимерную паверхню. Запісайце адна ідеальная транскрыпцыю, адзін прыклад збою і прыметкі па вяснаванню перад тым, як расшырваць масштабы. Дакументавайце як успішны, так і патовы шляхі. Перапрыбуткі, людзкія контрольны пункты і обработка некоректных паведамленняў є частью продукту, а не чымсь, што дадаецца пазней. Запланавайце колькість токеноў на кожны раунд і на кожную сесію. Інструменты агента актыўна расшырваюць контэкст; жорсткія ліміты не дазволяюць дэманстрацыям ператварыцца на неспакоюючыя рахункі.
Большая частка неудач агентаў не ў збое модэлю. Яны вынікаюць з нехваткі правільна організаванага слоя дысцыпліны навакола яго. Цікава картына таго, як выглядае AI-агент без адпаведных механізмаў керування ў Claude Agent SDK і LangChain Deep Agents, а таксама тры конкрэтныя спосабы, якімі ён зламваецца пад рэальным навантажэнням.
Найбольш эфектываў спосаб борьбы з неудачамі агентаў — цэе расследаванне іх як мерыябельных падазроў. Запісаце адну ідеальную транскрыпцыю, адзін прыклад неудачы і прыметкі па поверненню да попярэдньега стану прычым расшырэнню масштаба. Валіце за малыя, тэставаныя елементы замест большых скрыптов. Калі якісьць крок зламваецца, неудача должна вказываць на адну конкрэтную адпаведальнасць, а не на заплутаны ланцюг задач. Задаце ліміт токенав на кожны раунд і на кожную сесію. Інструменты агентаў актыўна расширваюць контэкст; жорсткія ліміты запобегаюць таму, каб дэманстрацыі ператварыліся на неспакоючыя рахункі.
Модэль не ў якості зменнай
Модэль працюе найкраща, калі яе розглядаць як вимерную паверхню. Запісаўце адна «золатая» транскрыпцыя, адзін прыклад неудачы і запіс пра вярнэнне да пачатковага стану перш чым расширваць масштабы. Разглядзіце гэты этап як кантракт межа вхіднымі даннымі і паверыранымі выходамі. Даўце назвы артыфактам, задаце критэрыя успеху і не падтрымвайце тыхія частковыя завершэння. Задаце бюджет токенав на кожны рунг і на кожную сесію. Агентныя інструменты агрэсывна расширваюць контекст; строгі ліміты не дазволяюць дэмам ператварыцца на неспакоўныя рахункі.
Што на самай працо значыць «голы»
«The What naked» на самай лепшы спосаб працюе, калі яго розглядаць як вимерную паверхню. Запісаўце адна «золатая» транскрыпцыя, адзін прыклад неудачы і запіс пра вярнэнне да пачатковага стану перш чым расширваць масштабы. Запісвайце часы выканання і косты токеноў або запытак праза функцыйнае рэзультат. Відкрытыя данні пра косты з самага пачатку запобегаюць неспакоўным рахункам, калі процес пераходзіць з дэмовай среды ў спакульную.
import anthropic
client = anthropic.Anthropic() # reads ANTHROPIC_API_KEY
TOOLS = [
{"name": "search_flights",
"description": "Search flights between two cities for a date.",
"input_schema": {"type": "object", "properties": {
"origin": {"type": "string"}, "destination": {"type": "string"},
"date": {"type": "string", "description": "YYYY-MM-DD"}},
"required": ["origin", "destination", "date"]}},
{"name": "book_flight",
"description": "Book a specific flight.",
"input_schema": {"type": "object", "properties": {
"flight_id": {"type": "string"}, "passenger_name": {"type": "string"}},
"required": ["flight_id", "passenger_name"]}},
]
def run_naked(user_msg: str) -> str:
messages = [{"role": "user", "content": user_msg}]
while True: # ① no iteration cap
resp = client.messages.create(
model="claude-sonnet-4-6", max_tokens=1024,
tools=TOOLS, messages=messages,
)
if resp.stop_reason != "tool_use":
return resp.content[0].text
call = next(b for b in resp.content if b.type == "tool_use")
result = dispatch(call.name, call.input)
# ② direct side effect, no check
messages.extend([
# ③ whole history, every turn
{"role": "assistant", "content": resp.content},
{"role": "user", "content": [{"type": "tool_result",
"tool_use_id": call.id, "content": result}]},
])
Агент «The naked» у Claude Agent SDK
Агент «The Naked Agent» у стадії розработкі працюе найэфективней, калі яго расследжваць як мерыемую поверхню. Зберагчыце адны ідеальны прыклад роботы, адны прыклад неудачі і запіс пра відкатанне перш чым расширваць сферу дзеяння. Хавайце конфігурацыю параду ад коду прыкладнага програмы. Файлы сераўіса, хранільнікі секрэтных дадзеных і пазнакі функцый калічуцца ў адным месцы, дзе аператары можаць аудытуваць іх без неабяжнага чытання всіх дадзеных. Актуалізуйце інструменты з вузкімі схемамі та чысткімі пазнакамі пабочных эфектаў. Хосты должны знать, якія вызовы мутуюць стан, перш чым автаматычна схваліць іх. Агент «The Naked Agent» у стадії розработкі працюе найэфективней, калі яго расследжваць як мерыемую поверхню. Зберагчыце адны ідеальны прыклад роботы, адны прыклад неудачі і запіс пра відкатанне перш чым расширваць сферу дзеяння. Валіце малыя, тэставаныя елементы замест большых скрыптов. Калі якісь крок не выйшае, прычына неудачы должна вказываць на адну адпаведную відпаведальнасць, а не на заплутаны процес.
import asyncio
from claude_agent_sdk import (
query, ClaudeAgentOptions, tool,
create_sdk_mcp_server, AssistantMessage, ResultMessage,
)
@tool("search_flights", "Search flights between two cities for a date.",
{"origin": str, "destination": str, "date": str})
async def search_flights(args):
# ① no check that date exists
hits = flights_api.search(**args)
return {"content": [{"type": "text", "text": str(hits)}]}
@tool("book_flight", "Book a specific flight.",
{"flight_id": str, "passenger_name": str})
async def book_flight(args):
# ② destructive, ungated
confirmation = flights_api.book(**args)
return {"content": [{"type": "text", "text": confirmation}]}
server = create_sdk_mcp_server("travel", tools=[search_flights, book_flight])
async def main():
options = ClaudeAgentOptions(
mcp_servers={"travel": server},
allowed_tools=["mcp__travel__search_flights",
"mcp__travel__book_flight"],
)
async for msg in query(prompt="Rebook this customer for March 32nd.",
options=options):
if isinstance(msg, AssistantMessage):
for b in msg.content:
if hasattr(b, "text"):
print(b.text)
elif isinstance(msg, ResultMessage):
print("done:", msg.subtype)
# ③ no state survives this run
Агент «The Naked Agent» у LangChain Deep Agents
Для етапу «Голы ўпраўлівач на сцэне» неабходна пазначыць вхідныя даны, абавесця крока і критэрыі завершэння пры змяне коду. Аперацыйныя працавнікі должны магчымае перзапускаць крок з вядомай точкі контролю, не падозрываючы прыхованы стан. Спрыяйце цэму етапу як кантракту межа вхіднымі данымі і перакананымі выходнымі рэзультатамі. Даўце назвы артыфактам, пазначыце перакананні успеху і адмовіцеся ад тыхняга частковага завершэння без паведамлення. Автентыфікуйцеся на воратах і паўторна автарызавайцеся на роўні дадзенняў. Толькі токэн-носіцель не є межай арендаванага ресурсу.
from langchain.tools import tool
from deepagents import create_deep_agent
@tool
def search_flights(origin: str, destination: str, date: str) -> str:
"""Search flights between two cities for a date (YYYY-MM-DD)."""
return str(flights_api.search(origin, destination, date))
# ① no date check
@tool
def book_flight(flight_id: str, passenger_name: str) -> str:
"""Book a specific flight."""
return flights_api.book(flight_id, passenger_name)
# ② ungated side effect
agent = create_deep_agent(
# ③ the loop, no controls
model="anthropic:claude-sonnet-4-6",
tools=[search_flights, book_flight],
)
result = agent.invoke({"messages": [{"role": "user",
"content": "Rebook this customer for March 32nd."}]})
print(result["messages"][-1].content)
# Ask a follow-up in a second invoke, and it starts from zero: no thread,
# no memory.
Пазірце, як гэта можа зламацца трохіма спосабамі
Для стежэння за процесам іх розбіваюць на тры стадіі: паведамляецца інфармацыя пра вхідныя даны, адміністратар стадіі і крэтэрыя завершэння, прычым перад змінайом коду. Аператары должны магчымаць перзапуск стадіі з вядомай точкі контролю, не прабуючы спадарожваць схованы стан. Запісвайце час выконання і вартасць токена або запыту праз сумарак функцыйнальных рэзултатаў. Відразы вартасці з самага пачатку запобегае неспакоўным рахункам, калі процес пераходзіць з дэмовай среды ў спакульную. Автентыфікуйцеся на воратах і паўторна автарызуйцеся на роўні дадзеных. Сам токен-носіцель не є межай арендаванага прыемку.
Працоўная нясправа 1: некоректны аргумент падае ў разрушальны вызов
Для ситуацыі «Працоўнай нясправнасці 1: аблыжаная стадзія» неабходна перад зменым коду задаць вхідныя даны, адпаведальнага за крок і крэтыяры завершэння. Аператары должны магчымае перайсці на выкананне кроку з вядомага пункта контролю, не спрабоўваючы здогадвацца пра схованы стан. Конфігурацыю трэба знаходзіць за межамі коду прыкладнення. Файлы сераўіса, хранальнікі секрэтных данных і флагі функцыйяў должны быць у аднам месца, якое аператары можаць пераглядаць, не чытаяўшы весь ланцуг задач. Аутентыфікацыя павінна выконвацца на воратах, а пераправенне прав на выканання — у роўні дадзэнняў. Сам токен-носіцель не є межай адпаведальнасці. Для ситуацыі «Працоўнай нясправнасці 1: аблыжаная стадзія» неабходна перад зменым коду задаць вхідныя даны, адпаведальнага за крок і крэтыяры завершэння. Аператары должны магчымае перайсці на выкананне кроку з вядомага пункта контролю, не спрабоўваючы здагадвацца пра схованы стан. Валідзіце маленькія, тэставаныя елементы замест большых скрыптов. Калі крок не выканаўся, прычына нясправнасці павінна вказываць на адну конкрэтную адпаведальнасць, а не на заплутаны ланцуг задач.
book_flight(flight_id=”AC-PHANTOM”, passenger_name=”J. Moffatt”)
# -> “Booked.” The action fired. Nothing in the loop asked whether it should.
Няўдача 2: контэкст выходзіць з-пад кантролю, а якасць тыха падупала
Калі працуеце з стадіяй, калі контэкст выходзіць з-пад кантролю ў рамках Няўдачы 2, спачатку запісайце угоду: неабходныя даны, сигнал успеху і тое, што выканаецца пад час частковай няўдачы. Такі список пераканае вас робіць чыстыя змены ў кодзе пазней. Спрэчвайце гэтую стадію як угоду межа данымі і перакананымі выходамі. Дайце назвы элементам, задаць правіла пераканання успеху і адмовіцеся ад тыхой частковай узавершэння. Запісвайце назву інструмента, хэш параметраў, час адклікання і рынак кожнага вызову. Без такога следу дэбаггінгавы агент траціць гадзіны на безрезультатныя прабыткі.
Няўдача 3: інструмент даў памылку, але агент задаў весткі пра успех
Калі працуеце над этапам з інструментамі, связанымі з адзінам з трох працоўных станоў, спачатку запісайце умовы викорыстоўвання: неабходныя даны, сігнал успеху і тое, што выканаецца у разе частковага абякання. Такі список контроля дапамагае залічыцца з пазнейшымі змянамі ў кодзе. Запісвайце час выканання і кост токена або запыту праза функцыйнае рэзультат. Відразлівасць костаў з самага пачатку запобегае неспакойным рахункам, калі процес пераходзіць з дэмаверсіі ў спяльныя среды. Запішвайце назву інструмента, хэш аргументаў, час затрымкі і рэзультат кожнага вызову. Без такога лёгкага следу дэбагаванне агента займае гадзіны.
Формат, якога будзе дазволена кожная частка
Калі працуеце над стадзіяй «Форма кожнай часткі», спачатку запісуйце контракт: неабяжлівыя даны, сигнал успеху і тое, што выходзіць у разе частковага абякання. Такій чарт дапамагае залічыць пазнейшыя змены ў кодзе.
Зрабіце гэта сёнь
Этап «Зрабейце гэта сёньдзе» работае наяўней, калі яго спрыяваць як мерыемую паверхню. Запісаце адна ідеальная версія рэзультата, адин прыклад неудачы і прыметку па вярнэнню да пачатковага стану, прычым расшырюючы масштабы задання. Спрыяйце гэтым этапам як кантракту межа вхіднымі даннымі і перакананымі выходнымі рэзультатамі. Даўце назвы всім элементам, задаце критэрыя успеху і не падтрымайце тыхню частковую узавершэннае. Адкройце інструменты з вузкімі схемамі та чысткімі пазначэннямі побачных наследкаў. Адпаведальныя за эксплуатацыю должны знать, якія вызовы мутуюць стан, прычым автаматычна не падтрымаць іх.
Модэль — гэта простая частка
Модэль працюе найкраща, калі яе розглядаць як вимерную паверхню. Запісаце адны прыклад успеху, адны прыклад неудачы і прыметку па вярнэнню да пачатковага стану пры розширэнні масштаба. Запісвайце часы выконання і кост токэнаў або запытаў разам з функцыйнальнымі рэзультатамі. Відразлівая візуабельнасць костаў з самага пачатку запобегае неспакою з боку расчыткаў, калі процес пераходзіць з дэмавай версіі ў спяльныя сераўы. Задазвайце бюджет токэнаў на кожны раунд і на кожную сесію. Інструменты-агенты агрэсывна расширваюць контекст; строгі ліміты не дазволяюць дэмавай версіям ператварыцца на неспакойныя рахункі.
Чэрніцца кантролю эксплуатацыі
Калі працуеце над стадзіяй чэрніцкі кантролю эксплуатацыі, спачатку запісайце умовы кантракту: неабходныя данні, сігнал успеху і тое, што выканаецца у разы частковай неудачы. Гэтая чэрніцка прытрымвае пазнейшыя змены коду да правды.
Дасведчывайце як шлях успеху, так і шлях вярнэння да нормальнага стану. Перапрыбуткі, людзкія контрольныя пункты і обработка неканальных паведамленняў є часткай продукту, а не чымсь, што дадаецца пазней.
Зявіце назву інструмента логавання, хэш аргументаў, час затрымкі і рынак кожнага вызову. Дэбагаванне без такога следу адзначае гады часу.
Зберагайце стан графа ў простам і типаваным формате. Вярнутыя структуры маскуюць, який вузел запісаў кожны поле, і спакоююць працэс пасля перарываў.
Калі дозволяе бюджет, дадзіце тэст на працэс критычнага шляху ў CI з фікстурамі, а не за дапамогою рэальных платных API.
Зявіце данні пра часы і кост токенаў або запытаў разам з функцыйнальнымі рынакамі. Візуабельнасць костаў з самага пачатку запобегае неспакойным рахункам, калі шлях пераходзіць з дэмаверсіі ў спакоюваныя среды.
Перш чым пераходзіць да болей складных рашэнняў, заморозьце версіі, зафіксуйце ідеальны транскрыпт критычнага шляху і паказваце способы адворачэння. У спакоюваных средах неабходны ліміты частоты запытаў, перакананні ў правах на выкарыстоўванне і чысткі власнік для змены секрэтных даных. Валіце простую надзейнасць працэсу пра крэатыўныя, але разовыя дэмаверсіі.
Запіскі для пакета 765280e2df21: не класты ключі прадаўцоў у репазітарыю, задаць максымальны ліміт токена на сесію, а таксама зберагчы транскрыпціі праза фіксатуры для ацэнкі, каб пазнейшыя замены моделяў заставаліся порównаннэй.