Collaborative AI Programming: From Requirements Co-creation to Code Auditing
While AI programming tools make it easy to generate code, stable software delivery requires clear requirements, reasonable module boundaries, and thoroughly verified code. This article explores a collaborative AI programming method that separates requirements analysis, solution design, code implementation, code auditing, and test verification. By leveraging different AI assistants to collaborate and constrain each other, developers can reduce rework costs and improve the reliability of software delivery.
With the development of AI programming tools, more people without a systematic programming background are attempting to independently build websites, management systems, and automation applications. However, “generating code” is not equivalent to “stable software delivery.” The truly difficult parts usually lie not in how to write a specific function, but in whether the requirements are clear, whether module boundaries are reasonable, whether edge cases are considered, and whether the generated code is verified.
A relatively reliable approach is not to hand over all work to a single AI assistant, but to split requirements analysis, solution design, code implementation, code auditing, and test verification, assigning different roles to different tasks. The entire workflow can be understood as:
Requirements Discussion → Solution Finalization → Constraint-based Development → Modular Implementation → Independent Auditing → Automated Testing → Manual Acceptance → Fix and Iterate
The core idea of this method is to enable AI tools to form a relationship of “collaboration and constraint,” rather than letting a single tool play freely from start to finish.
1. First Clarify the Responsibilities of Different AI Assistants
In practice, you can prepare two types of AI programming assistants with different capabilities.
The first type is more suitable for continuous conversation, explaining solutions, organizing documentation, and directly generating development results. It can advance the project based on context, making it suitable for the “implementer” role.
The second type is more suitable for raising objections, checking for omissions, analyzing risks, and reviewing code. It may not be directly responsible for final development, but it can act as a “reviewer” or “auditor” to help discover vulnerabilities in the solution.
It is important to note that this division of labor does not mean that one type of tool is inherently stronger than the other, but rather that software development itself encompasses multiple distinct tasks. Requirements understanding, code generation, logic review, and test design have different requirements for context organization and ways of thinking. Dividing these tasks helps reduce situations where a single tool self-confirms and ignores problems.
2. Start with Requirements Discussion, Not Direct Code Generation
The starting point of failure for many projects is the user providing only a vague requirement, such as “build a customer management system” or “develop an automated backend.” Such descriptions cannot directly guide development because they lack a large amount of critical content:
- Which users the system serves;
- What permissions users have;
- How core business processes flow;
- What fields need to be saved in the data;
- How to handle input errors;
- Whether operation logs are needed;
- How pages display across different screen sizes;
- Whether data deletion allows recovery;
- How the system prompts users when exceptions occur.
Therefore, the first step should be to have the AI assistant continuously ask questions around the requirements, rather than immediately starting to write code. You can require it to ask detailed questions regarding user roles, business objectives, functional scope, data models, permission control, exception handling, and acceptance criteria.
During the discussion, it is recommended to organize the requirements into a “Development Constraints and Implementation Guide” document. The document should not merely list features; it should also include the following content:
1. Project Objectives
Explain what problems the system solves and what it does not solve. Clarifying the scope prevents the continuous addition of irrelevant features during development.
2. User Roles
List the permission differences among regular users, administrators, or other roles, and specify which operations require authentication.
3. Functional Modules
Split modules according to business responsibilities, such as user management, data entry, query and filtering, statistical display, system configuration, and log recording.
4. Data Structure
Describe main entities, field meanings, field types, whether they are required, default values, and relationships between entities. Even if formal database scripts are not required initially, data relationships should be clearly explained.
5. Business Rules
For example, how states change, under what conditions submission is allowed, how duplicate data is handled, whether deletion operations require secondary confirmation, and whether different roles can perform certain operations.
6. Acceptance Criteria
Every feature should have verifiable results. For instance, “can be saved after entering valid information,” “gives a clear prompt when a duplicate ID is entered,” or “users without permission cannot access the management page.”
The more specific this document is, the lower the probability of deviations during subsequent code generation. It effectively serves a triple role as a project contract, a design specification, and a testing basis.
3. Put the Solution Through Multi-round Adversarial Discussions
Once the initial draft of the requirements document is complete, do not rush into development. Have an AI assistant review the document, focusing on finding the following issues:
- Whether requirements contradict each other;
- Whether there are features that are impossible to implement or incompletely described;
- Whether the data model omits key fields;
- Whether the permission design presents privilege escalation risks;
- Whether exception flows lack handling methods;
- Whether future expansions will easily cause massive rework;
- Whether the acceptance criteria are clear enough.
Subsequently, have the assistant originally responsible for organizing requirements respond to these opinions point by point. For areas where the two disagree, require them to provide reasons, applicable premises, and potential impacts, rather than simply outputting “suggest adopting Option A.”
After several rounds of discussion, a finalized document can be retained while recording important decisions. For example:
- Why soft delete is used instead of direct deletion;
- Why a certain operation requires administrator confirmation;
- Why a certain module does not currently support batch processing;
- Why certain data is view-only and cannot be modified.
The value of recording decisions lies in the ability to trace the basis when disputes arise later, preventing AI assistants from repeatedly changing the design across different conversations.
4. Use Project Constraint Files to Control Development Behavior
Before formal coding, a project-level constraint file should be prepared. It does not need to be bound to a specific tool; its core purpose is to clarify development rules for the AI assistant to continuously follow in subsequent tasks.
The constraint file can include:
- Project directory structure;
- Programming languages and framework types used;
- Naming conventions;
- Principles for splitting components or modules;
- Data access methods;
- Error handling requirements;
- Logging requirements;
- Security considerations;
- Organization of test files;
- Files that cannot be modified;
- Checks that must be executed before each commit.
For example, you can stipulate:
- Do not arbitrarily rewrite existing modules just to implement a small feature;
- When modifying data structures, validation logic and tests must be updated synchronously;
- All user input must undergo legality verification;
- Important operations must return clear success or failure results;
- Do not hide errors through silent exception catching;
- Upon completing each module, explain the modified files, implemented logic, and known risks.
The purpose of the constraint file is not to limit the creativity of the AI assistant, but to reduce the possibility of it arbitrarily introducing new patterns, new dependencies, or inconsistent writing styles into the project.
5. Adopt Modular Development, Avoid Generating the Entire Project at Once
Asking an AI assistant to generate a complete system all at once seems highly efficient, but in reality, it is prone to several issues: excessive context length, difficulty in locating errors, severe coupling between modules, where modifying one feature might affect multiple pages, and developers struggling to determine if the code truly meets the requirements.
A more robust approach is to proceed module by module. Each module goes through a relatively independent process:
- Clarify the module’s inputs, outputs, and boundaries;
- List the files involved;
- First design the data structure and interfaces;
- Then implement the core logic;
- Finally, add the UI, exception handling, and tests;
- Run checks and record results.
For example, when developing a data entry module, first determine field validation, duplicate checking, and save rules, then implement the service logic, and finally connect it to the UI. This way, even if a problem occurs, you can quickly determine whether it is caused by the interface, data processing, or permission control.
Upon completing each module, the AI assistant should also be required to output a change log, including:
- Which files were added;
- Which files were modified;
- What the core logic is;
- Which scenarios have been handled;
- Which scenarios have not yet been handled;
- Whether there are any temporary solutions.
6. Introduce Independent Code Auditing
After code generation is complete, you should not just let the original development assistant self-check. The code, requirements document, and project constraints should be handed over to another AI assistant for auditing.
The audit focus can be divided into five categories.
Functional Consistency
Check whether the code actually implements the behaviors in the requirements, whether edge conditions are omitted, and whether there are situations where “the UI has an entry point but the backend lacks logic.”
Security
Check whether permission validation is only at the UI layer, whether users might bypass restrictions by directly constructing requests, and whether input could cause injection, privilege escalation, or sensitive information leakage.
Stability
Check whether exceptions are handled correctly, whether the system will crash when external services are unavailable, and whether scenarios like empty data, duplicate submissions, and network interruptions have clear results.
Maintainability
Check whether module responsibilities are clear, whether there is duplicate code, overly complex functions, hard-to-understand variable naming, and implementations that sacrifice long-term maintainability for short-term effects.
Test Completeness
Check whether existing tests cover normal flows, exception flows, permission differences, and boundary data, rather than just verifying one or two success cases.
Audit results should not be directly accepted wholesale. The development assistant can respond to audit opinions point by point, explaining which problems are real, how they plan to fix them, which suggestions are not applicable, and why. After a few rounds of discussion, a final revision list is formed.
7. Design Automated Testing Schemes Early
Automated testing should not be considered only at the end of the project. A better practice is to have the auditing assistant generate a test plan based on the requirements document when feature implementation is nearly complete, and have the development assistant fill in the implementation details.
Testing should at least cover the following levels:
- Verification of individual functions or business rules;
- Verification of collaboration between modules;
- Verification of API inputs and outputs;
- Verification of key UI operations;
- Verification of permission and exception flows;
- Verification of data saving, updating, and deletion.
Test cases should preferably adopt the “Precondition - Action - Expected Result” format. For example:
- Precondition: The user is logged in but has no administrative permissions;
- Action: Access the management page and submit a modification request;
- Expected Result: The system rejects the operation and returns a clear prompt.
At the same time, special attention should be paid to boundary values, including empty strings, excessively long text, duplicate IDs, illegal formats, extremely large or small numerical values, rapid consecutive submissions, and operations after permissions change.
8. Manual Acceptance Remains Irreplaceable
AI tools excel at handling code structure and logic checks, but their judgment regarding real user experience remains limited. Manual acceptance particularly needs to focus on:
- Whether the page layout is clear;
- Whether there is occlusion on mobile or narrow screens;
- Whether error messages are easy to understand;
- Whether there is clear feedback during loading;
- Whether submit buttons can be clicked repeatedly;
- Whether the page is difficult to operate with large amounts of data;
- Whether the steps required for users to complete tasks are too many;
- Whether colors, text, and interactions align with actual usage habits.
In practice, UI issues are often the last type to be exposed the most. Therefore, manual testing is not just “clicking around the page a few times,” but should operate along the task paths of real users and record every detail that does not meet expectations.
9. A Minimum Closed Loop for Non-Professional Developers
For non-programmers, there is no need to pursue a complex architecture from the start. What is more important is to establish a stable process:
- Describe the goal in natural language;
- Let the AI assistant continuously ask questions and form a requirements document;
- Have another type of assistant independently raise objections;
- Freeze the solution after repeated discussions;
- Write the project constraint file;
- Develop step by step by module;
- Conduct code auditing after each module is completed;
- Revise based on audit opinions;
- Establish automated testing;
- Conduct manual acceptance and log issues.
The essence of this method is to transform intelligent programming from “automatically writing code” to “engineering collaboration with documentation, reviews, and tests.” Regardless of the specific tools used, only by forming a closed loop of requirements, implementation, auditing, and verification can we truly reduce rework costs and improve the reliability of software delivery.
