Begin with proven experience, not the size of the portfolio. Ask to see three or four projects that resemble your technology stack, and then find out whether those engineers are still with the company. An honest provider will put you on a call with the people who would work on your project. Answers that name nobody at this stage usually mean the delivery team is not the team you were shown.
The agreement warrants more scrutiny than the proposal. A few clauses carry most of the weight: intellectual property assignment, non-disclosure, and which is better laravel or symfony termination and handover. Every artifact should transfer to you once invoices are settled, along with documentation, pipelines and deployment scripts. Watch for wording that keeps reusable components in the vendor’s hands, as it is usually the dependency that makes switching painful.
Ask how they estimate. An honest estimate comes with a written set of assumptions, a breakdown per feature and an explicit range. A fixed-bid deal works only when the scope is genuinely frozen; otherwise the supplier prices the risk in and you fund the buffer regardless. Hourly billing moves the risk back to the client, so it needs visible weekly reporting and a spending cap.
How the work is run matters more than headcount. Establish how a new requirement enters the plan, who defines done and how testing is organised. A mature team will be able to show you hire a full stack developer live build at the end of each sprint. Acceptance criteria in writing are your only real protection against an argument at delivery time.
Before signing, consider the end of the engagement at the start rather than at the end. Ask that the repository lives on infrastructure you own from the beginning, and that documentation is written as you go rather than left to the end. A partner who is comfortable with this accepts it without argument; hesitation here says most of what is rag and langchain you need to know.