实习日志 / English / Journals / Journal 3: Professional Capabilities and Development Process
Journal 3: Professional Capabilities and Development Process
中文 | English
1. My Work: What I Was Responsible For and the Designs It Produced
Designing the Product Agent
Designing this agent starts with a question. General-purpose models such as ChatGPT can already hold a fluent conversation, so why not simply let one take claims? Used as it is, one runs into trouble quickly. It does not know what a rear-end collision claim needs to collect, or when to stop and hand over to a person. It writes down things the claimant never said as if they were facts, and tells the claimant "I've arranged a tow truck for you" when nothing has happened. And it has no standing to decide cover or liability. Public agent platforms and research mostly target general tasks or customer-service settings such as retail and airlines, and what makes claims different falls outside them. The claimant has just had an accident and is under stress. Decisions rest on policy wording and regulatory requirements. A claim runs for days, waiting on documents from third parties such as Police and assessors. And high-impact decisions such as cover, liability, fraud and settlement must be made by people.
Our agent's domain capability therefore comes from the runtime and prompts I built around the model specifically for claims. The runtime is the layer of software wrapped around the model that records facts, checks permissions and carries out actions. The prompt decides what role the model plays and what information it works from. This customisation took shape step by step as the product moved from prototype to MVP to validation prototype, with each round of design growing out of the problems the previous round exposed.
Prototype
The prototype stage set out to pin down the scope of the product. A fixed script walked the complete path from the claimant's first message to staff handling, understanding was left for later, and we agreed that demo scripts would never be written into product behaviour. Even at this stage, facts and permissions already lived outside the model. In each turn, the claimant's message, the agent's reply, the field proposals with their sources and the permission rulings were stored together as one unit. Any sign of injury or danger stopped routine information gathering at once and passed the case to a person. The intent of a turn was expressed through eight actions, among them ask, clarify, confirm, update, hand over and create claim.
MVP: First Round of Research and Design
The MVP meant connecting real models, and the prototype's limits soon showed. The fixed script understood nothing. The eight actions mixed how the agent replied with how the state changed, so a "confirm" was both a message to the claimant and possibly a change to the claim record, and the two could not be validated separately. Models from different providers also differ in their interfaces, capabilities and privacy terms, which called for a single access layer. So I ran a first round of research around three questions: what an agent that can really handle claims should be made of, what others have already proven, and what we would still have to design ourselves. I sorted sources by the strength of their evidence. Official technical documentation can serve as an engineering basis. Public implementations with readable code can be used to check methods and defects. Product descriptions that hide their internals can only confirm how a product is positioned. Vendor claims about effectiveness counted only as product descriptions.
The first group of sources was mature customer-service agent platforms. Dialogflow CX uses "pages" to track where a conversation has got to and moves the dialogue along with parameter collection and re-prompting [1]. We borrowed explicit conversation state and parameter pre-filling, but noted that fixed pages and forms easily slide into an ordered questionnaire, so in our design the order of the conversation and the order of fields are kept apart. Intercom Fin's Procedures combine natural-language instructions with deterministic conditions and code, and support simulations and regression testing of branches [2]. We adopted the same split, using natural language to keep the conversation flexible and controlled conditions and tools to make execution reliable, and required every branch to have tests for success, failure and edge-case inputs. Amazon Connect Cases treats a case as a long-lived work container, with a conversation as just one way in [3], which matches our decision to record sessions and claims separately. Copilot Studio lets the model pick and combine available capabilities, Genesys Agent Copilot gives staff next-step suggestions and handover summaries, and Sierra defines goals and guardrails separately. These fed, respectively, into our approach of letting the model propose candidates while the system decides whether to allow them, and into the design of the staff workbench and handover content.
The second group was insurance-specific products and public implementations. Hi Marley stresses keeping up communication with the claimant throughout a claim. Sprout.ai offers document extraction, policy checking and fraud explanation as separate capabilities. Five Sigma organises staff work around a complete view of the claim, Shift focuses on fraud detection and support for professional decisions, and Indemn stresses keeping insurance workflows and deterministic guardrails outside the model, with an audit trail. Public material like this can establish how a product is positioned, but not how it draws the lines of judgement internally, so we used it only to confirm direction. The same claim record should carry through all later communication, fraud can only ever appear as a signal, and the staff workbench is organised around claim state and outstanding work. AWS's serverless insurance claims sample links services such as claims, documents, fraud, settlement and notification through events and APIs [4]. It shows that an agent can serve as the front door to an existing claims system and that domain services should stay independent. In the sample, however, the voice agent only gets back "requested" after submitting, and the final outcome arrives later as an asynchronous notification in the interface, so the claimant cannot learn the next step within the conversation.
The third group was process and infrastructure tooling. Rasa's flows describe only the business logic and its branches without spelling out every conversation path, and fields can be filled by the model or by deterministic mappings and validated separately [5]. LangGraph and Temporal provide checkpoints, interrupts and durable execution, so a process can pause for days and resume from where it was recorded [6]. Open Policy Agent separates making a decision from enforcing it [7]. Azure AI Search requires results to be filtered by user permissions at retrieval time; retrieving them first and then asking the model not to mention them is not acceptable [8]. LiteLLM shows that many model providers can sit behind one interface. OpenAI's Structured Outputs can pin down the output format, but output in a valid format is not necessarily something the business can act on [9].
Putting these sources together, I arrived at several judgements. The model does not own the claim state. It can understand, extract, explain and propose, but facts and processes belong to the application. A flowchart is not a conversation script. The system needs defined states and branches, yet the claimant may jump around, correct things or pause at any point. A single turn often involves replying, recording, looking things up and arranging the next step. Handing over to a person is a normal capability, and how well it works depends on whether the reason and context are complete. Calling an outside service involves preparing, authorising, submitting, tracking and verifying, and any of these can fail on its own. Retrieved policy content authorises nothing. And evaluation has to examine the whole process, because a correct final answer does not rule out overreach or repeated questions along the way.
From this I wrote the target design during the MVP stage. Every output of the model is only a proposal. Once the runtime has validated it, it becomes an approved plan, and once it has been carried out, the actual result is recorded. Keeping the three records separate means we can always trace what the model wanted to do, what the system allowed and what actually happened. The eight mixed actions were split into six concepts: what the claimant wants in this turn, how the agent responds, what changes the claim record needs, which tools are called, whether the next step is to continue, wait, interrupt or hand over, and what actually happened when it ran. Actions were grouped into five families, each with its own validation and permission requirements: communication, changes to the claim record, human support and review, external services, and runtime control. Decisions on cover, liability, fraud and settlement are left to people alone, and fraud appears only as a signal with its sources. The staff-side agent can be called on in plain language but only ever produces drafts, which are carried out once staff confirm them.
Knowledge of the claims domain went into the runtime as a set of versioned, finite registries. The field registry records what each field means, its type, which product lines it applies to, and whether it is needed now or only before submission. The branch registry records which descriptions cause which fields to grow on the form. The lifecycle registry records the states a case can be in and the legal moves between them. The model can only propose content within these registries and cannot invent new fields or branches. Following Rasa, the flow decides only what the form can grow into, not the order of questions. The form starts with the handful of fields every claim needs. When the claimant says their car was rear-ended, motor fields appear; when they mention an injured passenger, injury fields appear too. Several facts can be taken from one sentence, each recorded against the claimant sentence it came from, and times keep whatever precision the claimant gave. What the claim involves and how far the case has got, including whom it is waiting on, are tracked as two separate sets of state. Policy retrieval is designed to filter first by insurance product, version, effective period and visibility, and whatever it returns is only a basis for judgement.
Model access became a layer of its own, able to work with official APIs, relay services and locally deployed models. LiteLLM showed that unified access is feasible, but the capability, privacy and behaviour contracts were ours to define. Each model profile records the capabilities that have been verified for it, and a model is never given a use that has not been verified. The first real model went in with motor claims. The prompt was modelled on a personal client manager, professional and restrained in tone, kept under version control, and the model's output was held to a strict structure. By the validation prototype stage, the design covered all three product lines, motor, home and contents, with branches that do not overlap. The team deployed an open-source model on its own server, reached over a private network, so that each session could choose between the local model and a cloud model, as a fallback in case claimant data could not go to the cloud. Prompts, model profiles and registries were published with version numbers through an admin console, and the runtime refers only to published versions, so it is always possible to trace which version a given turn used.
Validation Prototype: Second Round of Research and Context
Once real journeys were running across all three product lines, speed became a pressing problem. A simple question could take more than eighty seconds to get a reply. I first had the system record what went into each turn's requests, and found that every ordinary turn called the model twice. The first call carried the full prompt, the claim data and the tool for reading the claim. The second sent all of that again, along with the read result and the full output format. Together they came to about nine thousand tokens, more than three times the design limit. On top of that, the set of tools changed from turn to turn, which broke the cache, and conversation history was cut off purely by message count.
To find out how mature systems handle this, I ran a second round of research into how 12 systems manage context: the AI coding tools Kiro [10], Cursor, Claude Code [11], Codex, Aider [12] and Sourcegraph Cody; engineering articles from Anthropic [13] and Manus [14]; and the relevant mechanisms in the OpenAI Agents SDK, Google ADK, MCP and Amazon Bedrock [15]. Several practices kept coming up. The always-loaded core is kept as small as possible. Kiro, for instance, decides when a piece of guidance enters the context in one of four ways: always, when a file matches, by semantic relevance, or when referenced by hand. Catalogues of capabilities are kept apart from their full content. Cursor, Claude Code and Codex keep only the names and descriptions of skills loaded, reading the full text only when a skill is used, and Aider first gives the model a very small map of the codebase before reading specific files as needed. Deterministic conditions come before semantic matching. Sourcegraph Cody uses both the fixed relationships between pieces of code and semantic retrieval, without folding them into a single similarity score.
There is also broad agreement on history. The OpenAI Agents SDK keeps the full stored history apart from the history fed into the current turn, and Google ADK uses a token threshold as the main trigger for compaction, with message count only as a secondary one. On caching, Manus treats the cache hit rate as a key metric for production agents. Bedrock caches in the order tools, system prompt, messages, so changing the tool definitions invalidates everything cached after them. MCP requires tool lists to come back in a fixed order and treats discovery, authorisation and execution as three separate boundaries. The Claude Code documentation also notes that instructions placed in the context are only guidance, and that anything which must be reliably blocked has to be enforced in code. This matches our own principle that prompts cannot stand in for runtime validation.
Building on these practices, my central judgement was that letting the model know something exists and sending it that thing's full text in the current turn are two different actions. Taken further, an item being discovered, selected, loaded, authorised and executed are five distinct states, and blurring them together is the common root of both context bloat and overreach. The optimisation goal followed from this. While staying correct, properly authorised and traceable, an ordinary turn should call the model only once, keep information dense and the cache prefix stable, and be able to account for any extra loading in terms of its reason, source and authorisation. On that basis I designed layered loading. A small set of safety and permission requirements travels with every turn, and everything else is loaded according to the current product line and task. The model first sees only the identifiers and summaries of materials and fetches the full text when it needs it. The full conversation is stored outside, and each turn carries only a snapshot of the current claim, the open questions and the last few turns. The order of tools, output format and prompt is fixed per scenario and versioned, with the changing claim content placed after the fixed prefix.
Tuning the Model, Runtime and Prompts Together
With speed under control, a deeper problem came to the surface. While tracing an error that broke a conversation midway, we found that "what to ask in this turn" was decided by a function that does not understand language, and the model that understands the claimant had no say in it. Every turn, the function ran down a fixed checklist from the top, picked the first unconfirmed item to ask about, and swapped the model's own question for a fixed template. It was not the only problem of its kind. As soon as a claimant mentioned an injury, the runtime handed the case over and stopped calling the model, so nothing the claimant said afterwards got a reply. The test for whether a sentence had "confirmed" a fact was so strict that a simple home claim took twenty back-and-forth steps. Some branches had been built without the dedicated fields they needed. And while the domain model defined seven states for a field, the conversation logic had squeezed them into three: filled, empty and enough. The legitimate answer "the claimant says they don't know" disappeared as a result, and the model would sometimes make up an answer just to fill a field.
The design was first revised by patching, over several rounds, each round resolving one specific contradiction. I then walked through the new version end to end in a real browser. The claimant explained the rear-end collision in the very first sentence, yet the agent still asked them to describe what happened. The same thing was asked twice. In reply to a simple "yeah", the model invented a record that someone had been injured. Internal field codes showed up in the conversation, and a service card that should have appeared did not. I concluded that the patching route had failed. Every patch had improved how the runtime verified something, and none had asked who should be making the judgement in the first place. The more patches went in, the more finely the runtime made decisions on the model's behalf, while the direction itself was wrong. I then set out a number of design foundations to test every later design decision against:
- the claimant should never sense the runtime, which shows itself only when it stops something for safety or permission reasons;
- the model decides what to do in a turn, and the runtime decides whether it can be done and how to get it done;
- the runtime holds the skeleton of the form, the model fills it in, and any field may legitimately be "not known yet";
- a submission is complete when staff can pick it up and work on it directly;
- files matter as much as the conversation.
With these foundations in place, the runtime pulled back to the boundaries. Deciding what to ask next, how to word it and how to write the summary went back to the model. The runtime kept the jobs of checking what the claimant actually said, drawing the lines between product lines, authorising irreversible actions and holding the line on safety. In the normal flow the runtime no longer produces any text the claimant can see, and an automated check makes sure of it. A further check keeps what the model says in line with what the system has recorded. If the model mentions a service that was turned down, or claims that something unauthorised has been done, it is asked to rewrite once with the runtime's ruling in hand, and if it still fails, a fallback reply is used. Promising something that will happen, such as "I'll pass your claim to the claims team", is fine, but "it has been submitted" must be backed by a system record.
Fields got all seven states back, and each field was given four legitimate end states at submission: filled; answered approximately, which is good enough; not known now but to be supplied later; or something the claimant should never have been asked, to be filled in by a third party. The model can mark a field as "to be supplied later" or "awaiting a third party", but the runtime checks whether the claimant's own words support the mark, and "awaiting a third party" also needs a record that the claimant agreed to the service involved. Files are treated on a par with the conversation. A file may arrive unprompted from the claimant, be provided at the agent's request, or be obtained by the agent from a third party on the claimant's behalf. Values read from a file are the model's interpretation and start out as "to be confirmed".
Judging the product line went back to the model. The drop-down that made claimants pick a product line up front was removed, and the old keyword matching was demoted to a ranking hint and a fallback. The model's say is limited to the first product-line branch, and when a description fits more than one product line or clashes with facts already confirmed, the agent has to ask the claimant. Each turn has a single authoritative product-line result, which routing, context, service selection and fields all rely on. Third-party services went the other way, into the runtime's hands. The runtime picks a service from the registry based on the turn's product line and the claimant's intent, while the model supplies only a limited intent code and does not copy service identifiers. The core reply and the service cards were separated, so an error in one card affects only that card and the reply still goes out. On whether to keep replying to a claimant after a handover, a teammate had already built a silent design. After checking what handovers actually cover, I adopted it, with one exception: a retry of the same request, cut off by a network failure, is still processed to completion.
Choosing the model was part of the tuning as well. In testing, the model marked even fields it could plainly work out as "later", and I judged this to be a gap in the model's capability. When switching models I therefore changed only the model size and kept the provider, so that the result would confirm or rule out that judgement directly. After the switch, the same facts were extracted correctly in a single pass. The switch that turns off thinking mode had originally been wired only to the local model, and during tuning it was wired to the cloud models too, which cut waiting times further.
Adjusting to the Real Claims Process
At a sprint presentation, industry judges pointed out that the claims process the system showed needed to reflect how claims really work. After a rear-end collision, people usually note the other party's registration, driver and insurer first. When someone is hurt, Police are often involved. And the excess is treated differently depending on who is at fault. An interface that merely looks like a claims system does not show that the product solves the problem. The academic supervisor pointed to another gap, from the user's point of view. The list of third-party services that pops up after the claimant's first message is confusing: the claimant cannot tell what the pop-up means, or what they can do and what help they will get once they are in the conversation. The supervisor suggested making the whole journey clearer, for example by replacing the pop-up with a quick-start claim guide.
We gathered this feedback into a list of gaps, checked each one against the code, and researched the real claims process again. The comparison showed that the system had treated "getting through a conversation smoothly, extracting safety-related facts and working out the product line" as the end point of a claim. A real claim also needs the information behind liability assessment, excess calculation, contact with the other party's insurer and verification of Police documents. There were no fields yet for the driver, the other vehicle and its insurer, or witnesses. And the claimant's policy number was just a string of text, so the system could not tell which policy tier or excess structure it belonged to. During this research I also checked whether the criticism had led me astray, and corrected two of my first ideas. First, a shaken claimant usually starts by telling what happened, and good practice is to let them finish before asking follow-up questions, so the open conversational entry point was not itself the problem, and scenario prompts are only an optional convenience. Second, the claim number should be issued at first contact, which the system already did.
From this came the adjustments for the current version of the agent. Checking on safety moves to the very start, and the agent raises it itself. Once the claimant has told what happened, the agent first plays the account back for confirmation and then asks targeted questions about the gaps. Information that is easiest to get at that moment, such as the other party's details, witnesses and the status of the Police report, is added as fields. Where policy wording calls for professional judgement, the agent sets out the basis and offers a preliminary view that can be checked, for staff to decide on, with the limits of its authority unchanged. The claimant's policy is to be linked to its actual excess structure, so that the claimant can find out what they would pay under it. When handing over to a person, the agent tells the claimant why. Following the supervisor's suggestion, the entry point and the experience after the first message are to become a clear claim guide. We are now working on these adjustments.
How the Agent Serves the Claimant Journey
Following the claim process from the claimant's side shows how the design above plays out at each stage of the journey, and where the backend logic and the interface each come in.
Entry. Claimants can start a claim without signing in, and can use voice input, because someone who has just had an incident may be in an urgent or anxious state. The entry point is a chat box with optional scenario prompts beside it. Claimants do not need to work out first what kind of incident they have had. The agent determines the product line from their description.
Telling the story. Claimants can give a lot of information at once. The agent pulls several facts out of a single sentence and records where each came from. It does not ask again for anything it already knows, only for what is genuinely missing to reach the next step.
The form. Beside the conversation sits "What we know so far", showing the value, source and status of each fact, with anything new from the current turn highlighted. Claimants can edit it directly or ask for corrections in the conversation. Anything the model proposes takes effect only once the claimant confirms it, and an out-of-date page cannot overwrite newer facts. The form starts with the handful of fields every claim needs and grows fields for the type of incident as the claimant describes it. Each field can end up filled, roughly known, to be supplied later, or left for a third party to fill. "I don't know" is a legitimate answer in its own right.
Documents. Documents may come from the claimant unprompted, at the agent's request, or from a third party that has to issue them, such as a Police report or an assessment report. The backend tracks each one separately. If one has not arrived, only the steps that depend on it wait, and the rest carry on as normal.
Third-party services. When an assessor, tow truck or repairer is needed, the agent shows a service card below the relevant reply, explaining what information will be shared, with whom and why. Claimants can say they do not need it for now, or agree and withdraw later. Each request's preparation, submission, processing, failure and unknown outcome are recorded separately, and until the system confirms, the agent never says something has been done.
Handover to a person. When a claimant asks for a person, the system hands over straight away. When there are signs of injury or danger, the runtime interrupts the routine flow and escalates before the model is even called. The handover carries the confirmed facts, what is still missing, the status of documents, risk signals and the reason for the handover, so the claimant does not have to repeat themselves to staff.
Staff take-over. The staff workbench follows the order in which staff work. The first screen answers which claim to deal with now, where it is stuck and what comes next. The action area shows only the actions allowed in the current state, and evidence, history and the full conversation open up on demand. Fraud appears only as a signal with its sources, and the interface draws no conclusions. Staff must pick up a case before working on it, so two people never change the same record at once. The staff-side agent only provides drafts, which become formal actions once staff have edited and confirmed them, and permissions are checked again when they run.
On the backend, sessions and claims are recorded separately, so one claim can span several sessions. Every change carries a version number, so an older version can never overwrite a newer one. If a claimant sends the same message twice, it takes effect only once. And when processing fails, no half-written state is left behind. On the interface side, the front end presents only what the product can really do. Features whose backend is not ready are shown as unavailable, with the reason. Waiting is shown as waiting and failure as failure. The process state is the single source of truth, and the interface simply presents it. On refresh, on going back or on entering a URL directly, the page checks the state first and never renders half a page.
2. Professional Capabilities: What I Learned About How to Work
Planning, Organisation and Establishing Collaboration Norms
Adjusting the plan to reality. I was responsible for the team's iteration goals and task breakdown. The breakdown starts from the iteration goal and works down through capabilities and work packages to tasks that can be finished in an hour or two, each with a single owner, clear inputs and outputs, acceptance criteria and dependencies. The planning method itself changed several times as problems came to light. Those changes showed me that a plan needs validating like anything else: whether a way of dividing the work is right depends on whether the team can put the pieces together into a complete result that passes acceptance. The format of task cards settled into a standard along the way, so that when team members and their tools read the same card, they all understand what to do and what counts as done.
Risk management. Insurance data is personal data, and a real insurer may well refuse to let it leave for a cloud model. We therefore kept the model replaceable and prepared a locally hosted fallback, so that swapping models would not mean redesigning the agent. Claimant data is shared with third parties only after the claimant agrees. The lesson I took from this is that risk is cheapest to manage before it arrives: asking at decision time what happens if an assumption fails costs far less than repairing the damage afterwards.
Improving efficiency. Most of the team had never worked in a repository run to consistent standards, so the repository itself had to show what good collaboration looks like: task templates, collaboration rules, and a Kanban board that moves on its own as development progresses, so that nobody has to keep the whole project in their head to get started. Then, on one occasion, a change was merged even though every one of its checks had failed, and it broke the main branch. After that I turned the rules into checks that run automatically, with a gate at each stage from local push to server-side merge. Later I moved checking forward to the point where tasks are created, so that a task that cannot say what problem it solves is flagged before anyone spends time on it. Everyone on the team works with AI coding tools, so the rules sit at the entrance every tool reads on entering the repository, and tools must state their understanding of a task before taking it on. What this made clear to me is that writing rules down does not mean they will be followed. Norms only keep working once they are built into checks that run by themselves.
Research and Technical Judgement
Finding information and grading evidence. When researching agents, I weighed evidence by how credible its source was, and treated vendor claims about effectiveness as nothing more than product descriptions. I applied the same standard to the team's user research, separating facts, judgements and assumptions, using conclusions from small samples only to set priorities, and treating public comments as individual examples. I came away convinced that the more material there is, the more it matters to ask first how much each piece can actually prove, before deciding whether to rely on it.
Critical reading and verification. While we were tuning the agent, problems that unit tests had missed surfaced together once the complete claim flow was run: the agent kept asking about things the claimant had already said, and wrote down facts the claimant had never given. Tests check the expectations we wrote down. If those expectations have drifted away from what the claimant actually experiences, passing every test proves nothing about whether the product is right. In the same way, a capability that is "registered" in the documentation is not necessarily one that "can actually run". Code review reports need the same kind of reading. Before one merge, a report listed several blocking issues, and I asked for each one to be verified and traced to its root cause before any change was made. The lesson for me was that acceptance criteria should be set from the claimant's complete experience, and that with any conclusion from a document, a test or a report, I first need to be clear about what it actually proves.
Defining the problem. Most of the detours in this project trace back to one cause: we had not grasped what the problem really was. Designing from the surface description of a problem, however carefully, can end up solving a secondary or even a wrong problem, and such mistakes often surface only in real testing or external review, by which time a good deal of work has piled up that has to be undone. The agent's conversation growing stiffer with each revision for a while, and the system for a while treating a smoothly finished conversation as the end point of a claim, are both examples. What I take from this is that a design cannot be good if it misses the heart of the problem. When a design starts being patched again and again, or outside feedback points to a gap in its direction, I now go back first and check whether the problem itself was defined correctly, before discussing how to change anything.
Seeing the big picture. Modules that each make sense on their own can clash when they are put together. For a while during the agent's development, every round of patching resolved one specific contradiction, yet the conversation as a whole grew stiffer and stiffer. It taught me that getting the parts right is no substitute for judging the whole. A change has to be weighed against the entire claimant journey and the entire project, and when one way of patching keeps failing, it is time to stop, go back to the goal and rethink the direction. The stages of the project also showed me that "done" means different things at different points: the prototype needs a complete path, the MVP needs repeatable runs, the validation stage needs real journeys that prove value, and after the freeze only problems that affect validation get fixed. Trade-offs belong in this big picture too. Between asking everything and the claimant's patience, for example, we chose to ask only what the next step really needs.
Staying sceptical. When industry judges said the process was "not realistic enough", I first broke that comment down into questions that could be checked, then researched them. Along the way I also held my own first ideas for improvement up against the evidence, found that two of them had been pulled off course by the criticism, and dropped them. Later, while checking a teammate's request, I found that a judgement I had earlier written into a task was wrong, and corrected it publicly. Both episodes brought me to the same conclusion: outside feedback and my own conclusions alike are hypotheses to be tested.
Working with People
On negotiating and handling disagreement: when a design question was not mine alone to decide, I turned it into a topic, set out what had to be decided, what the options were and what each would cost, and brought it to the team. During the interface redesign I prepared thirteen such topics. I found that framing a disagreement as a topic with options and costs makes agreement easier to reach than arguing it out. Where a disagreement touched existing designs, I treated two cases differently. If the team had already made a clear decision, I followed it and raised only well-founded exceptions separately. If a change would break the design foundations, I held to the original principles and did not give way point by point.
On ownership of the project: from the middle of the project onwards I effectively took on the coordinating role of team lead, and it taught me that a coordinator's job is to make the boundaries clear, while the way work is done inside each boundary is for that area's owner to decide. Changes that cross boundaries are raised first through written proposals. When the front end needs a new backend field, for example, a field proposal goes to the backend owner first, and the front end does not add the field on its own. For work with clear boundaries, I gave the owner written authority to decide the approach independently, with a check-in needed only if something went beyond the agreed scope.
On coordinating across roles: on the night the continuous integration service stopped working because its quota had run out, I set up the most urgently needed merge checks and board syncing overnight as a stopgap, submitted an access request for the new platform first thing the next morning, and emailed the administrator to explain what had happened. The lesson was that anything needing someone else's approval should be raised at the first opportunity, and that automation is no substitute for timely communication. Working with teammates also has to be divided along boundaries, with each side meeting the other only at interfaces agreed in advance, and any handover material between roles must set out those boundaries first.
References
[1] Google Cloud, "Dialogflow CX: Pages." [Online]. Available: https://cloud.google.com/dialogflow/cx/docs/concept/page
[2] Intercom, "Fin Procedures explained." [Online]. Available: https://www.intercom.com/help/en/articles/12495167-fin-procedures-explained
[3] Amazon Web Services, "Amazon Connect Cases." [Online]. Available: https://docs.aws.amazon.com/connect/latest/adminguide/cases.html
[4] Amazon Web Services, "Serverless insurance claims processing (aws-samples)." [Online]. Available: https://github.com/aws-samples/serverless-eda-insurance-claims-processing
[5] Rasa, "Flows." [Online]. Available: https://rasa.com/docs/reference/primitives/flows/
[6] LangChain, "LangGraph: Durable execution." [Online]. Available: https://docs.langchain.com/oss/python/langgraph/durable-execution
[7] Open Policy Agent, "Open Policy Agent documentation." [Online]. Available: https://www.openpolicyagent.org/docs/latest/
[8] Microsoft, "Security filters for trimming results in Azure AI Search." [Online]. Available: https://learn.microsoft.com/en-us/azure/search/search-security-trimming-for-azure-search
[9] OpenAI, "Structured Outputs." [Online]. Available: https://developers.openai.com/api/docs/guides/structured-outputs
[10] Kiro, "Steering." [Online]. Available: https://kiro.dev/docs/steering/
[11] Anthropic, "Claude Code: Agent skills." [Online]. Available: https://docs.anthropic.com/en/docs/claude-code/skills
[12] Aider, "Repository map." [Online]. Available: https://aider.chat/docs/repomap.html
[13] Anthropic, "Effective context engineering for AI agents." [Online]. Available: https://www.anthropic.com/engineering/effective-context-engineering-for-ai-agents
[14] Manus, "Context engineering for AI agents: Lessons from building Manus." [Online]. Available: https://manus.im/blog/Context-Engineering-for-AI-Agents-Lessons-from-Building-Manus
[15] Amazon Web Services, "Prompt caching for faster model inference." [Online]. Available: https://docs.aws.amazon.com/bedrock/latest/userguide/prompt-caching.html