Практычныя прытамулі: як функцыонуе MCP: дэтальны аналіз з кодам
Практычныя прыказкі: Как функцыонуе MCP: Дзейная аналіза з кодам – кантракты, перакрыцця та слоты для коду для команд, якія викорыстоўваюць гэты патэрн.
У гэтым карыце парадоксальна дорага ад сыр'ёў да рабочай системы для: «Як працюе MCP: Дзейнае дакладнае аналізаванне з кодам». Акцэнт ставяцца на практычныя крокі, чыстае перакананне і код, які можна проста дадаць у репазітарый без неабяснення меты. У стадзіі агляду неабяжна з'явіць вхідныя даны, адпаведальнага за крок і критэрыя завершэння прычым перад зменай коду. Аперацыйныя працавнікі павінны магчымае перадзягаць крок з вядомай точкі контролю без неабяснення схованага стану. Запісваюць час выконання і кост токенаў або запытаў разам з функцыйнальнымі рэзултатамі. Відразувыя даны пра косты запобегаюць неспадзеваным рахункам, калі дорага пераходзіць з дэмаверсіі ў спяльныя среды.
{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/list",
"params": {}
}
{
"jsonrpc": "2.0",
"id": 1,
"result": {
"tools": [
{
"name": "search_web",
"description": "Search the web for a given query",
"inputSchema": {
"type": "object",
"properties": {
"query": { "type": "string" }
},
"required": ["query"]
}
}
]
}
}
{
"jsonrpc": "2.0",
"id": 2,
"method": "tools/call",
"params": {
"name": "search_web",
"arguments": {
"query": "latest news on MCP protocol"
}
}
}
{
"jsonrpc": "2.0",
"id": 2,
"result": {
"content": [
{
"type": "text",
"text": "Anthropic released MCP in Nov 2024 as an open standard..."
}
]
}
}
Што такое FastMCP?
Калі працюеце над этапам «Што такое FastMCP», спачатку запісайце умовы вярбунка: неабяжлівыя данні, сігнал успеху і тое, што выходзіць у случае частковага нявыпання. Такі список дапамагае заліцьварыць пазнейшыя змены ў кодзе. Зберагаюце настройкі паза кодам прыемліка. Файлы сераўнавання, хранільнікі секрэтных дадзеных і флагі функцыйяў должны знаходзіцца ў аднам месцы, куды аператары можаюць адбавіць аудыт без неабяжлівага чытання всей структуры. Запісвайце назву інструмента, хэш аргументаў, час затрымкі і рынак кожнага вызову. Без такога лёгкага следу час на дэбагаванне агента, які цягнёцца бесканечна, губіцца на гады.
from fastmcp import FastMCP
mcp = FastMCP("My Server") # creates the server
@mcp.tool() # registers the function as an MCP tool
def add(a: float, b: float) -> float:
"""Add two numbers.""" # docstring → tool description sent to the LLM
return a + b # type hints → JSON Schema sent to the LLM
mcp.run() # starts the stdio message loop
Тры прымітывы MCP
Калі працуеце над стадзіяй «Тры MCP прымітывы», спачатку запісайце умовы викорыстання: неабяжлівыя даннэ, сігнал успеху і тое, што выканаецца у разе частковага нявыполнення. Такі список дапамагае заліцварыць пазнейшыя змены ў кодзе. Документавайце як шлях успеху, так і шлях вярнення да нормальнага стану. Перапрыбуткі, людзкія контрольныя пункты і обработка некоректных паведамленняў є частью продукту, а не елементамі пазнейшай дапрацоўкі. Зявляйце логі з назвай інструмента, хэшам параметраў, часам адклікання і рэзультатам кожнага вызову. Без такога следу дэбаггінг агента губіць гадзіны часу.
# servers/math_server.py
@mcp.tool()
def divide(a: float, b: float) -> float:
"""Divide a by b. Raises an error if b is zero."""
if b == 0:
raise ValueError("Cannot divide by zero")
return a / b
# servers/math_server.py
@mcp.resource("math://constants")
def get_math_constants() -> str:
"""Common mathematical constants."""
return f"π = {math.pi}\n e = {math.e}\n ..."
@mcp.resource("math://formulas/{category}")
def get_formulas(category: str) -> str:
"""Retrieve mathematical formulas by category (geometry | algebra | statistics)."""
catalog = {
"geometry": (
"Geometry Formulas:\n"
" Circle area: A = π × r²\n"
" Circle circumference: C = 2π × r\n"
" Rectangle area: A = length × width\n"
" Triangle area: A = (base × height) / 2\n"
" Sphere volume: V = (4/3) × π × r³\n"
),
"algebra": (
"Algebra Formulas:\n"
" Quadratic formula: x = (−b ± √(b²−4ac)) / 2a\n"
" Difference of squares: a²−b² = (a+b)(a−b)\n"
" Perfect square: (a+b)² = a²+2ab+b²\n"
" Sum of arithmetic seq: S = n(a₁+aₙ)/2\n"
),
"statistics": (
"Statistics Formulas:\n"
" Mean: μ = Σx / n\n"
" Variance: σ² = Σ(x−μ)² / n\n"
" Std Dev: σ = √(Σ(x−μ)² / n)\n"
" Z-score: z = (x−μ) / σ\n"
),
}
return catalog.get(
category,
f"Unknown category '{category}'. Available: geometry, algebra, statistics",
)
# servers/math_server.py
@mcp.prompt()
def math_tutor(difficulty: str = "intermediate") -> str:
return (
f"You are an expert math tutor for {difficulty}-level students. "
"Break every problem into numbered steps..."
)
Падсумак сервера
Калі працуеце над стадзіяй падсумавання сервера, спачатку запішыце умовы контракту: неабяжлівыя даны, сігнал успеху і тое, што выходзіць у разе частковага нявыпання. Такі список контроля дапамагае заліцьварыць пазнейшыя змены ў кодзе. Валіце маленькія, тэставаныя елементы замест большых скрыптов. Калі якісь крок не выйшае, прычына нявыпання павінна вказываць на адну конкрэтную адпаведальнасць, а не на заплутаны ланцюг задач. Запішыце назву інструмента, хэш аргументаў, час затрымкі і рынак кожнага вызову. Без такога следу дэбагаванне агента губіць гадзіны.
З точкі зору кліента
Калі працюеце на стадыі «З баку кліента», спачатку запісайце угоду: неабяжлівыя даны, сігнал успеху і тое, што выходзіць у разе частковага нявыпання. Такі список перакладзець пазнейшыя змены коду ў правільны направленні. Спрытывайце гэты стадыю як угоду межа данымі і перакананымі рэзультатамі. Даўце назвы элементам, задайце критэрыя успеху і не прымайце частковае завершэння без паведамлення. Зявляйце логі з назвай інструмента, хэшам параметраў, часам адклікання і рэзультатам кожнага вызову. Без такога следу дэбаггінгавы агент траціць гадзіны на безрезультатныя прабыткі.
You type a query
│
▼
main.py ← entry point, parses args, kicks off async loop
│
▼
client/agent.py ← spawns 3 MCP servers, builds the agent, invokes it
│ │
│ ▼
│ utils/tracker.py ← fires on every LLM call, tool call, and result
│
▼
LangGraph ReAct loop ← think → call tool → observe → repeat
│
▼
servers/{math,text,data}_server.py ← each runs as an isolated subprocess
Шаг 1 — точка входу
Калі вы працуеце над першым крокам, тэперы ў стадіі прадзеяў, спачатку запісайце контракт: неабходныя даны, сігнал успеху і тое, што выходзіць пад час частковага невыпання. Такі список пераканальвае застаўляцца чыстасцю пазнейшых змян у кодзе. Запісвайце часы выканання і кост токена або запиту праза функцыональныя рэзультаты. Відразлівасць костаў з самага пачатку запобегае неспакою, калі праця пераходзіць з дэмаверсіі ў спакульнаныя сераўсы. Запісвайце назву інструмента, хэш аргументаў, час затрымкі і рэзультат кожнага вызову. Без такога лёгкага следу дэбагаванне агента займае гадзіны.
async def _run(queries: list) -> None:
from client.agent import run_query # imported here (late) to keep startup fast
for i, q in enumerate(queries):
await run_query(q)
def main() -> None:
...
asyncio.run(_run(queries))
Generate 8 random numbers between 5 and 50 using seed=42,
then calculate their statistics, and tell me if there are any outliers.
python3 main.py --query "Generate 8 random numbers between 5 and 50 using seed=42, \
then calculate their statistics, and tell me if there are any outliers."
╭────────────────────────────── 🔌 MCP Example ───────────────────────────────╮
│ Multi-Server MCP Demo │
│ │
│ Three FastMCP servers, each exposing tools + resources + prompts: │
│ ● Math Server — add, subtract, multiply, divide, power, sqrt, │
│ percentage │
│ ● Text Server — count_words, word_frequency, reverse, transform, │
│ extract_emails │
│ ● Data Server — generate_numbers, calculate_statistics, find_outliers, │
│ normalise │
│ │
│ Stack : FastMCP · LangChain · LangGraph · OpenAI · Rich │
│ Track : live Rich panels + JSONL log files under logs/ │
╰──────────────────────────────────────────────────────────────────────────────╯
Крок 2 — Стварэнне агента
Калі працуеце над 2-м крокам, якім ёсь стварэнне сцэны, спачатку запішыце контракт: неабяжлівыя даннэ, сігнал успеху і тое, што выходзіць у разе частковага нявыпання. Такі список пераконтроўвае чыстасць пазнейшых змян у кодзе. Зберагаюце настройкі праза код аплікацыі. Файлы сераўнавання, храненні секрэтных данных і флагі функцыйяў должны знаходзіцца ў аднам месцы, куды аператары можаць адбавіць аудыт без неабяжлівага чытання всей структуры. Запішыце назву інструмента, хэш аргументаў, час затрымкі і рынак кожнага вызову. Без такога лёгкага следу дэбагаванне агента займае гадзіны.
log_file = str(LOGS_DIR / f"run_{int(time.time())}.jsonl")
tracker = MCPTracker(log_file=log_file)
╭──── 💬 USER QUERY ────╮
│ Generate 8 random... │
╰────────────────────────╯
def _server_config() -> Dict[str, Any]:
silent_env = {**os.environ, "FASTMCP_LOG_LEVEL": "ERROR"}
return {
"math_server": {
"command": sys.executable,
"args": ["servers/math_server.py"],
"transport": "stdio",
"env": silent_env,
},
"text_server": { ... },
"data_server": { ... },
}
client = MultiServerMCPClient(_server_config())
tools = await client.get_tools()
Connected to 3 servers (math_server, text_server, data_server) with 19 tools: add, subtract, multiply,
divide, power, square_root, calculate_percentage, count_words, word_frequency, reverse_text,
transform_case, find_and_replace, extract_emails, count_vowels_consonants, generate_numbers,
calculate_statistics, find_outliers, sort_values, normalize_values
model = ChatOpenAI(model=model_name, temperature=0)
agent = create_react_agent(model, tools)
START
│
▼
[call_model] ─── no tool call ──▶ END
│
tool call requested
│
▼
[call_tools]
│
▼
[call_model] (loop again with tool result in context)
config = {"callbacks": [tracker]}
result = await agent.ainvoke({"messages": [("human", query)]}, config=config)
3-й крок — Следзіце за всім у рэальны час
Калі вы працуеце над этапам 3 «Адзірванне всьго», спачатку запісайце умовы дагавароту: неабяжлівыя даны, сігнал успеху і тое, што выходзіць у случае частковага нявыпання. Такі список контролю дапамагае заліцьварыць пазнейшыя змены ў кодзе. Дакументавайце як шлях успеху, так і шлях вярнення. Перапрыбуткі, людзкіе перакрыцця і обробка некоректных паведамленняў ёсць частью продукту, а не пазнейшым дапрацоўкам. Зявляйце логі з назвай інструмента, хэшам аргументаў, часам затрымкі і рэзультатам кожнага вызову. Без такога следу дэбагаванне агента займае гадзіны.
agent.ainvoke() called
│
├─▶ on_chain_start() "▶ AGENT STARTED" panel
│
├─▶ on_chat_model_start() "🤖 LLM CALL #1" panel (timer starts)
├─▶ on_llm_end() "LLM responded ⏱ 1.23s → will call: add, multiply"
│
├─▶ on_tool_start() "🔧 TOOL CALL #1" panel (timer starts)
├─▶ on_tool_end() "✓ TOOL RESULT ⏱ 0.01s" panel
│
├─▶ on_tool_start() (second tool, if any)
├─▶ on_tool_end()
│
├─▶ on_chat_model_start() "🤖 LLM CALL #2" (LLM synthesises final answer)
├─▶ on_llm_end() no tools this time → loop ends
│
└─▶ agent.ainvoke() returns
TOOL_SERVER_MAP = {
"add": "math_server",
"count_words": "text_server",
"generate_numbers": "data_server",
...
}
SERVER_COLORS = {
"math_server": "cyan",
"text_server": "green",
"data_server": "yellow",
}
── 🤖 LLM CALL #1 model=gpt-5-mini messages=1 ──╮
│ Role Content preview │
│ Human Generate 8 random numbers between 5 and 50… │
╰──────────────────────────────────────────────────────╯
LLM responded ⏱ 5.35s → will call: generate_numbers
{
"name": "generate_numbers",
"arguments": {"count": 8, "min_val": 5, "max_val": 50, "seed": 42}
}
╭── 🔧 TOOL CALL #1 ──────────────────╮
│ Tool : generate_numbers │
│ Server: data_server │
│ Args : │
│ {'count': 8, 'min_val': 5, │
│ 'max_val': 50, 'seed': 42} │
╰───────────────────────────────────────╯
{"method": "tools/call", "params": {"name": "generate_numbers",
"arguments": {"count": 8, "min_val": 5, "max_val": 50, "seed": 42}}}
╭── ✓ TOOL RESULT ⏱ 0.63s ────────────────────────────╮
│ [33.77, 6.13, 17.38, 15.04, 38.14, 35.45, 45.15, 8.91] │
╰──────────────────────────────────────────────────────────╯
random.seed(42)
return [round(random.uniform(5, 50), 2) for _ in range(8)]
# → [33.77, 6.13, 17.38, 15.04, 38.14, 35.45, 45.15, 8.91]
╭── 🤖 LLM CALL #2 model=gpt-5-mini messages=3 ──╮
│ Role Content preview │
│ Human Generate 8 random numbers… │
│ AI (the tool-call decision) │
│ Tool [33.77, 6.13, 17.38, ...] │
╰──────────────────────────────────────────────────────╯
Tool : calculate_statistics
Server: data_server
Args : {'numbers': [33.77, 6.13, 17.38, 15.04, 38.14, 35.45, 45.15, 8.91]}
Result: {"count":8, "min":6.13, "max":45.15, "mean":24.9962,
"median":25.575, "std_dev":14.8181, "variance":219.5755,
"range":39.02, "q1":15.04, "q3":38.14}
Tool : find_outliers
Server: data_server
Args : {'numbers': [...], 'threshold': 2}
Result: {"outliers": [], "outlier_count": 0,
"total_checked": 8, "mean": 24.9962, "std_dev": 14.8181}
╭── 🤖 LLM CALL #4 messages=7 ──╮
│ Human / AI / Tool │
│ AI / Tool │
│ AI / Tool │
╰───────────────────────────────────╯
LLM responded ⏱ 30.25s
╭── ✅ FINAL ANSWER ───────────────────────────────╮
│ Random numbers: [33.77, 6.13, 17.38, ...] │
│ Mean: 24.9962 / Median: 25.575 / Std Dev: 14.8181│
│ Outliers: none (all |z| < 2) │
╰───────────────────────────────────────────────────╯
╭─────────────────────────────────────────────────────╮
│ LLM Calls 4 │
│ Tool Calls 3 │
│ Total Time 42.25s │
│ Log File logs/run_1776864980.jsonl │
╰─────────────────────────────────────────────────────╯
Полная последовальнасць паведамленняў
Калі працуеце над стадзіяй «Полная последовательность сообщений», спачатку запісайце умовы кантракта: неабяжлівыя даны, сигнал успеху і тое, што выходзіць у разе частковага абякання. Такі список дапамагае заліцварыць пазнейшыя змены ў кодзе. Валіце маленькія, тэставаныя елементы замест большых скрыптов. Калі якісь крок абякае, прычына абякання павінна вказываць на адзін конкрэтны элемент, а не на заплутаную схему. Запісвайце назву інструмента, хэш аргументаў, час адклікання і рэзультат кожнага вызову. Без такога следу дэбаггін займае гадзіны. Калі працуеце над стадзіяй «Полная последовательность сообщений», спачатку запісайце умовы кантракта: неабяжлівыя даны, сигнал успеху і тое, што выходзіць у разе частковага абякання. Такі список дапамагае заліцварыць пазнейшыя змены ў кодзе. Запісвайце часы выканання і кост токенаў або запытаў разам з функцыйнальнымі рэзультатамі. Відразувыя даны пра косцы запобегаюць неспакойным рахункам, калі праця пераходзіць з дэмавайнага режыма ў спакульнае сераўерное сэрאвы.
1 HumanMessage "Generate 8 random numbers…"
2 AIMessage [tool_call: generate_numbers({count:8, min:5, max:50, seed:42})]
3 ToolMessage [33.77, 6.13, 17.38, 15.04, 38.14, 35.45, 45.15, 8.91]
4 AIMessage [tool_call: calculate_statistics({numbers:[...]})]
5 ToolMessage {count:8, mean:24.9962, std_dev:14.8181, ...}
6 AIMessage [tool_call: find_outliers({numbers:[...], threshold:2})]
7 ToolMessage {outliers:[], outlier_count:0, ...}
8 AIMessage "Here are the results. Random numbers: …" ← final answer
Журнал JSONL
Этап логавання у формате JSONL працюе найэфектывней, калі яго розглядаць як мерыемую структуру. Зберагачыце адны ідеальны прыклад роботы, адны прыклад неудачы і запіс пра вярнэнне да пачатковага стану, перш чым расширваць сферу прыемлівання. Конфігурацыю трэба залічыць пазначкай занята ўнутрь коду прыемлівання. Файлы сяродавішча, хранільнікі секрэтных дадзеных і пазначкі функцый канальна знаходзіцца ў аднам месцы, куды аператары можаць адрабатваць контроль, не чытаючы весь граф. Абяўляйце інструменты з вузкімі схемамі та чысткімі атрыбутамі паслядніх эфектаў. Хостам неабходна знаты, якія вызовы мутуюць стан, перш чым яны автаматычна схваляюць іх.
{"timestamp": "...", "event": "agent_start", "data": {"runnable": "LangGraph", "run_id": "..."}}
{"timestamp": "...", "event": "llm_call", "data": {"call_number": 1, "model": "gpt-5-mini", "messages": 1}}
{"timestamp": "...", "event": "llm_end", "data": {"elapsed": "5.35s", "tool_calls_requested": ["generate_numbers"]}}
{"timestamp": "...", "event": "tool_start", "data": {"call_number": 1, "tool": "generate_numbers", "server": "data_server", "args": "..."}}
{"timestamp": "...", "event": "tool_end", "data": {"elapsed": "0.63s", "output_preview": "[33.77, 6.13, ...]"}}
{"timestamp": "...", "event": "llm_call", "data": {"call_number": 2, "model": "gpt-5-mini", "messages": 3}}
...
{"timestamp": "...", "event": "run_summary", "data": {"llm_calls": 4, "tool_calls": 3, "total_elapsed": "42.25s"}}
Ўтвары
Этап «Джэрсіз» працюе наяўней, калі яго спрыяваць як мерыемую паверхню. Зафіксавайце адна ідеальная транскрыпцыю, адзін прыклад неудачы і запіс пра вярнэнне да пачатковага стану перш чым расширваць масштабы. Дакументавайце як шлях успеху, так і шлях вярнэння. Перапрыбуткі, людзкія контралі і обработка некоректных паведамленняў є часткай продукту, а не наступным этапам дапрацоўкі. Адкройце інструменты з вузкімі схемамі та чысткімі пазначэннямі побачных эфектаў. Хостам неабходна знаты, якія вызовы мутуюць стан, перш чым яны автаматычна схваляюць ўпрацоўкі.
Паведамленне ад нашага заснавальніка
Паведамленне The A з нашай стадыі працуе найкраща, калі яго спрыяваць як мерыемую паверхню. Зберагачыце адны ідеальны прыклад роботы, адзін прыклад неудачы і запіс пра вярнэнне да пачатковага стану перад расшырэнням масштаба. Валіце маленькія, тэставаныя елементы замест большых скрыптов. Калі якісь крок не выйшае, неудача должна вказываць на адну конкрэтную адпаведальнасць, а не на заплутаны ланцюг задач. Адкрывайце інструменты з вузкімі схемамі та чысткімі пазначэннямі побачных наследкаў. Адпаведальныя за эксплуатацыю должны знать, якія вызовы мутуюць стан системы, перш чым автаматычна схваліць іх. Паведамленне The A з нашай стадыі працуе найкраща, калі яго спрыяваць як мерыемую паверхню. Зберагачыце адны ідеальны прыклад роботы, адзін прыклад неудачы і запіс пра вярнэнне да пачатковага стану перад расшырэнням масштаба. Запісвайце часы выконання та вартасць токенаў або запытав, падаючы іх разам з функцыйнальнымі рэзултатамі. Відразувыя даны пра вартасці запобегаюць неспакойным рахункам, калі процес пераходзіць з дэмавайнага режыма ў спяльныя сераўры.
Чэк-ліст для эксплуатацыі
Этап перагляду канцэларыі аперацый працюе найкраща, калі яго спрыяваць як мерыемую плошчу. Запісаўце адна ідеальная версія, адзін прыклад неудачы і запіс пра вярнэнне да пачатковага стану перш чым расширваць масштабы.
Спрыявайце гэтым этапам як кантракту межу вхіднымі дадзеннямі і паўнастацэннымі выходамі. Дайце назвы артыфактам, задаце крэтырыя успеху і адмовіцеся ад тыхоўскага частковага завершэння.
Адкройце інструменты з вузкімі схемамі та чысткімі пазначэннямі пабочных эфектаў. Адпаведальныя за аператывуцю павінны знать, якія вызовы мутуюць стан, перш чым автаматычна ўзгадваць іх.
Калі бюджэт дазволяе, дадзіце тэст на працяснасць, які перабірае критычны шлях у CI з фіксатрамі, а не з рэальнымі платнымі API.
Запісвайце часы выканання та кост токенаў або запытаў разам з функцыйнаімі рэзультатамі. Відкрытыя даныя пра косцы з’являюцца раніше, чым утвараюцца неспадзянаныя рачункі, калі шлях пераходзіць з дэмаверсіі ў спяльныя среды.
Адаптавайце інструменты з вузкімі схемамі та чыткімі пазначэннямі побачных наследкаў. Хостам неабходна знаты, якія вызовы мутуюць стан, прытаму яны можаў бы аўтоматычна санкціонаваць іх.
Перад паднятыем стэка заморажуйце версіі, зафіксавайце «золаты» транскрыпты для критычных шляхоў і паказвайце крокі для атрыбуцыі. У спадзяльных средах неабходны ліміты частоты запытоў, пераказкі належнасці та чысткая адпаведальнае особа за зміну секрэтных даных. Валіце простую надзяйнасць працы над крэатывнымі, але разовымі дамах.
Прыметка для пакету c7efc4f69698: не кладзіце ключы прадаўцаў у репазітарый, задаце верхнюю межу токенаў на сесію та зберагачыце транскрыпты празаўседы ў фіксатыях eval, каб пазнейшыя замены модэляў заставаліся пораўнанымі.
Для стадіі 0 прыема забезпечэння надзеі неабяжна практычная ваказка: перад зменым коду трэба адзначыць вхідныя данні, адпаведальнага за крок і критэрыя завершэння. Аперацыйныя працавнікі должны магчыма ўможна перадзеяць крок з вядомага пункта контролю, не спрабоўваючы здагадвацца пра схованы стан. Неабяжна задокументаваць як шлях успеху, так і шлях вярнення да нормальнага стану. Перапрыбуткі, людзкія перакрыцця і обробка некоректных паведамленняў є часткай продукту, а не чымсь, што дадаецца пазней.
Дакладнасць прыема забезпечэння надзеі 0/888: трэба змерыць час выканання, класію паказанней і колькасць выкорыстоўваных токенав для гэтай ваказкі, а пасля, на аднойчынных критэрыях, а не на індывідуальных спостарожэннях, вырашыць, чы робіцца змена.
Калі працуеце над першым этапам зміцнення, спачатку запісайце контракт: неабяжлівыя вхідныя даны, сигнал успеху і тое, што выходзіць у разе частковага невыпання. Такі список контроля дапамагае заліцвачыць пазнейшыя змены коду. Спрыятлівае ставленне да гэтаго этапу як да контракта межа вхіднымі данымі і перакананымі выходнымі результатамі. Дайце назвы артыкулам, задаце критэрыі успеху і адмовіцеся ад мовчанкавага частковага завершэння.
Дзеянне зміцнення 1/888: вымерыце час виканання, класію памылак і колькасць викорыстоўваных токенав для гэтага пункту, а потым вынікніце рашэнне пра тое, чы робіць змену на адной пазначанай базе пытанняў, а не на адной лячбе.
Этап зміцнення 2 працюе лепей, калі яго спрыятлівае ставленне як да вимерыванай плошчы. Запісайце адну ідеальную транскрыпцыю, адзін прыклад невыпання і запіску пра анулюванне, перш чым расширваце сферу дзейснення. Зберагаюце настройкі паза кодам прыемленае. Файлы сераўіса, хранільнікі секрэтных данных і флагі функций должны знаходзіцца ў аднам месцы, якое аператары можаць пераглядаць без неабяжлівага чытання всей структуры.
Дзеянне паўжасткі 2/888: звярніце увагу на час выканання, клас памылак і колькасць викорыстоўваных токенаў для гэтага запісу, а пасля, на аднойчынай базе фіксаванага набору пытанняў, а не на асобістых спазыраннях, выявіце, чы хачаце застаўіць змяну.
Для 3-й стадзіі паўжасткі запісу з’явіце вхідныя даны, адпаведальнага за крок і критэрыя завершэння пры зміне коду. Аперацыйныя працавнікі должны магчыма было перзапускаць крок з вядомай точкі контролю, не падозрываючы прыхованы стан. Валіце маленькія, тэставальныя елементы працэў над велікімі скрыптамі. Калі крок не выйшоў, прычына неудачы должна вказываць на адну конкрэтную адпаведальнасць, а не на заплутаны ланцужок задач.
Дзеянне паўжасткі 3/888: звярніце увагу на час выканання, клас памылак і колькасць викорыстоўваных токенаў для гэтага запісу, а пасля, на аднойчынай базе фіксаванага набору пытанняў, а не на асобістых спазыраннях, выявіце, чы хачаце застаўіць змяну.