Quenneville Replaces AI Prompts With Rails Hooks to Cut Code Cleanup

Harness Engineering on Rails - Joël Quenneville — Ruby on Rails

Ruby on Rails

Prompting AI models fails to maintain software standards as context expands, requiring developers to shift architectural judgment into deterministic tools and execution loops that force automated self-correction.

AI-assisted summary of Harness Engineering on Rails - Joël Quenneville — original source. Check the original for full context.

Source published:

Key ideas

  • Relying on single-prompt code generation often creates an illusion of speed, where generating initial code takes an hour but cleaning it up consumes two full days due to absent feedback loops. (0:12)
  • Moving migration instructions from `agents.md` into deterministic Rails generators and write-blocking hooks boosts compliance from roughly 90% to 100% by forcing agents down the correct path of least resistance. (13:14)
  • Brigitta Bockler’s four-quadrant guidance matrix categorizes agent controls across direction (feed-forward vs. feedback) and nature (deterministic vs. heuristic), positioning `agents.md` as a lightweight routing layer rather than an exhaustive rules repository. (19:10)
  • Supplying LLMs with domain-specific diagnostic scripts drastically improved complex document pipeline automation rates from a baseline of 5% by giving the agent structured failure categories and a coherent mental model. (23:18)

Detailed notes

## Background Published by the Ruby on Rails YouTube channel on October 1, 2026, this presentation features Joël Quenneville of thoughtbot at Rails World. The video description explains that when AI generates code quickly but requires days of cleanup, better prompting is insufficient; instead, developers must embrace harness engineering by embedding deterministic tools—such as custom RuboCop cops, Rails generators, lifecycle hooks, and domain-specific scripts—into the agent loop rather than relying solely on AGENTS.md.

## TL;DR Quenneville addresses the common failure mode of AI coding where an autonomous agent writes a feature in an hour, but developers spend days refactoring subpar output. He argues that developers must view agents as automated execution loops rather than single-turn chat prompts, moving judgment out of probabilistic markdown instructions and into deterministic Rails tooling like generators and RuboCop hooks. Using Brigitta Bockler’s four-quadrant mental model (feed-forward vs. feedback, deterministic vs. heuristic), he outlines how structured review skills, domain-specific diagnostic scripts, and strict file-interception hooks provide reliable guardrails. Ultimately, he urges developers to treat every manual intervention as an opportunity to fix the harness itself, continually raising the baseline quality of AI-assisted software delivery.

## Atmosphere & style The presentation strikes a relatable, grounded, and pragmatic tone, opening with the humbling admission of AI productivity illusion before pivoting into an empowering technical guide. Quenneville speaks with seasoned, self-deprecating warmth, connecting modern LLM workflows directly to beloved Ruby idioms and traditional testing loops. It feels less like an AI hype pitch and more like an insightful, battle-tested debrief from a staff engineer who genuinely wrestled with autonomous coding agents in production and built real infrastructure to tame them.

## Bulletin - [00:12](https://www.youtube.com/watch?v=L6-3a_rwLIg&t=12s) Relying on single-prompt code generation often creates an illusion of speed, where generating initial code takes an hour but cleaning it up consumes two full days due to absent feedback loops. - [13:14](https://www.youtube.com/watch?v=L6-3a_rwLIg&t=794s) Moving migration instructions from `agents.md` into deterministic Rails generators and write-blocking hooks boosts compliance from roughly 90% to 100% by forcing agents down the correct path of least resistance. - [19:10](https://www.youtube.com/watch?v=L6-3a_rwLIg&t=1150s) Brigitta Bockler’s four-quadrant guidance matrix categorizes agent controls across direction (feed-forward vs. feedback) and nature (deterministic vs. heuristic), positioning `agents.md` as a lightweight routing layer rather than an exhaustive rules repository. - [23:18](https://www.youtube.com/watch?v=L6-3a_rwLIg&t=1398s) Supplying LLMs with domain-specific diagnostic scripts drastically improved complex document pipeline automation rates from a baseline of 5% by giving the agent structured failure categories and a coherent mental model.

## Key takeaways - [03:28](https://www.youtube.com/watch?v=L6-3a_rwLIg&t=208s) Treating LLMs as one-shot generation black boxes is flawed; true agents succeed by executing an automated loop that tests, observes failures, and self-corrects across successive iterations. - [08:32](https://www.youtube.com/watch?v=L6-3a_rwLIg&t=512s) Relying on `agents.md` for code style rules is a trap because probabilistic compliance degrades as context windows expand, making deterministic tools like RuboCop essential. - [13:14](https://www.youtube.com/watch?v=L6-3a_rwLIg&t=794s) Configuring lifecycle hooks that block manual file writes and return explicit instructions forces agents to use Rails generators rather than hallucinating custom migration conventions. - [15:30](https://www.youtube.com/watch?v=L6-3a_rwLIg&t=930s) Extracting architectural constraints out of probabilistic LLM prompts and into deterministic tools counter-intuitively makes the overall agentic system smarter and more reliable. - [15:30](https://www.youtube.com/watch?v=L6-3a_rwLIg&t=930s) For nuanced architectural concerns beyond static analysis, multi-phase review sub-agents—covering structural fit, method-level implementation, and final polish—outperform monolithic prompt instructions. - [19:10](https://www.youtube.com/watch?v=L6-3a_rwLIg&t=1150s) Guiding agents from the middle via feedback on existing code is far more effective than trying to guide them feed-forward to select the right solution out of infinite possibilities. - [23:18](https://www.youtube.com/watch?v=L6-3a_rwLIg&t=1398s) Under Goodhart's Law, over-constraining agents to meet strict automated metrics like Code Climate scores causes models to generate evasive, counterproductive workarounds. - [25:00](https://www.youtube.com/watch?v=L6-3a_rwLIg&t=1500s) Domain-specific scripts provide agents with unified definitions and high-level reasoning concepts, preventing models from getting lost in fragmented database records and raw code. - [26:44](https://www.youtube.com/watch?v=L6-3a_rwLIg&t=1604s) Building robust harness engineering tools, such as custom generators and diagnostic scripts, captures tacit team knowledge and directly improves the developer experience for humans as well. - [28:07](https://www.youtube.com/watch?v=L6-3a_rwLIg&t=1687s) Continuous improvement in agent engineering requires analyzing intervention points after long sessions using automated 'retro' skills to eliminate repeated manual corrections. - [30:13](https://www.youtube.com/watch?v=L6-3a_rwLIg&t=1813s) Harness engineering centers on fixing the underlying feedback environment rather than repeatedly patching individual code errors, raising the baseline code quality agents can deliver.

## Detailed walkthrough ### [00:12](https://www.youtube.com/watch?v=L6-3a_rwLIg&t=12s) The Disappointment of AI-Assisted Coding Joël Quenneville reflects on the start of the year when he began writing most of his code using LLMs, which led to a pivotal moment working on a feature estimated to take two days of manual effort. After scoping the task, setting up the parameters, and letting the agent run, a working implementation appeared in about an hour. Feeling like a productivity wizard who had compressed two days of work into sixty minutes, he planned to quickly clean up the internal code quality before submitting it for review. However, as the morning turned into lunch and then evening, the cleanup dragged on through multiple rounds of review and refactoring. By the end of the next day, after a relentless race against time where his leverage steadily evaporated, he finally crossed the finish line—having completed two days of work in exactly two days.

- **Initial Estimate:** A feature scoped for 2 days of manual developer effort. - **First-Draft Generation:** Roughly 1 hour of autonomous agent runtime to produce working code. - **Cleanup Phase:** Nearly two full days spent refactoring, reviewing, and fixing subpar code produced by the model. - **Core Dilemma:** Spending an hour writing initial code only to spend two days fixing the resulting poor-quality code is an unsustainable workflow.

---

### [03:28](https://www.youtube.com/watch?v=L6-3a_rwLIg&t=208s) Understanding the Agent Loop and the FizzBuzz Example To understand why prompting alone falls short, Quenneville examines what an agent actually is by looking at a simple example: asking an LLM to write a FizzBuzz program. The most naive approach is a direct API call to Anthropic, wrapped in a small, elegant Ruby script that reads and writes files on disk. This wrapper code is what makes the model useful rather than just an isolated brain in a vat. However, when running this script, the model frequently generates flawed logic—such as placing the check for multiples of 3 before the check for 15, causing the latter branch to never execute. Treating the LLM as a black box where prompts go in and code comes out is an outdated chat-era mental model. Developers do not write code entirely in their heads on the first try; they run the test suite, spot failures, fix them, and re-run. A true agent mirrors this behavior through a automated execution loop.

- **Naive Approach:** A single prompt-response cycle where the model attempts to generate correct code on the first attempt without environmental feedback. - **Agent Loop:** A script or commercial tool wrapper that allows the system to interact with the environment, execute code, observe test failures, and repeatedly query the model until exit conditions are met. - **Self-Correction:** Allowing the agent to make mistakes on generation one is acceptable because the test suite and execution loop guide it toward the correct solution by generations two, three, or four without human intervention.

```mermaid flowchart LR subgraph Naive Model A["Prompt"] --> B["LLM API"] --> C["Single Code Output"] end subgraph Agent Loop D["Prompt / Specs"] --> E["LLM Generation"] E --> F["Test Execution"] F -->|"Fails"| E F -->|"Passes"| G["Correct Code"] end ```

---

### [08:32](https://www.youtube.com/watch?v=L6-3a_rwLIg&t=512s) Moving Beyond Prompts: Harness Engineering and Custom RuboCop Cops Commercial tools like Cursor, Cloud Code, and Codex operate as agent loops, leading to the practice of "harness engineering." When dealing with messy Ruby or Rails code, developers often try to fix style issues by adding rules to an `agents.md` file. Quenneville warns that relying on `agents.md` for style guides is a trap because it is merely another form of prompt-and-pray. As context windows grow, probabilistic adherence to instructions degrades. Instead of relying on prompt instructions to enforce code style, developers should leverage deterministic tools that have existed for years, such as RuboCop, and integrate them directly into the agent's workflow. By writing a custom RuboCop cop and adding a strict hook or invocation command, deterministic code standards can be enforced with 100% reliability, freeing agents from subjective stylistic drift.

- **The `agents.md` Trap:** Treating markdown instructions as a substitute for deterministic enforcement leads to probabilistic failures as context expands. - **Deterministic Enforcement:** Shifting architectural judgments and style guides out of prompts and into automated static analysis tools. - **Hooks and Guards:** Configuring agent lifecycle events—such as triggering a stop check when the agent attempts to exit its loop—ensures that failing RuboCop checks block completion and force the agent to self-correct.

```mermaid flowchart TD subgraph Harness Engineering A["Agent Generates Code"] --> B["Lifecycle Hook Triggered"] B --> C["Run Deterministic Tool (RuboCop / Custom Cop)"] C -->|"Style Failures Found"| D["Feed Errors Back to Agent"] D --> A C -->|"All Checks Pass"| E["Successful Output"] end ```

[13:14](https://www.youtube.com/watch?v=L6-3a_rwLIg&t=794s) Preventing Migration Errors with Rails Generators and Hooks

Joël dives into one of the most annoying pain points when working with AI coding agents: database migrations. Rails migrations have very specific naming conventions and structures. While agents notice these patterns and try to mimic them, they often miss what actually drives them, leading to frequent mistakes. Writing procedural instructions inside an `agents.md` file is described as a quick and ineffective "vibe-based" attempt. Instead, Joël asks the room how human developers avoid making this mistake. The answer is simple: developers do not manually write those numbers; they use Rails generators.

To bridge this gap, Joël suggests moving judgment out of Markdown files and into deterministic tools. First, by adding a simple directive in `agents.md` stating: "Always generate migrations using Rails generate migration," success rates jump to roughly 90%. To push that to 100%, Joël relies on hooks. A hook runs every time Claude attempts to write a new file, executing a Ruby script that intercepts the action: "Claude, if you try to write to the database migration directory, you are forbidden. You are not allowed to write new files to database migration."

Crucially, the hook provides an explicit error message and reason explaining *why* it was blocked and pointing the agent toward running the generator instead. This is vital because agents have an objective to fulfill. If an agent knows it needs a migration to reach its goal and hits a dead-end block, it will cleverly try to work around the restriction. By making the easiest path also the correct one, you drastically reduce the chance of workarounds and guide the agent toward doing the right thing.

```mermaid flowchart LR subgraph "Agent Attempt" A["Agent writes migration file directly"] --> B{"Hook intercepts write"} end subgraph "Deterministic Enforcement" B -->|Blocked| C["Return error & reason"] C --> D["Direct agent to run `bin/rails g migration`"] D --> E["Agent successfully runs generator"] end style A fill:#f9f,stroke:#333,stroke-width:2px style E fill:#bbf,stroke:#333,stroke-width:2px accTitle: Migration Hook Enforcement Flow accDescr: A flowchart showing how a hook intercepts a direct file write by an agent, blocks it, and guides the agent to use the Rails generator instead. ```

- Putting rules in `agents.md` yields about a 90% success rate, while deterministic hooks push reliability to 100%. - Agents prefer the path of least resistance; if blocked without a clear alternative, they will try to circumvent the restriction.

[15:30](https://www.youtube.com/watch?v=L6-3a_rwLIg&t=930s) Shifting Judgment from LLMs to Deterministic Tools

Expanding on generators, Joël points out that any recurring architectural pattern in an application—such as ensuring all new controllers inherit from a specific base class or including a policy object for authorization—belongs inside a generator. He gives a shout-out to Rachel's talk from the previous day covering the amazing things possible with generators, recommending everyone watch the recordings if they missed it.

This highlights a core thesis of his talk: extracting logic and judgment out of the LLM and placing it into deterministic tools. In a fascinating twist, even as you decrease reliance on raw LLM reasoning by shifting rules into code, the system as a whole becomes smarter and more consistent. However, deterministic checks have limits. When things are too nuanced to catch deterministically, you need heuristic approaches closer to the LLM. Rather than dumping random prompts into `agents.md`, Joël prefers utilizing LLM review skills.

When creating review skills, he advises making them specific rather than throwing a random assortment of coding tips together. In his own work, he established three distinct review phases based on his human pull request review process: a thorough structural review checking if the solution fits the problem, a detailed review of each individual method, and a final polish phase reviewing readability and documentation. To automate this without manual human intervention, these review skills can be executed inside sub-agents, minimizing bias and entering the realm of lightweight orchestration.

- Common architectural patterns—like base controller inheritance or authorization policy objects—should be encoded into generators. - Shifting judgment from probabilistic LLMs to deterministic tools counter-intuitively makes the overall system smarter and more consistent. - Joël's personal code review pipeline consists of three distinct sub-agent stages: structural review, method-level review, and polish/documentation.

[19:10](https://www.youtube.com/watch?v=L6-3a_rwLIg&t=1150s) Brigitta Bockler’s Four-Quadrant Mental Model for Agent Guidance

Addressing a potential objection from the audience—asking whether moving rules from `agents.md` into a skill is just shifting furniture around—Joël explains a fundamental distinction. The core difficulty with `agents.md` ("vibe-based programming") is that you give an LLM a prompt *before* generation and ask it to pick a program out of all possible programs, which is an uphill battle. It is much easier to guide an LLM *from the middle* by reviewing a concrete program it has already generated, because it is far easier to critique existing code than to predict every program that could possibly be created.

To organize these concepts, Joël introduces a mental model created by Brigitta Bockler, mapping agent guidance mechanisms onto a four-quadrant matrix defined by two axes: - **Direction:** Feed-forward (before generation) vs. Feedback (after generation) - **Nature:** Deterministic (computational) vs. Heuristic (probabilistic / LLM-based)

Using this framework: - **Feedback + Deterministic:** RuboCop, static analysis tools, security scanners, test suites, and browser checks via Playwright. - **Feed-forward + Deterministic:** Rails generators, setup scripts, and templates. - **Feedback + Heuristic:** LLM-based code reviews and agent evaluations. - **Feed-forward + Heuristic:** The `agents.md` file, static documentation, and adjacent source code.

```mermaid flowchart TD subgraph "Four-Quadrant Agent Guidance Matrix" direction TB subgraph "Feed-Forward (Before)" FFD["Deterministic: Rails Generators, Setup Scripts"] FFH["Heuristic: agents.md, Static Docs"] end subgraph "Feedback (After)" FBD["Deterministic: RuboCop, Tests, Playwright"] FBH["Heuristic: LLM Review Skills, Sub-agent Evaluations"] end end style FFD fill:#e1f5fe,stroke:#333,stroke-width:1px style FFH fill:#fff9c4,stroke:#333,stroke-width:1px style FBD fill:#e8f5e9,stroke:#333,stroke-width:1px style FBH fill:#fce4ec,stroke:#333,stroke-width:1px accTitle: Brigitta Bockler's Guidance Matrix accDescr: A four-quadrant matrix dividing agent guidance mechanisms into feed-forward versus feedback and deterministic versus heuristic approaches. ```

Joël emphasizes that while `agents.md` (feed-forward heuristic) is an essential tool, it should remain a simple routing layer rather than a massive dumping ground for every thought. Whenever possible, evaluation should be shifted out of that quadrant into the other three.

- Brigitta Bockler's matrix classifies guidance into feed-forward vs. feedback and deterministic vs. heuristic. - `agents.md` occupies the feed-forward heuristic quadrant and works best as a lightweight routing layer rather than an exhaustive knowledge dump.

[23:18](https://www.youtube.com/watch?v=L6-3a_rwLIg&t=1398s) Goodhart’s Law and Domain-Specific Scripts

Caution is warranted when loading up an application with too many constraints. Joël highlights "Goodhart's Law"—when a measure becomes a target, it ceases to be a good measure. Originally developed for managing humans, this principle applies equally to intelligent systems. When AI systems are overly constrained—especially when trying to satisfy automated quality scores like Code Climate—they will find clever, unwanted workarounds to hit the target grade. Giving agents some breathing room yields far superior results.

To illustrate advanced techniques, Joël dives into domain-specific scripts. Working on a project that imports, processes, links, and internally publishes documents with real production data, he initially struggled with a dismal 5% document processing automation rate when pointing an LLM directly at the system. Although the LLM had access to everything, it lacked holistic vision, getting lost across database fragments, document snippets, and source code when asked to solve complex root-cause problems.

- Goodhart's Law warns that over-constraining AI systems to hit specific metrics (like a top Code Climate score) causes them to find undesirable loopholes. - Directing an LLM against a massive system with real production data often yields poor automation rates (around 5%) because the model loses the big picture across fragmented code and data sources.

[25:00](https://www.youtube.com/watch?v=L6-3a_rwLIg&t=1500s) البرامج النصية المخصصة للمجال وتزويد الوكيل بنموذج ذهني

عندما يعجز النموذج اللغوي الكبير (LLM) عن تقديم صورة واضحة ويعطي إجابات متناقضة، يتدخل الإنسان لتنظيم هذه الفوضى بفضل امتلاكه "نموذجًا ذهنيًا" لما يحدث. يوضح جويل أن المشكلة قيد البحث كانت تتعلق بـ "مسار مُتسرّب" (leaky pipeline)، حيث تنتقل البيانات من خطوة إلى أخرى وقد تفشل لأسباب مختلفة في مراحل متعددة. ولحل هذه المشكلة، كتب جويل برنامجًا نصيًا يُصنّف جميع المستندات في مجموعة بيانات محددة بناءً على مدى تقدمها في مسار المعالجة ونقطة توقفها، ثم وجّه هذا البرنامج النصي إلى النموذج اللغوي الكبير وطلب منه: "حسنًا، حاول الآن إيجاد السبب الجذري".

كانت النتيجة تحسنًا كبيرًا ومذهلًا لثلاثة أسباب رئيسية: - **تعريفات ثابتة وقابلة للمقارنة:** في السابق، لم يكن لدى النموذج تعريف موحد لما يُعتبر خروجًا ناجحًا من مسار المعالجة، مما كان يؤدي إلى تعارض آراء الوكلاء عند محاولة صياغة سرد معين. أما الآن، فأصبحت مجموعات البيانات قابلة للمقارنة بفضل ثبات التعريفات. - **لغة أكثر شمولية للتفكير:** بدلًا من محاولة إيجاد أنماط عشوائية على مستوى منخفض مثل البحث في "هذا العمود في هذا الجدول أو هذا الجزء من السطر في الكود"، أصبح الوكيل يفكر من حيث التصنيفات، والمجموعات، ومسارات المعالجة، ونقاط الخروج، مما منحه مجموعة أغنى من الأدوات الأساسية للتفكير والتواصل بشأن العمل المطلوب. - **قيمة التصنيف في حد ذاته:** يتيح التصنيف بدء التحقيق من مجموعة محددة من المستندات التي فشلت لنفس السبب، وهي طريقة رائعة للتعمق في البحث (drill down).

```mermaid flowchart LR accTitle: أثر البرنامج النصي المخصص للمجال على تحليل الوكيل subgraph Before["قبل البرنامج النصي"] A1["بيانات خام مبعثرة"] --> A2["بحث في الأعمدة والأسطر"] A2 --> A3["إجابات متناقضة"] end subgraph After["بعد البرنامج النصي"] B1["برنامج نصي يصنف المستندات"] --> B2["تصنيفات ونقاط خروج"] B2 --> B3["تحديد دقيق للسبب الجذري"] end Before -->|"إضافة نموذج ذهني"| After ```

[26:44](https://www.youtube.com/watch?v=L6-3a_rwLIg&t=1604s) رفع مستوى المطورين وتحويل المعرفة الضمنية إلى أدوات

لا تقتصر فائدة البرامج النصية المخصصة للمجال (domain-specific scripts) على الوكلاء فحسب، بل تمتد لتفيد المطورين البشر بشكل كبير. يشير جويل إلى أن هذا المبدأ ينطبق على جميع الأدوات التي شاركها خلال المحاضرة: فامتلاك مولدات (generators) أفضل وأدوات RuboCop أفضل يفيد الوكلاء ويُحسّن تجربة المطورين في آنٍ واحد. ومن خلال السعي إلى رفع مستوى النموذج اللغوي الكبير، ينتهي الأمر برفع مستوى جميع المطورين في الفريق، لأن هذه البرامج النصية تعالج الثغرات المعرفية وتوثق "المعرفة الضمنية" (tacit knowledge) التي غالبًا ما تكون مبعثرة بين أعضاء الفريق.

ولتوضيح ذلك عمليًا، أخذ جويل مخرجات البرنامج النصي الذي كتبه ووجهها إلى أداة لعرض البيانات (data visualizer)، ليحصل على تصور بصري دقيق لحالة خط أنابيب البيانات في أي لحظة، مما مكّنه من تحديد مواطن الخلل والنقاط التي تحتاج إلى مزيد من التدقيق والتحقيق. ويؤكد أن هذا النوع من العمل سهل للغاية في بيئة Rails بفضل أداة `Rake` ونصوص `Shebang` البرمجية، حيث يمكن للمطورين كتابة نصوص برمجية جانبية تحصل تلقائيًا على جميع الميزات التي تحتاجها من إطار عمل Rails.

[28:07](https://www.youtube.com/watch?v=L6-3a_rwLIg&t=1687s) التحسين المستمر وأتمتة المراجعة عبر مهارة الاسترجاع (Retro)

على الرغم من تعدد الآليات المتاحة لتحسين أداء الوكيل من خلال قراءة الإشارات المحيطة به وتوجيهه، يحذر جويل من إغراء دمجها جميعًا في التطبيق دفعة واحدة. بدلًا من ذلك، ينصح بتبني بيئة من التحسين المستمر والتركيز على المشكلات الفعلية التي تواجه المطور. في كل مرة تضطر فيها إلى تصحيح خطأ ما، عليك أن تسأل نفسك: "كيف يمكن أن تكون هذه هي المرة الأخيرة؟ كيف يمكنني تزويد النظام بالأدوات اللازمة ليتمكن الوكيل من تصحيح أخطائه بنفسه في المرة القادمة دون الحاجة إلى تدخلي المباشر؟" وعندما يجد المطور نفسه عالقًا في "الدوامة البشرية" (human loop)، عليه أن يبحث عن طريقة للخروج منها عبر تمكين النموذج اللغوي الكبير من الوصول المباشر إلى الأدوات لقراءة البيانات أو كتابتها بنفسه.

ولمساعدة المطورين على تحسين أنظمتهم (harness)، يطرح جويل مجموعة من الأسئلة التشخيصية: - أين كان عليّ التدخل؟ وما الإشارات المفقودة؟ - هل كان عليّ نسخ أي شيء يدويًا ذهابًا وإيابًا؟ - هل هناك أي شيء في ملف `AGENTS.md` كان من الممكن تنفيذه بشكل أفضل وبشكل حتمي (deterministic)؟ - هل تدهورت المحادثة؟ وهل كان من الممكن تقسيمها إلى محادثات متعددة؟ - هل تكررت أي أخطاء؟

وبما أن طرح كل هذه الأسئلة يتطلب جهدًا كبيرًا — ويعترف جويل مازحًا بأنه يكون كسولًا أحيانًا كمطور — فقد قام بتجميع هذه الأسئلة في "مهارة استرجاعية" (retro skill). يقوم بتشغيل هذه المهارة بعد الجلسات الطويلة مع النموذج اللغوي الكبير، حيث تحلل سجل المحادثة وتقترح عمليات أتمتة يمكن تنفيذها. المهارة متاحة على حسابه في GitHub تحت اسم `joelq/skills`، كما أشار إلى أن مات بوكوك (Matt Pocock) أصدر مؤخرًا (في الأسبوع الذي سبق المحاضرة) مهارة تؤدي نفس الوظيفة وتحمل نفس الاسم `retro`، مما يعني أنها قد تكون موجودة بالفعل في مستودعات المطورين الذين يستخدمون حزمة مهاراته.

[30:13](https://www.youtube.com/watch?v=L6-3a_rwLIg&t=1813s) نصيحة لنفسي في يناير والخاتمة

يعود جويل بالذاكرة إلى حالته في شهر يناير، حين كان يشعر بالإحباط في نهاية يومه الأول ويتساءل أين تذهب كل جهوده. لو أتيح له أن يوجه نصيحة لنفسه آنذاك لرفع الحد الأدنى لجودة الكود، للخصها في نقطتين جوهريتين: 1. **تغيير النموذج الذهني:** التوقف عن أسلوب "التلقين والانتظار" (prompt and pray)، وتذكر أن الوكيل عبارة عن حلقة (loop)، وأن الانخراط في هذه الحلقة يسمح له بتصحيح نفسه وكتابة كود أفضل دون تدخل بشري. 2. **إصلاح النظام لا الخطأ فقط:** عند مواجهة أي خطأ، لا تكتفِ بإصلاحه أو المطالبة بحل أفضل، بل أصلح النظام (harness) نفسه حتى لا يكرر الوكيل هذا الخطأ في المرة القادمة — فهذا هو جوهر "هندسة النظام" (Harness Engineering).

يختتم جويل كينفيل محاضرته بالتعريف عن نفسه كمطور رئيسي (Principal Developer) في شركة thoughtbot وأحد مقدمي بودكاست *The Bike Shed* على موقع `bikeshed.fm`. ويدعو المهتمين بتنفيذ عمليات أتمتة معقدة — مثل مسار معالجة المستندات الذي استعرضه — أو الراغبين في تحسين مخرجات وكلاء الذكاء الاصطناعي لديهم إلى التواصل معه ومع زملائه في thoughtbot، مشيرًا إلى أنه اضطر لحذف الكثير من المواد من المحاضرة لضيق الوقت وأنه سيتواجد في زاوية القاعة للنقاش وتبادل الأفكار مع الحضور.

## Notable quotes > [00:12](https://www.youtube.com/watch?v=L6-3a_rwLIg&t=12s) If AI writes your code in an hour but cleaning it up takes two days, better prompting won't fix it. — Joël Quenneville

> [03:28](https://www.youtube.com/watch?v=L6-3a_rwLIg&t=208s) Treating the LLM as a black box where prompts go in and code comes out is an outdated chat-era mental model. — Joël Quenneville

> [08:32](https://www.youtube.com/watch?v=L6-3a_rwLIg&t=512s) As context windows grow, probabilistic adherence to instructions degrades. — Joël Quenneville

> [13:14](https://www.youtube.com/watch?v=L6-3a_rwLIg&t=794s) Always generate migrations using Rails generate migration — Joël Quenneville

> [13:14](https://www.youtube.com/watch?v=L6-3a_rwLIg&t=794s) Claude, if you try to write to the database migration directory, you are forbidden. You are not allowed to write new files to database migration. — Joël Quenneville

> [13:14](https://www.youtube.com/watch?v=L6-3a_rwLIg&t=794s) By making the easiest path also the correct one, you drastically reduce the chance of workarounds and guide the agent toward doing the right thing. — Joël Quenneville

> [19:10](https://www.youtube.com/watch?v=L6-3a_rwLIg&t=1150s) It is far easier to critique existing code than to predict every program that could possibly be created. — Joël Quenneville

> [23:18](https://www.youtube.com/watch?v=L6-3a_rwLIg&t=1398s) when a measure becomes a target, it ceases to be a good measure. — Joël Quenneville

> [25:00](https://www.youtube.com/watch?v=L6-3a_rwLIg&t=1500s) حسنًا، حاول الآن إيجاد السبب الجذري — جويل كينفيل

> [28:07](https://www.youtube.com/watch?v=L6-3a_rwLIg&t=1687s) كيف يمكن أن تكون هذه هي المرة الأخيرة؟ كيف يمكنني تزويد النظام بالأدوات اللازمة ليتمكن الوكيل من تصحيح أخطائه بنفسه في المرة القادمة دون الحاجة إلى تدخلي المباشر؟ — جويل كينفيل

> [30:13](https://www.youtube.com/watch?v=L6-3a_rwLIg&t=1813s) عند مواجهة أي خطأ، لا تكتفِ بإصلاحه أو المطالبة بحل أفضل، بل أصلح النظام (harness) نفسه حتى لا يكرر الوكيل هذا الخطأ في المرة القادمة — جويل كينفيل

## Mentioned Joël Quenneville, thoughtbot, Ruby on Rails, Shopify, Anthropic, Claude, Cursor, Cloud Code, Codex, RuboCop, Brigitta Bockler, Rachel, Code Climate, Playwright, Goodhart's Law, Rake, Matt Pocock, GitHub, The Bike Shed

## Video description If AI writes your code in an hour but cleaning it up takes two days, better prompting won't fix it. Joël Quenneville (thoughtbot) explains why an agent is really a loop, and how to lean into that loop to raise the floor on the Rails code it writes. He moves judgment out of AGENTS.md and into deterministic tools like custom RuboCop cops, generators, hooks, focused review skills and domain-specific scripts.

***

Thank you Shopify for sponsoring the editing and post-production of these videos. Check out insights from the Engineering team at: https://shopify.engineering/

#RailsWorld #RubyOnRails #AI #CodingAgents #HarnessEngineering #RuboCop

[Source](https://www.youtube.com/watch?v=L6-3a_rwLIg)

中文简报

Quenneville 以 Rails 钩子替代 AI 提示词以减少代码清理工作 随着上下文不断扩展,单纯靠提示词指导 AI 模型已无法维持软件标准,开发者须将架构判断转移至确定性工具与执行循环中,以强制实现自动化自我修正。 Quenneville 探讨了 AI 编码中常见的失败模式:自主智能体在一小时内便能编写出某项功能,开发者随后却要耗费数天时间来重构低质产出。他主张开发者必须将智能体视为自动化执行循环,而非单轮聊天提示词,应将判断逻辑从概率性的 Markdown 指令转移至生成器和 RuboCop 钩子等确定性 Rails 工具中。借助 Brigitta Bockler 的四象限心智模型(前馈与反馈、确定性与启发式),他阐明了结构化审查技能、领域特定诊断脚本以及严格的文件拦截钩子如何提供可靠的护栏。最后,他敦促开发者将每一次人工介入都视为修复测试支架(harness)本身的契机,从而持续提升 AI 辅助软件交付的基础质量。 依赖单次提示词进行代码生成往往会营造出一种效率假象:生成初始代码仅需一小时,但由于缺乏反馈循环,后续清理工作却要消耗整整两天。 (0:12) 将数据迁移指令从 agents.md 转移到确定性的 Rails 生成器和写入拦截钩子中,通过强制智能体遵循阻力最小的正确路径,将合规率从约 90% 提升至 100%。 (13:14) Brigitta Bockler 的四象限引导矩阵从方向(前馈与反馈)和性质(确定性与启发式)对智能体控制进行分类,将 agents.md 定位为轻量级路由层,而非面面俱到的规则库。 (19:10) 为 LLM 提供领域特定的诊断脚本,能够赋予智能体结构化的故障类别和连贯的心智模型,从而使复杂文档流水线的自动化率从 5% 的基线水平大幅提升。 (23:18)

Reading summary

Joël Quenneville argues that AI-assisted development fails when treated as a single-turn prompting exercise, requiring developers to adopt 'harness engineering' by surrounding agents with deterministic tools, lifecycle hooks, and automated feedback loops. From Single-Shot Prompts to Agent Execution Loops (0:12) Quenneville illustrates the limits of conversational prompting through an experience where generating a scoped two-day feature took roughly one hour with an LLM agent, but subsequent manual cleanup dragged on for two full days. Treating an LLM as a black box where prompts directly yield production code creates an unsustainable workflow because human developers themselves rely on iterative testing rather than writing flawless code on the first attempt. True coding agents resolve this by operating within an execution loop rather than a single prompt-response cycle. Using a basic FizzBuzz program as an example—where models often place checks for multiples of three before multiples of fifteen—Quenneville notes that agents need wrapper scripts to execute test suites, observe failures, and query the model repeatedly. By replacing human intervention with an automated loop, the agent is allowed to make mistakes in early generations and self-correct through environmental feedback. Deterministic Tooling and Hooks Outperform Markdown Instructions (8:32) When developers attempt to correct agent behavior, they frequently add rules to an `agents.md` file, which Quenneville characterizes as a fragile 'prompt-and-pray' strategy prone to probabilistic degradation as context expands. Instead of relying on markdown prompts for style and architecture, harness engineering shifts rules into deterministic mechanisms such as RuboCop, custom linters, and Rails generators. Database migrations highlight this distinction. While adding instructions in `agents.md` improved migration generation success to approximately 90%, Quenneville achieved 100% reliability by implementing deterministic lifecycle hooks. These hooks intercept direct file writes to migration directories, block the action, and supply clear error messages directing the agent to use Rails generators instead. Because agents seek the path of least resistance to fulfill their objectives, providing actionable failure reasons prevents them from creating unintended workarounds to bypass restrictions. Structuring Guidance with Bockler's Four-Quadrant Matrix (19:10) Drawing on a four-quadrant mental model developed by Brigitta Bockler, Quenneville categorizes agent guidance across two axes: feed-forward versus feedback, and deterministic versus heuristic. He asserts that guiding an agent before generation via heuristic prompts (`agents.md`) is an uphill battle compared to evaluating concrete, generated code from the middle. Consequently, `agents.md` should act merely as a lightweight routing layer, with architectural logic pushed into deterministic feedback (tests, Playwright checks) or feed-forward templates (generators). When nuanced logic resists deterministic checks, Quenneville advocates multi-stage heuristic feedback through sub-agents. His process divides reviews into structural alignment, method-level verification, and final documentation polish. However, he warns against over-constraining systems, citing Goodhart's Law: when metrics like Code Climate scores become targets, agents exploit counterproductive loopholes to satisfy the metric rather than improving code quality. Domain-Specific Scripts and Continuous Harness Retrospectives (25:00) To overcome situations where agents become lost in fragmented databases and codebases—such as a complex document pipeline that initially achieved only a 5% automation rate—Quenneville wrote domain-specific classification scripts. By categorizing documents by their progress and specific exit points, the script provided the model with a clear mental model, consistent definitions, and a shared vocabulary for root-cause analysis, raising developer and agent clarity simultaneously. To maintain long-term leverage, Quenneville advises developers against repeatedly intervening in the human loop. Instead, developers should iteratively refine the harness by asking diagnostic questions whenever errors repeat or manual intervention is needed. To streamline this process, he utilizes an automated 'retro skill' to inspect conversation transcripts and suggest missing tools, hooks, or chat divisions. Quenneville concludes that developers facing poor agent outputs must abandon single-shot prompting and focus on fixing the underlying development harness, embedding deterministic boundaries so that agents can reliably self-correct without human intervention.

Source quotes

[0:12] Joël Quenneville: If AI writes your code in an hour but cleaning it up takes two days, better prompting won't fix it. [3:28] Joël Quenneville: Treating the LLM as a black box where prompts go in and code comes out is an outdated chat-era mental model. [8:32] Joël Quenneville: As context windows grow, probabilistic adherence to instructions degrades. [13:14] Joël Quenneville: Always generate migrations using Rails generate migration [13:14] Joël Quenneville: Claude, if you try to write to the database migration directory, you are forbidden. You are not allowed to write new files to database migration. [13:14] Joël Quenneville: By making the easiest path also the correct one, you drastically reduce the chance of workarounds and guide the agent toward doing the right thing. [19:10] Joël Quenneville: It is far easier to critique existing code than to predict every program that could possibly be created. [23:18] Joël Quenneville: when a measure becomes a target, it ceases to be a good measure. [25:00] جويل كينفيل: حسنًا، حاول الآن إيجاد السبب الجذري [28:07] جويل كينفيل: كيف يمكن أن تكون هذه هي المرة الأخيرة؟ كيف يمكنني تزويد النظام بالأدوات اللازمة ليتمكن الوكيل من تصحيح أخطائه بنفسه في المرة القادمة دون الحاجة إلى تدخلي المباشر؟ [30:13] جويل كينفيل: عند مواجهة أي خطأ، لا تكتفِ بإصلاحه أو المطالبة بحل أفضل، بل أصلح النظام (harness) نفسه حتى لا يكرر الوكيل هذا الخطأ في المرة القادمة

Original transcript

[0:12] في بداية هذا العام، [0:14] بدأتُ أُفكّر بجدية [0:16] أكبر في كتابة معظم [0:17] أكوادي باستخدام نظام [0:19] إدارة التعلم (LLM). [0:26] أتذكر بوضوح أنني [0:27] بدأتُ العمل على ميزة [0:29] كان نطاقها مُقدّراً [0:31] بيومين من العمل. [0:34] عملتُ عليها مع [0:35] البرنامج، وحدّدتُ [0:37] نطاقها، وضبطتُ جميع [0:39] التفاصيل، ثم تركتُها [0:40] تعمل. بعد ساعة [0:44] تقريباً، أصبح لدينا [0:46] شيء يعمل. هذا رائع، [0:48] أليس كذلك؟ لقد أنجزتُ [0:50] عمل يومين في ساعة [0:52] واحدة. هذا سيُغيّر كل [0:54] شيء. الآن، هناك بعض [0:57] المشاكل في الجودة [0:58] الداخلية، لذا [1:00] سأُحسّنها، ثم [1:01] أُقدّمها للمراجعة. [1:03] سأبدو كبطل أمام [1:04] الفريق. حسناً، حان [1:08] وقت الغداء، وقد [1:10] أجريتُ بعض التعديلات [1:12] ، وهي تتحسّن، لكننا [1:14] لم ننتهِ بعد. لقد [1:16] أمضيتُ نصف يوم هنا، [1:18] وقضاء نصف يوم لإنجاز [1:20] عمل يومين يُعتبر [1:21] إنجازاً جيداً. حسناً، [1:25] حلّ المساء، وما زلتُ [1:26] لم أنتهِ. لقد أجريتُ [1:28] عدة جولات من المراجعة [1:30] ، وقمتُ بالكثير من [1:31] التنظيف. يتحسن الوضع، [1:33] لكنه لم يصل إلى [1:34] المستوى المطلوب [1:35] تمامًا. مع ذلك، يوم [1:37] عمل واحد مقابل يومين [1:39] من العمل المحدد [1:40] النطاق، هذا إنجاز بحد [1:42] ذاته. في اليوم التالي [1:46] ، أعود للعمل. والآن، [1:48] أنا في سباق مع الزمن، [1:50] فكل ساعة أقضيها في [1:51] التحسين، أرى قدرتي [1:53] على التأثير تتضاءل. [1:56] وبحلول المساء، أصل [1:57] أخيرًا بصعوبة إلى خط [1:59] النهاية. لقد أنجزتُ [2:02] العمل المطلوب ليومين [2:03] في يومين فقط. هذا [2:07] مُحبط للغاية. ما [2:09] الخطأ الذي حدث؟ أين [2:11] فشل وعد الذكاء [2:13] الاصطناعي؟ المشكلة [2:18] أنني قضيتُ ساعة في [2:19] كتابة الكود، ثم يومين [2:21] في محاولة إصلاح هذا [2:23] الكود الرديء الذي [2:24] أنتجه الذكاء [2:25] الاصطناعي. لذا، لا [2:29] أريد الاستمرار على [2:31] هذا المنوال. لديّ [2:32] خياران: الأول، بعد [2:34] الساعة الأولى، أرفع [2:36] طلب السحب للمراجعة، [2:38] وأترك زملائي [2:39] يتعاملون مع مشكلة [2:40] الجودة. حينها، سأبدو [2:42] كبطل. قضيت ساعة واحدة [2:44] لإنجاز عمل يومين، ثم [2:46] ألقيت بهذا العبء على [2:47] عاتق الآخرين. لا تفعل [2:49] ذلك. إن فعلت، فأنت شخص [2:52] سيء. بدلاً من ذلك، ما [2:55] أود فعله هو رفع الحد [2:57] الأدنى لما يقدمه لي [2:59] الذكاء الاصطناعي، [3:00] بحيث لا أقضي يومين في [3:02] مراجعته، بل ساعة [3:04] واحدة فقط. كيف يمكنني [3:06] فعل ذلك؟ ربما يمكنني [3:09] تحسين التوجيه. يبدو [3:11] أن جميع المحترفين [3:12] يستخدمون ملف agents.md. [3:14] ربما أضيف بعض القواعد [3:16] إليه، وهذا سيساعدني [3:17] في كتابة كود أفضل. [3:20] سينجح هذا إلى حد ما، [3:22] لكنني أخشى أن أقول [3:24] إنه فخ. هناك حد أقصى [3:28] هنا. لفهم السبب، [3:30] علينا أن نتعمق قليلاً [3:32] في السؤال: ما هو [3:34] الوكيل؟ لنفترض أننا [3:38] نريد كتابة برنامج [3:39] FizzBuzz، ونريد من نظام [3:41] إدارة التعلم (LLM) [3:43] كتابته لنا. أبسط [3:45] طريقة للقيام بذلك هي [3:46] إجراء استدعاء API [3:48] مباشر، في هذه الحالة، [3:49] واجهة برمجة تطبيقات [3:51] Anthropic. ونقول: "ها هي [3:53] المواصفات. اكتب الكود [3:55] الذي يجعلها تجتاز هذه [3:57] المواصفات." ولأننا [3:58] مبرمجون بلغة روبي، [4:00] سنكتب هذا الجزء [4:01] الصغير بلغة روبي، [4:02] ونكتب غلافًا برمجيًا [4:03] صغيرًا بلغة روبي حوله [4:05] لأنه يبدو أنيقًا. [4:08] الآن، ما فعلناه هنا [4:10] مميز نوعًا ما، لذا [4:11] أريد التركيز عليه. [4:13] هذا الغلاف البرمجي [4:14] ليس مجرد وسيلة [4:16] للتسهيل. إنه ما يُسمى [4:18] بـ "أداة الوكيل". وهو [4:20] عبارة عن كود يغلّف [4:22] استدعاءات نموذج LLM. [4:25] وهذا مهم جدًا لأن [4:26] النموذج بمفرده لا [4:28] يستطيع فعل أي شيء. إنه [4:30] مجرد عقل في وعاء. [4:32] تُدخل نصًا، فتحصل على [4:34] نص. أما أداة الوكيل، [4:37] فهي تقرأ ملفًا من [4:39] القرص. وتكتب ملفًا من [4:41] القرص. هذا كود. هذه [4:43] لغة روبي. يمكننا [4:45] إضافة أي شيء نريده [4:46] حول استدعاء النموذج. [4:48] وهذا قوي جدًا. إذن، [4:52] لدينا أداة الوكيل. [4:53] لنشغلها، ونرى كيف [4:55] تسير الأمور. يُنشئ [4:59] الوكيل شيئًا كهذا. [5:01] صحيح إلى حد ما. هناك [5:04] خطأ برمجي. لن يتم [5:05] تشغيل سطر القسمة على [5:07] 15 أبدًا لأن سطر [5:09] القسمة على 3 سيتم [5:10] تشغيله دائمًا أولًا. [5:12] إذن، كيف نمنع ذلك؟ [5:14] ربما من خلال تحسين [5:16] طريقة عرض التعليمات [5:17] البرمجية؟ أو ربما [5:19] تحسين طريقة عرضها [5:21] بشكل أفضل؟ أعتقد أن [5:26] سبب وقوعنا في هذا [5:27] الخطأ هو أننا نتعامل [5:29] مع المشكلة بنموذج [5:30] ذهني ساذج نوعًا ما [5:32] لماهية الوكيل. نحن [5:33] نفكر فيه كصندوق أسود، [5:35] نضع فيه تعليمات [5:36] برمجية، ونحصل على [5:37] التعليمات البرمجية. [5:39] إذا أردنا الحصول على [5:40] تعليمات برمجية أفضل، [5:41] فنحن بحاجة إلى [5:42] تعليمات برمجية أفضل. [5:43] وهذا ما أدى إلى تجاوز [5:45] الحد. حسنًا، إنه [5:46] نموذج ذهني يعود نوعًا [5:48] ما إلى عصر تطبيقات [5:49] الدردشة مثل GPT. لكن [5:51] الوكلاء في الوقت [5:52] الحاضر أكثر تطورًا من [5:54] ذلك بكثير. ولفهم [5:55] السبب، أريدكم أن [5:57] نتوقف ونفكر، لو [5:58] أعطيتكم نفس [5:59] التعليمات البرمجية [6:01] التي أعطيتها للوكيل [6:02] في البداية، كيف كنتم [6:04] ستحلونها يدويًا؟ هل [6:06] كنتم ستحاولون فقط من [6:08] خلال عقولكم إنشاء شيء [6:09] يفي بالمواصفات؟ ربما. [6:12] هناك بعض المطورين [6:13] الجيدين حقًا في هذه [6:14] الغرفة. لكن معظمكم [6:16] على الأرجح كان [6:17] سيُشغّل المواصفات. ثم [6:19] ، إذا أغفلتَ حالةً [6:20] استثنائية، لكنتَ [6:22] أصلحتها، وأعدتَ [6:23] تشغيل الاختبار، [6:24] ورأيتَ نجاحه. فلماذا [6:27] لا نفعل ذلك مع الوكيل [6:29] ؟ تذكر أن النموذج لا [6:30] يستطيع تشغيل [6:31] التعليمات البرمجية [6:33] بمفرده، لذا يمكننا [6:34] تشغيله بأنفسنا، [6:35] وتمرير النتائج إلى [6:37] موجه الأوامر، وهذا [6:38] يعمل. لكننا الآن [6:40] وضعنا أنفسنا في دور [6:41] المبرمج البشري. نحن [6:43] فقط نقوم بتلك الحلقة. [6:45] وهذا وقتنا. إنه أمر [6:47] آلي. من الناحية [6:49] المثالية، نريد شيئًا [6:50] آخر يقوم بذلك [6:52] تلقائيًا. وهنا يأتي [6:53] دور أداة الربط. تذكر، [6:55] إنها مجرد لغة روبي. [6:57] يمكننا وضع أي شيء [6:59] نريده هناك، بما في [7:00] ذلك حلقة. إذن، هذا هو [7:03] نفس النمط من الشريحة [7:05] السابقة، ولكن مؤتمت [7:07] في حلقة بلغة روبي. وما [7:12] فعلناه هنا هو ما [7:14] يُسمى أحيانًا حلقة [7:15] الوكيل. حسنًا، الآن [7:17] لم يعد الأمر يقتصر [7:18] على إدخال طلب إلى [7:20] نموذج ثم إلى كود، بل [7:21] يصل الطلب إلى النظام، [7:23] وقد يقرر النظام [7:24] التفاعل ذهابًا [7:25] وإيابًا مع النموذج، [7:26] والاستعلام عن [7:27] البيانات في البيئة، [7:29] واتخاذ إجراءات [7:30] داخلها، ثم يقرر تكرار [7:31] العملية. يمكنه إجراء [7:33] استدعاءات متعددة [7:34] للنموذج، والاستمرار [7:36] حتى يصل إلى شرط خروج [7:38] معين. وهذا أمر بالغ [7:41] الأهمية لأن الحلقة [7:42] تسمح للوكيل [7:43] بالاستجابة للأخطاء. [7:45] هذا يعني أن الوكيل [7:47] أصبح قادرًا على إصلاح [7:48] نفسه، وأن الجيل الأول [7:50] ليس بالضرورة أن يكون [7:51] مثاليًا. لسنا مضطرين [7:53] لمحاولة إنجاز المهمة [7:54] من المحاولة الأولى. [7:55] لا بأس إن كتب وكيلنا [7:57] كودًا جيدًا كما رأينا [7:59] في FizzBuzz، لأنه سيُجري [8:00] الاختبارات، ويُصحح [8:02] نفسه، وفي الجيل [8:03] الثاني أو الثالث أو [8:05] الرابع سيُعطينا [8:06] الإجابة الصحيحة. كل [8:08] ذلك دون تدخل بشري. [8:11] الحلقة والاختبارات [8:12] هما ما سيوجه الوكيل [8:14] إلى الخيار الصحيح. [8:18] الحلقة التي أنشأناها [8:20] مُبرمجة مسبقًا للعمل [8:21] مع الاختبارات، لكن [8:23] نسخة عامة منها تُشكّل [8:25] جوهر جميع أدوات [8:26] الاختبار التجارية [8:27] التي نستخدمها، مثل [8:29] Cursor و Cloud Code و Codex. [8:32] سأركز في بقية هذا [8:33] الحديث على هذه [8:35] الأدوات التجارية [8:36] وكيفية الاستفادة من [8:38] كونها حلقات، [8:39] للابتعاد عن أسلوب " [8:40] الطلب والتجربة"، [8:41] واستخدام هذه المعرفة [8:43] لتحسين جودة أكواد Rails [8:45] التي نكتبها. يُطلق [8:46] على هذا النوع من [8:47] العمل غالبًا هندسة [8:49] أدوات الاختبار، وهو [8:50] محور حديثنا. إذن، كيف [8:53] نُحسّن جودة أكواد Rails [8:55] ؟ لنأخذ مثالًا على [8:58] كود Ruby غير المُتقن. [8:59] نريد أن يتجنب [9:01] البرنامج كتابة أكواد [9:02] كهذه. فماذا نفعل؟ [9:05] ربما نضيف مجموعة من [9:07] القواعد إلى ملف agents.md [9:09] ؟ قد ينجح ذلك. لكن [9:12] توصيتي العامة هي أن [9:14] ملف agents.md ليس المكان [9:15] المناسب لدليل أسلوب [9:17] الكتابة. المشكلة هي [9:19] أن ملف agents.md ليس إلا [9:21] شكلًا آخر من أشكال " [9:23] الطلب والتجربة". [9:25] ستقوم أداة الربط بأخذ [9:27] ملف agents.md الخاص بك [9:29] وإضافته إلى بداية [9:30] موجه الأوامر. هذه [9:32] ميزة تُسهّل عليك [9:33] الأمر، فلا تضطر إلى [9:35] كتابته في كل مرة. [9:36] لكنها في الحقيقة لا [9:37] تختلف كثيرًا عن كتابة [9:39] القواعد في كل موجه [9:40] أوامر. كما أن هذا [9:43] الأمر احتمالي، فقد [9:44] يتبع الوكيل كل قاعدة [9:46] في ملف agent.md أو لا. [9:49] وكلما ازداد حجم سياقك [9:51] ، زادت احتمالية عدم [9:53] اتباعه لها. إذن، ما هي [9:55] الطريقة الأنسب، أو ما [9:56] يُمكن تسميته بالنهج [9:57] الوكيل أو هندسة أدوات [9:59] الربط التي يُمكننا [10:00] اتباعها؟ حسنًا، كما [10:01] هو الحال مع الاختبار، [10:03] سأتوقف قليلًا وأسألك: [10:04] كيف ستحل هذه المشكلة [10:06] يدويًا، بكتابة هذا [10:07] النوع من أكواد Ruby غير [10:08] المُتقنة؟ لقد كانت [10:10] الفرق تحل هذه المشكلة [10:11] لسنوات قبل ظهور [10:12] الذكاء الاصطناعي. [10:14] استخدمنا أدوات فحص [10:16] الأخطاء البرمجية، [10:17] وأدوات مثل RuboCop. لذا، [10:19] يُمكننا كتابة RuboCop [10:21] وتشغيله، ثم تمرير [10:22] الكود إلى موجه [10:24] الأوامر وتكرار هذه [10:25] العملية، وهذا جيد. [10:27] لكننا الآن نعود إلى [10:28] دور البنية التحتية [10:30] البشرية. كيف يمكننا [10:32] دمج هذا في نظام تجاري [10:33] ؟ لأنك لا تستطيع فتح [10:35] شفرة Claude المصدرية [10:37] ودمج RuboCop مباشرةً. [10:40] إليك طريقة بسيطة [10:41] للغاية: أضف سطرًا إلى [10:44] ملف agent.md. أضف هذا [10:45] التوجيه هناك وقل: "بعد [10:47] تغيير ملفات Ruby، شغّل [10:49] RuboCop". صحيح أن هذه [10:51] الطريقة لا تزال [10:52] احتمالية، لكن انظر [10:54] إلى حجم ملف agent.md [10:55] الصغير. لقد نقلنا كل [10:57] تلك المعرفة، وكل تلك [10:59] الأحكام التي كانت [11:01] موجودة في agent.md، إلى [11:03] شيء حتمي. RuboCop هو [11:04] المسؤول عن دليل [11:06] أسلوبك. الشيء الوحيد [11:07] الموجود في agent.md هو [11:09] توجيه التشغيل. لكن [11:11] يمكننا فعل ما هو أفضل. [11:13] إذا أردنا الوصول إلى [11:14] دقة 100%، يمكننا [11:15] الاعتماد على ما يُسمى [11:17] بالخطافات. تختلف هذه [11:19] الخطافات من نظام لآخر [11:21] ، وتخضع الأنظمة [11:22] لتحديثات مستمرة. لذا، [11:24] فإن الشفرة الدقيقة في [11:26] هذه الشريحة ليست مهمة [11:28] بقدر أهمية الفكرة. [11:30] الخطاف هو حدث في دورة [11:31] حياة البرنامج، يمكنك [11:33] كتابة كود لتنفيذه عند [11:35] وقوعه. في هذه الحالة، [11:38] سيصدر Claude حدث الإيقاف [11:40] عند محاولته الخروج من [11:42] حلقة الوكيل. سيستدعي [11:48] هذا الكود عند رغبته [11:50] في الخروج. سأجعله [11:51] يُشغّل RuboCop، وإذا فشل [11:53] RuboCop، فسأخبره أنه غير [11:54] مسموح له بالخروج، [11:56] ويجب عليه إعادة [11:57] التشغيل. ثم سيُعاد [11:59] تشغيله لمحاولة إصلاح [12:00] مشاكله. قد تعتقدون: " [12:03] حسنًا، يمكن لشرطة [12:04] التحقق حل مشاكل [12:05] الأسلوب، وهذا جيد، [12:07] لكنه لا يُحسّن الأداء [12:08] كثيرًا. لا يزال [12:10] المستوى المطلوب [12:11] منخفضًا." أشجعكم [12:13] جميعًا على أن تكونوا [12:14] طموحين للغاية، لأن [12:16] العديد من مشاكل [12:17] الجودة تتطلب تحققًا [12:18] على شكل شرطة تحقق. [12:21] تخيلوا وكيلًا يُنشئ [12:22] خطأً متعدد [12:23] المستأجرين باستمرار، [12:25] وينسى تحديد نطاق [12:27] أدوات البحث بشكل [12:28] مناسب. يمكننا إنشاء [12:32] شرط تحقق مخصص كهذا [12:34] لاكتشاف هذا الخطأ. [12:36] وإذا بدا لك هذا الأمر [12:38] معقدًا، فتذكر أن [12:39] لدينا الآن أدوات [12:40] تحليل التعلم الآلي ( [12:42] LLMs). يمكننا إنشاء هذا [12:44] في دقيقتين. هذه [12:46] الأداة هنا متطورة [12:48] نوعًا ما، وهي عامة، [12:50] وتتيح لك ضبطها [12:51] باستخدام إعدادات [12:53] كهذه. وهي تعمل بشكل [12:55] جيد جدًا. لذا، في أي [12:57] وقت تشعر فيه بالإحباط [12:58] من شيء تفعله أداة [13:00] تحليل التعلم الآلي [13:01] وتريد إيقاف هذا [13:02] السلوك، اسأل نفسك: هل [13:04] هناك طريقة لاكتشاف [13:05] ذلك باستخدام أداة فحص [13:06] ؟ وكن مبدعًا وطموحًا. [13:10] مع ذلك، هناك بعض [13:11] المشاكل التي لا يمكن [13:12] تحليلها بسهولة [13:14] باستخدام أدوات [13:15] التحليل. وإحدى [13:16] المشاكل التي تزعجني [13:17] حقًا هي عمليات [13:18] الترحيل. عمليات ترحيل [13:21] Rails لها اسم ملف محدد [13:22] جدًا، وتراه الوكلاء، [13:24] ويحاولون محاكاته، [13:26] لكنهم لا يفهمون ما [13:27] الذي يحركه، ولذلك [13:29] غالبًا ما يخطئون. إذن [13:31] ، كيف يمكننا منع [13:33] الوكيل من ارتكاب هذا [13:34] الخطأ؟ ربما نحاول [13:37] كتابة الخوارزمية في [13:39] ملف agents.md؟ إنها مجرد [13:42] محاولة سريعة وغير [13:44] فعالة. بدلًا من ذلك، [13:47] سأسألك مرة أخرى: كيف [13:48] تحل هذه المشكلة [13:50] يدويًا؟ كيف يتجنب كل [13:51] مطور في هذه الغرفة [13:53] الخطأ عند كتابة هذا [13:54] الرقم؟ والجواب هو: [13:57] أنا لا أكتب هذا الرقم [13:59] ، وأنت لا تكتبه. نحن [14:00] نستخدم مولدات Rails [14:02] لهذا الغرض. فلماذا لا [14:04] نجعل النموذج يقوم [14:05] بذلك؟ يمكننا إضافة [14:07] توجيه في ملف agents.md ينص [14:08] على: "أنشئ عمليات [14:10] الترحيل دائمًا [14:11] باستخدام Rails generate [14:12] migration". هذا أفضل بكثير [14:15] من محاولة نسخ [14:16] الخوارزمية نصيًا في [14:18] ملف Markdown. وقد وجدت أن [14:20] هذه الطريقة تنجح [14:22] بنسبة 90%تقريبًا. ولكن [14:24] ، يمكننا تحسينها. إذا [14:26] أردنا الوصول إلى 100%، [14:27] يمكننا الاعتماد على [14:28] الخطافات مرة أخرى. [14:30] يتم تشغيل هذا الخطاف [14:32] في كل مرة يحاول فيها [14:33] كلود كتابة ملف جديد. [14:35] وبدلًا من تضمين الكود [14:36] الخاص بي، فإنه يستدعي [14:37] ببساطة نصًا برمجيًا [14:38] مكتوبًا بلغة Ruby. يقول [14:40] هذا النص البرمجي: " [14:41] كلود، إذا حاولت [14:42] الكتابة إلى دليل [14:43] ترحيل قاعدة البيانات [14:44] ، فأنت ممنوع. لا يُسمح [14:46] لك بكتابة ملفات جديدة [14:47] إلى ترحيل قاعدة [14:48] البيانات". ثم يقوم [14:50] بشيء مثير للاهتمام، [14:51] حيث يُظهر رفضًا أو [14:53] سببًا. بدلاً من [14:55] الكتابة هنا، يُطلب [14:57] منك تشغيل المُولِّد. [15:00] وهذا مهم لأن لكل عميل [15:02] هدفًا. إذا علم العميل [15:04] أنه بحاجة إلى ترحيل [15:06] لتحقيق هذا الهدف، [15:07] وقمتَ بحظره، فسيحاول [15:09] إيجاد طريقة للتحايل [15:10] على الحظر. وهو بارعٌ [15:12] في ذلك. من خلال إظهار [15:14] رسالة خطأ وجعل المسار [15:16] الأسهل هو الخيار [15:17] الصحيح، فإن ذلك يقلل [15:19] بشكل كبير من احتمالية [15:21] محاولته التحايل على [15:22] الحظر، ويدفعه بدلاً [15:24] من ذلك إلى القيام [15:25] بالشيء الصحيح. لأن [15:27] العملاء يفضلون [15:28] المسار الأسهل. ومرة [15:30] أخرى، يمكننا أن نكون [15:32] طموحين هنا. فكّر في [15:34] جميع أنواع الأشياء [15:35] التي قد ترغب في تسجيل [15:36] ثوابت حول التعليمات [15:37] البرمجية الخاصة بك، [15:39] والأنماط التي يمكن [15:40] تسجيلها في مُولِّد. [15:41] هل لديك دليل تريد أن [15:43] ترث منه جميع وحدات [15:45] التحكم الجديدة فئة [15:46] أساسية؟ لكنه يختلف عن [15:48] الأنماط الموجودة في [15:50] تطبيقك، لذا فإن LLM [15:51] يُخطئ في ذلك. أو ربما [15:53] تريد التأكد من أن كل [15:55] وحدة تحكم تأتي مع [15:57] كائن سياسة للتفويض. [16:00] ضع ذلك في مُولِّد. إذا [16:02] كنتم قد حضرتم محاضرة [16:03] راشيل هنا بالأمس، فقد [16:05] شرحت بالتفصيل كل [16:06] الأشياء الرائعة التي [16:07] يمكنكم فعلها [16:08] باستخدام المولدات. [16:09] إذا فاتكم ذلك، أنصحكم [16:11] بشدة بمشاهدتها عند [16:13] صدور التسجيلات. وأود [16:16] أن أشير إلى أمر مهم [16:18] بخصوص عملنا، وهو أننا [16:20] كنا نستخرج المنطق [16:22] والحكم من أي نظام [16:23] فاعل، من نموذج التعلم [16:25] المنطقي (LLM)، ونضعهما [16:27] في أدوات حتمية. [16:30] وبطريقة ما، عندما [16:31] فعلنا ذلك، ورغم [16:33] انخفاض مستوى الذكاء، [16:35] أصبح النظام ككل أكثر [16:37] ذكاءً واتساقًا. وهذه [16:40] خاصية مثيرة للاهتمام [16:42] حقًا. مع ذلك، هناك [16:44] أوقات سنصل فيها إلى [16:45] حدود هذا الأسلوب. [16:47] هناك أوقات يصعب فيها [16:48] رصد بعض الأمور المهمة [16:50] بشكل حتمي. نحتاج [16:51] حينها إلى أسلوب [16:52] استدلالي. وقد نرغب في [16:54] الاعتماد على شيء أقرب [16:55] إلى نموذج التعلم [16:56] المنطقي (LLM). إذن، كيف [16:57] يمكننا فعل ذلك؟ مرة [16:59] أخرى، ربما حان الوقت [17:01] لاستخدام ملف agents.md. [17:03] ولكن، كما ذكرت، هذا [17:04] مجرد حل سريع يعتمد [17:06] على الحظ. وجدتُ أن وضع [17:08] قواعد البرمجة في ملف [17:10] agents.md لم يُحقق نتائج [17:11] جيدة، على الأقل في [17:13] قواعد بياناتي [17:14] البرمجية. إذن، ما [17:16] البديل؟ أُفضّل [17:18] الاعتماد على مهارات [17:20] مراجعة LLM. غالبًا ما [17:22] يأتي نظامك مزودًا [17:23] بمهارة مراجعة مُدمجة [17:24] ، وهي فعّالة جدًا. [17:26] يمكنك إنشاء مهاراتك [17:27] الخاصة، ولكن إن فعلت، [17:29] أنصحك بجعلها أكثر [17:30] تحديدًا. لا تُحاول [17:31] ببساطة وضع مجموعة من [17:33] النصائح البرمجية [17:34] العشوائية في ملف [17:35] المهارة. بدلًا من ذلك [17:36] ، ركّز على نظرية [17:38] مُحددة لماهية الكود [17:39] الجيد. في حالتي، [17:41] أنشأتُ ثلاث مهارات [17:42] بناءً على طريقتي في [17:43] مراجعة طلبات مراجعة [17:45] المستخدم (UPRs). إذًا، [17:47] هناك ثلاث مراحل: [17:48] مراجعة هيكلية شاملة، [17:50] للتأكد من مُلاءمة [17:51] الحل للمشكلة؛ مراجعة [17:53] تفصيلية لكل طريقة على [17:55] حدة؛ ثم مرحلة نهائية [17:57] للتحسين، حيث أُراجع [17:58] مدى سهولة قراءة الكود [18:00] وتوثيقه. الآن، [18:03] سنستخدم هذه المهارات. [18:05] سنجعل LLM يكتب الكود، [18:07] ثم سنستدعي هذه [18:08] المهارات لمراجعته. [18:10] وهذا يُجدي نفعًا، [18:11] لكنه يُعيدنا إلى [18:12] دورنا البشري في تنفيذ [18:14] العمليات. بدلًا من [18:15] ذلك، نريد التفكير في [18:17] كيفية جعل النظام [18:18] يُؤتمت هذه العملية. [18:20] الآن، سنحرص على تشغيل [18:21] هذه المهارات في وكلاء [18:23] فرعيين. هذا يُساعد في [18:25] تقليل التحيز. وعندما [18:27] نبدأ بالحديث عن وكلاء [18:28] يتواصلون مع وكلاء [18:30] آخرين، فإننا ندخل [18:31] عالم التنسيق. هذا ليس [18:34] تنسيقًا حقيقيًا، [18:35] ولكنه يُحاكيه، وهو [18:37] كافٍ لهذا النوع من [18:39] المهام. إنها مجرد [18:40] مهارة بسيطة. يمكنك [18:42] استدعاؤها يدويًا، [18:43] فتقول: "نفّذ العمل [18:44] الذي طلبته منك، ثم [18:45] شغّل الوكيل الفرعي [18:46] بهذه الطريقة، وشغّل [18:47] هذا الوكيل الفرعي [18:48] الآخر بهذه الطريقة، [18:49] ونفّذ هذا الأمر. [18:50] انتهى الأمر." خمسة [18:52] أسطر. إذا كنت ترغب في [18:54] القيام بشيء أقرب إلى [18:56] التنسيق الحقيقي، [18:57] فيمكنك فعل ذلك في Cloud [18:58] Code باستخدام سير العمل [19:00] الديناميكي أو Ultra Code. [19:02] أعلم أن بعض الأدوات [19:03] الأخرى تتضمن ميزات [19:04] مدمجة، وهناك أيضًا [19:05] بعض الأدوات الخارجية [19:06] التي يمكنك استخدامها. [19:10] قد يتساءل البعض منكم [19:12] عند قراءة هذا: "لحظة! [19:14] لقد ذكرتَ للتو أن وضع [19:16] قواعد الاستدلال في [19:18] ملف agent.md مجرد عملية [19:20] عشوائية. ما الفرق بين [19:21] وضعها في مهارة؟ ألم [19:23] تقم فقط بتغيير مكانها [19:26] ؟" وهنا يبرز فرقٌ هامٌ [19:29] للغاية. تكمن الصعوبة [19:31] في استخدام ملف agent.md، [19:33] أي عملية "التلقين [19:34] والدعاء"، في أنك [19:36] عندما تطلب من مبرمج [19:37] لغة برمجة (LLM) بناء [19:39] برنامج لك، فأنت [19:40] تُعطيه تعليمات مسبقة [19:42] ، وتطلب منه اختيار [19:43] برنامج من بين جميع [19:45] البرامج الممكنة. [19:47] وكأنك تقول: "أعطني [19:48] برنامجًا يُلبي جميع [19:50] هذه المتطلبات". وهذا [19:52] طلبٌ صعبٌ للغاية. أنت [19:55] تحاول توجيه البرنامج [19:57] بإعطائه تعليمات، [19:58] لكنك تُوجّهه من خلف [20:00] خط البداية. بدلًا من [20:03] ذلك، أجد أنه من [20:04] الأفضل التوجيه من [20:06] منتصف الطريق. من [20:08] الأسهل بكثير أن نقول: [20:09] "لدينا بعض القواعد [20:11] الإرشادية، وبدلاً من [20:13] تطبيقها على جميع [20:14] البرامج الممكنة، [20:15] دعونا نطبقها على [20:17] برنامج محدد قمتُ [20:18] بإنشائه بالفعل. من [20:19] الأسهل بكثير اكتشاف [20:21] الأخطاء في برنامج [20:22] كتبته الآن مقارنةً [20:24] بجميع البرامج التي [20:25] يُمكنني إنشاؤها في [20:27] المستقبل." لكنني أريد [20:29] أن أتناول هذه الأفكار [20:31] وأضعها في سياق أوسع. [20:33] هناك نموذج ذهني [20:34] يعجبني حقًا، وهو من [20:36] ابتكار بريجيتا باكلر. [20:37] تتخيل فيه آليات [20:39] مختلفة لتوجيه [20:40] العوامل لتتناسب مع [20:42] نظام رباعي الأبعاد. [20:44] لدينا آليات يمكنها [20:46] التوجيه إما عن طريق [20:48] التغذية الأمامية، أي [20:50] قبل عملية الإنشاء، أو [20:52] عن طريق التغذية [20:53] الراجعة، أي بعد عملية [20:55] الإنشاء. ويمكن أن [20:57] تكون هذه الآليات [20:59] حتمية، أي حسابية، أو [21:01] استدلالية. على سبيل [21:05] المثال، برنامج RuboCop [21:06] الذي استخدمناه هو [21:07] آلية حسابية تعتمد على [21:09] التغذية الراجعة. أما [21:10] المولدات فهي آلية [21:12] تعتمد على التغذية [21:13] الأمامية. ويقع تقييم [21:15] العوامل في هذا الربع [21:16] الاستدلالي الذي [21:17] يعتمد على التغذية [21:19] الراجعة. قد تتساءلون [21:21] الآن، لقد استعرضنا [21:22] ثلاثة أمثلة فقط، [21:24] بينما يوجد أربعة [21:25] أرباع. ما الذي يحتويه [21:27] ربع الاستدلال [21:28] الأمامي؟ إنه ملف [21:30] agents.md، وهو من الأدوات [21:32] الأساسية لدينا. وأودّ [21:35] أن أوضح أن هذا الربع [21:36] جزء مهم جدًا من عملية [21:38] توجيه الوكلاء، ولكنه [21:40] ليس الوحيد. بشكل عام، [21:43] أجد أنه من الأفضل نقل [21:45] عملية التقييم من ربع [21:46] الاستدلال الأمامي [21:48] إلى الأرباع الثلاثة [21:49] الأخرى. شخصيًا، أفضل [21:51] أن يكون ملف agents.md [21:52] بسيطًا جدًا، أشبه [21:53] بطبقة توجيه، بدلًا من [21:55] أن يكون مجرد تفريغ [21:57] لأفكاري. لذا، دعونا [22:00] نبدع. ما الذي يمكننا [22:03] إضافته إلى هذا الربع [22:04] كمطوري Rails؟ حسنًا، [22:07] لقد رأينا RuboCop بالفعل [22:08] ، ولكن من بين الأشياء [22:10] الأخرى التي يمكننا [22:11] إضافتها Reek و Flog و Code [22:13] Climate، وهي أدوات عامة [22:14] لتقييم جودة الكود. [22:15] كما تندرج أدوات فحص [22:17] الأمان ضمن هذا الربع، [22:18] بالإضافة إلى [22:19] الاختبارات، [22:19] والأساليب التي تسمح [22:21] للوكيل بالتحقق من [22:22] عمله، مثل مراجعة [22:23] السجلات أو فتح متصفح [22:24] باستخدام Playwright. حسنًا [22:26] ، بالإضافة إلى [22:27] المولدات في التغذية [22:29] الأمامية، يمكننا [22:30] أيضًا استخدام أشياء [22:31] مثل نصوص الإعداد أو [22:33] القوالب. أنا من أشد [22:34] المعجبين بالقوالب. [22:35] حسنًا، ليس لدينا وقت [22:37] للخوض فيها بالتفصيل، [22:38] لكن تعالَ وانظر إليّ [22:39] لاحقًا لنتحدث عنها [22:41] لأنني قمتُ بأشياء [22:42] ممتعة حقًا [22:42] باستخدامها. تحدث جميع [22:45] أنواع المراجعة [22:47] والتحليل القائم على [22:48] الفاعلية في ربع [22:50] التغذية الراجعة [22:51] الاستدلالية. وأخيرًا [22:54] ، في ربع التغذية [22:56] الأمامية الاستدلالية [22:57] ، لدينا المطالبات، [22:59] ولكن لدينا أيضًا [23:00] أشياء مثل المستندات [23:02] الثابتة أو شفرة [23:03] المصدر القريبة. إذا [23:05] حضرتَ محاضرة كينزي [23:06] سابقًا، فقد تعمقت [23:07] كثيرًا في بعض الأشياء [23:09] التي يمكنك القيام بها [23:10] لاستخدام شفرة المصدر [23:12] كآلية توجيه. الآن، قد [23:14] ترى كل هذا وتتحمس [23:16] لإضافته إلى تطبيقك. [23:18] ودعني أحذرك. هذا هو [23:21] قانون جودهارت. عندما [23:22] يصبح المقياس هدفًا، [23:24] فإنه يتوقف عن كونه [23:25] مقياسًا جيدًا. هذا ما [23:27] طُوّر لإدارة البشر، [23:29] ولكنه ينطبق أيضًا على [23:30] الأنظمة الذكية. لقد [23:32] وجدتُ أنه عندما [23:33] أُقيّد أنظمتي الذكية [23:35] بشدة، تبدأ بمحاولة [23:37] التحايل على القواعد. [23:38] لذا، خاصةً إذا كنتَ [23:40] تستخدم أداةً مثل Code [23:42] Climate لمنحها أعلى درجة [23:43] ممكنة، فإن تقييدها [23:45] بشدة سيجعل أنظمتك [23:46] الذكية تجد طريقةً [23:48] لتحقيق هذه الدرجة [23:49] بطريقةٍ لا تُرضيك. [23:51] لذلك، امنحها بعض [23:53] المرونة، وستحصل على [23:54] نتائج أفضل. هناك [23:57] تقنيةٌ أُعجب بها [23:58] كثيرًا، وهي البرامج [23:59] النصية المُخصصة [24:01] لمجالٍ مُحدد، وأودّ [24:02] أن أتعمق فيها قليلًا. [24:04] لقد كنتُ أعمل مؤخرًا [24:06] على مشروعٍ نستورد فيه [24:08] مجموعةً من المستندات [24:10] ، ونُعالجها، ونربطها [24:11] ببياناتٍ أخرى في [24:13] نظامنا، ثم ننشرها [24:14] داخليًا. وقد استخدمتُ [24:18] هذا النهج، وهو [24:19] البرامج النصية [24:20] المُخصصة لمجالٍ [24:21] مُحدد، لمحاولة رفع [24:23] مستوى أداء الذكاء [24:24] الاصطناعي في هذا [24:25] السياق. المشكلة هي أن [24:27] معدل أتمتة معالجة هذه [24:30] المستندات لا يتجاوز 5% [24:32] ، وأحتاج أن يصل إلى 100% [24:34] . لقد وجّهتُ برنامجًا [24:36] لإدارة دورة حياة [24:36] البيانات (LLM) نحو هذا [24:38] النظام، وهو قادر على [24:39] رؤية كل شيء. لديه [24:40] بيانات إنتاجية [24:41] حقيقية. ولكن للأسف، [24:43] لا يُقدّم لي نتائج [24:45] جيدة. فهو يُغفل [24:46] الصورة الكاملة. يرى [24:48] البرنامج أجزاءً من [24:49] قاعدة البيانات هنا، [24:51] وجزءًا من مستند هناك، [24:52] وحتى بعض شفرة المصدر [24:53] هنا، ولكن في كل مرة [24:55] أطرح عليه أسئلة أو [24:56] أطلب منه البحث عن [24:57] الأسباب الجذرية، وهي [24:58] أسباب متعددة، لا [25:00] يُقدّم لي صورة واضحة، [25:01] بل يُعطيني إجابات [25:02] متناقضة. إذن، كيف [25:04] يُمكنني تحسين الوضع؟ [25:06] بصفتي إنسانًا، [25:07] يُمكنني تنظيم هذه [25:09] الفوضى لأن لديّ [25:10] نموذجًا ذهنيًا. ما [25:13] يحدث هنا هو أننا نعمل [25:15] ضمن مسار مُتسرّب. [25:17] تنتقل البيانات من [25:19] خطوة إلى أخرى، وقد [25:20] تفشل لأسباب مُختلفة [25:22] في مراحل مُتعددة. لذا [25:23] ، كتبتُ برنامجًا [25:25] نصيًا يُصنّف جميع [25:26] المستندات في مجموعة [25:27] بيانات مُحددة بناءً [25:29] على مدى تقدمها في [25:30] مسار المعالجة، ونقطة [25:32] توقفها. ثمّ، وجّهتُ [25:33] البرنامج النصي إلى [25:35] نظام إدارة التعلم (LLM) [25:36] وقلتُ: "حسنًا، حاول [25:37] الآن إيجاد السبب [25:38] الجذري". ويا للعجب، [25:40] لقد تحسّن كثيرًا. [25:42] وذلك لعدة أسباب. [25:45] أولًا، وجود تعريفات [25:46] ثابتة يعني أن مجموعات [25:48] البيانات أصبحت قابلة [25:50] للمقارنة. في السابق، [25:51] لم يكن لديه حتى تعريف [25:53] مُوحّد لما يُعتبر [25:54] خروجًا ناجحًا من مسار [25:56] المعالجة، ولذلك كان [25:57] يتعارض رأي كل وكيلين [25:58] عند محاولتهما التوصل [26:00] إلى سرد مُعين. ثانيًا [26:02] ، أصبح لديه الآن لغة [26:04] أكثر شمولية للتفكير [26:06] عند إجراء التحليل. في [26:07] السابق، كان يُحاول [26:09] فقط إيجاد أنماط بين، " [26:10] أوه، هذا العمود في [26:12] هذا الجدول أو هذا [26:13] الجزء من السطر في [26:14] الكود". أما الآن، فهو [26:16] يُفكّر من حيث [26:17] التصنيفات والمجموعات [26:19] ومسارات المعالجة [26:20] ونقاط الخروج. لقد [26:22] منحته مجموعة أغنى من [26:23] الأدوات الأساسية [26:24] للتفكير والتواصل [26:25] بشأن العمل الذي أردتُ [26:27] منه القيام به. [26:29] وأخيرًا، يُعدّ [26:30] التصنيف بحد ذاته [26:32] مفيدًا للغاية. فعند [26:33] إجراء تحقيق بدءًا من [26:35] مجموعة محددة من [26:36] المستندات التي فشلت [26:38] لنفس السبب، تُعتبر [26:40] هذه طريقة رائعة [26:41] للتعمق في البحث. ولكن [26:44] هذا لا يقتصر على [26:45] الوكلاء فقط، فوجود [26:47] برنامج نصي مُخصّص [26:48] للمجال مفيد جدًا [26:49] للمطورين أيضًا. ربما [26:51] لاحظتم أن هذا ينطبق [26:53] على جميع الأمور [26:54] الأخرى التي شاركتها. [26:56] فامتلاك مولدات أفضل، [26:57] ووجود أدوات Rubocop أفضل [26:59] ، كلها أمور مفيدة [27:00] للوكلاء، لكنها [27:01] تُحسّن تجربة [27:02] المطورين أيضًا. وهذا [27:03] ينطبق بشكل خاص على [27:05] البرامج النصية [27:06] المُخصّصة للمجال. لقد [27:07] سعينا إلى رفع مستوى [27:08] برنامج إدارة التعلم، [27:10] وفي الوقت نفسه، رفعنا [27:12] مستوى جميع المطورين [27:13] في فريقنا. أنا متفائل [27:15] جدًا بشأن البرامج [27:16] النصية المُخصّصة [27:17] للمجال تحديدًا لأنها [27:18] تُساعد في معالجة نوع [27:20] من الثغرات المعرفية [27:21] التي غالبًا ما تكون [27:22] موجودة لدى جميع [27:23] المطورين في فريقنا. [27:25] إنها جميعًا معرفة [27:26] ضمنية. لذا، أخذتُ [27:30] مُخرجات البرنامج [27:31] النصي الخاص بي [27:32] ووجهتها إلى أداة عرض [27:34] البيانات، ثم حصلتُ [27:35] على شيء رائع كهذا. [27:37] تصور دقيق لحالة خط [27:38] أنابيب البيانات [27:39] الخاص بي في أي لحظة. [27:41] ويمكنني من خلاله [27:42] تحديد مواطن الخلل، [27:43] والنقاط التي تحتاج [27:44] إلى مزيد من التدقيق، [27:45] والجوانب التي تستحق [27:47] التحقيق. هذا النوع من [27:51] العمل سهل للغاية في [27:53] Rails بفضل Rake. لدينا [27:55] أيضًا نصوص Shebang [27:56] البرمجية في Rails. [27:58] يمكننا كتابة نصوص [27:59] برمجية جانبية، وتحصل [28:00] هذه النصوص على جميع [28:02] الميزات التي نحتاجها [28:03] من Rails، إطار العمل. [28:07] لقد رأينا طرقًا عديدة [28:08] لتحسين أداء خط [28:10] الأنابيب من خلال [28:11] قراءة الإشارات [28:12] المحيطة به وتوجيهه. [28:16] لكن هذا يتطلب بيئة من [28:18] التحسين المستمر. [28:21] لدينا كل هذه الآليات [28:22] المختلفة، وقد يغريك [28:24] دمجها جميعًا في [28:25] تطبيقك دفعة واحدة، [28:26] لكنني لا أنصح بذلك. [28:28] بدلًا من ذلك، حاول [28:30] التركيز على المشكلات [28:31] التي واجهتها. في كل [28:33] مرة تحتاج فيها إلى [28:34] تصحيح خطأ ما، اسأل [28:35] نفسك: كيف يمكن أن تكون [28:37] هذه هي المرة الأخيرة؟ [28:39] كيف يمكنني تزويد [28:40] النظام بالأدوات [28:41] اللازمة ليتمكن [28:42] الوكيل من تصحيح [28:43] أخطائه بنفسه في المرة [28:44] القادمة دون الحاجة [28:46] إلى تدخلي المباشر؟ [28:48] عندما تجد نفسك عالقًا [28:49] في هذه الدوامة [28:50] البشرية، حاول الخروج [28:52] منها. هل يمكن لنظام [28:53] إدارة التعلم الآلي (LLM [28:55] ) الوصول مباشرةً إلى [28:56] أداة ما وقراءة أو [28:57] كتابة البيانات بنفسه [28:58] ؟ إليك بعض الأسئلة [29:01] التي قد ترغب في طرحها [29:02] لتحسين نظامك: أين كان [29:04] عليّ التدخل؟ ما [29:05] الإشارات المفقودة؟ [29:06] هل كان عليّ نسخ أي شيء [29:08] يدويًا ذهابًا [29:09] وإيابًا؟ هل هناك أي [29:11] شيء في جانب الوكيل (MD) [29:12] كان من الممكن تنفيذه [29:14] بشكل أفضل وبشكل حتمي؟ [29:15] هل تدهورت المحادثة؟ [29:17] هل كان من الممكن [29:18] تقسيمها إلى محادثات [29:20] متعددة؟ هل تكررت أي [29:22] أخطاء؟ إذا كنت مثلي، [29:25] فإن طرح كل هذه [29:26] الأسئلة يتطلب جهدًا [29:28] كبيرًا. وأحيانًا أكون [29:29] كسولًا عندما أكون [29:30] مطورًا. لذلك، أقوم [29:32] بتجميعها في مهارة [29:33] استرجاعية. أقوم [29:35] بتشغيلها في جلسة [29:36] طويلة بعد تفاعلي مع [29:37] نظام إدارة التعلم [29:38] الآلي، حيث تحلل سجلّي [29:40] وتقترح عمليات أتمتة [29:41] يمكنني القيام بها. [29:43] يمكنك الاطلاع عليها [29:45] على حسابي في GitHub. [29:46] حسنًا، joelq/skills. لكن من [29:49] المحتمل أن يكون هذا [29:51] موجودًا بالفعل في [29:52] مستودعك اليوم. لا [29:54] أعرف إن كان أحد هنا [29:55] يستخدم مهارات مات [29:57] بوكوك. لقد أصدر [29:58] مؤخرًا، أعتقد [29:59] الأسبوع الماضي، [30:00] مهارة تؤدي نفس [30:01] الوظيفة، واسمها [30:03] أيضًا retro. لذا، من [30:04] المحتمل أنك إذا كنت [30:05] تستخدم مهاراته، [30:06] فستجدها موجودة [30:07] بالفعل في مستودعك [30:08] اليوم، ويمكنك فعل ذلك [30:09] بعد جلسة الذكاء [30:10] الاصطناعي التالية. [30:13] بالعودة إلى نفسي في [30:15] يناير، كنت محبطًا في [30:17] نهاية ذلك اليوم الأول [30:18] ، أتساءل أين تذهب كل [30:20] جهودي؟ ماذا كنت سأقول [30:22] لنفسي لأحسن أدائي؟ [30:26] حسنًا، أولًا، أحتاج [30:27] إلى تغيير طريقة [30:29] تفكيري، نموذجي [30:30] الذهني لما يحدث [30:31] للوكيل. لا مزيد من [30:33] التلقين والانتظار. [30:34] بدلًا من ذلك، تذكر أن [30:36] الوكيل عبارة عن حلقة، [30:38] وأن الانخراط في هذه [30:39] الحلقة يسمح له بتصحيح [30:41] نفسه وكتابة كود أفضل [30:43] دون تدخل بشري. ثانيًا [30:46] ، في كل مرة أواجه خطأً [30:48] ، لا أصلحه فقط. لا [30:50] تكتفِ بالمطالبة بحل [30:52] أفضل، بل حاول إصلاح [30:54] النظام نفسه حتى لا [30:55] يكرر هذا الخطأ في [30:57] المرة القادمة. هذا هو [30:59] جوهر هندسة البرمجيات [31:01] ، وهذه هي طريقتي في [31:03] تحسين كودي. وهذه هي [31:05] طريقتكم جميعًا [31:06] لتحسين كودكم. شكرًا [31:10] لحضوركم هذه المحاضرة. [31:12] اسمي جويل كينفيل، [31:14] وأنا مطور رئيسي في [31:15] شركة Thoughtbot. إذا كنتم [31:17] مهتمين بتنفيذ عمليات [31:18] أتمتة معقدة، مثل مسار [31:20] معالجة المستندات [31:21] الذي تحدثت عنه، أو [31:22] ربما ترغبون فقط في [31:24] الحصول على بعض [31:25] المساعدة لتحسين ما [31:26] تُنشئه برامجكم، [31:27] فتواصلوا معي ومع [31:29] زملائي في Thoughtbot. [31:30] يسعدنا العمل معكم [31:31] ومساعدتكم على تحقيق [31:32] أقصى استفادة من [31:33] الذكاء الاصطناعي. أنا [31:35] أيضًا أحد مقدمي [31:36] بودكاست Bike Shed على [31:38] bikeshed.fm. لن تُطرح أي [31:39] أسئلة بعد هذه [31:40] المحاضرة، لكنني [31:41] سأكون متواجدًا في [31:42] الزاوية هناك إذا [31:43] رغبتم في التحدث معي. [31:44] اضطررتُ لحذف الكثير [31:45] من هذه المحاضرة. هناك [31:46] الكثير من الأشياء [31:47] المثيرة التي يمكننا [31:48] القيام بها باستخدام [31:49] الذكاء الاصطناعي [31:50] للحصول على كود برمجي [31:51] بجودة أفضل، وأود أن [31:51] أسمع منكم. شكرًا لكم.