RESEARCH · Sep 21, 2026 · 7 min read
How LinkedIn Post Studio is adding AI Assist without losing user control
A build-log on LinkedIn Post Studio's AI Assist tab: local models, BYO provider keys, ten scoped writing actions, editable prompts, and structured output.
- The Forge
- linkedin-post-studio
- ai-assist
- llm
- prompt-engineering
- structured-output
- ollama
- open-source
- privacy
- content-tools
The formatter works. You paste Markdown, it gives you LinkedIn-ready plain text, you copy it out. That part shipped.
The next question was obvious: can the tool also help you write the post, not just clean it up? Generate hooks, suggest hashtags, rewrite the tone, shorten the draft. Every content tool eventually faces this question, and the answer is always "yes, but."
The "but" is where the interesting decisions live. This is a record of those decisions for LinkedIn Post Studio, what we built, what we paused, and why.
The provider problem: one API or seven?
Most writing tools that add AI pick a single provider. You sign up, they hold the key, and the LLM call happens on their backend. That works, but it locks users into one vendor's pricing, rate limits, and model quality.
We went the other way. The settings panel supports seven providers: Ollama (local), OpenAI, Anthropic, Google Gemini, Groq, Mistral, and OpenRouter. Each stores its own base URL, model name, and API key in the browser's localStorage. Nothing leaves the device until the user explicitly runs an action.
Ollama is the default. It runs on your machine, needs no API key, and keeps the draft entirely local. For users who want faster or more capable models, the cloud providers are there with a bring-your-own-key setup. OpenRouter adds a fallback: one key, dozens of models.
This is more work than picking one provider. Each has slightly different API shapes, error responses, and rate-limit behavior. The trade-off is that users choose their own cost, speed, and privacy posture instead of inheriting ours.
Ten actions, not one chat box
A general-purpose chat box inside a content tool is tempting and usually wrong. "Make this better" is too vague for reliable output. The model doesn't know if you want a shorter post, a different tone, or a stronger opening line.
We defined ten specific actions instead:
Writing actions take raw input and produce a draft:
- Generate a complete post from an idea
- Turn rough notes or bullets into a structured post
- Improve an existing draft for clarity and flow
- Shorten a post while keeping the core message
Tone actions rewrite in a specific direction:
- Professional (clear, specific, human)
- Conversational (warm, personal, readable)
Component actions produce specific artifacts:
- Generate 5 hook options for the current post
- Improve the opening hook with 5 alternatives
- Suggest 5 to 8 hashtags (broad, niche, and topic-specific)
- Create 5 natural call-to-action options
Each action has its own system instruction. The prompt builder combines the action instruction, the user's brief, the current post text, and a tone setting into a structured request. This is narrower than a chat interface but more predictable. The model knows exactly what output shape to produce.
Prompt design: what the system message actually says
The system prompt carries a set of constraints that apply to every action:
- Write for creators, founders, operators, and technical professionals
- Return plain text only, no Markdown headings, no quote wrapping
- Use short paragraphs and LinkedIn-friendly spacing
- Do not invent personal experience, credentials, metrics, clients, or named examples
- Respect any audience, goal, length, and voice notes the user provides
- For hooks or hashtags, return only those options, nothing else
The "do not invent" rule matters more than it looks. LLMs default to fabricating credentials and success stories when writing LinkedIn-style content. A post that opens with "When I scaled my startup to $10M ARR" is convincing until you remember neither the model nor the user said anything about a startup. The constraint forces the model to work with the user's actual input.
The user message includes the action name, tone, instruction text, the user's idea or direction, and the current post. Separating these fields makes the prompt auditable. You can see exactly what the model received.
Structured output: the part that isn't solved yet
Here's where the project is honest about what's unfinished. The current Assist panel returns free-form text. When you ask for five hooks, you get five lines of text. When you ask for hashtags, you get a paragraph that usually contains hashtags.
"Usually" is the problem. Different models format their responses differently. One returns a numbered list, another uses bullet points, a third wraps everything in an explanation. Parsing these reliably across seven providers and dozens of possible models is not a prompt-engineering problem alone.
The fix is structured output: telling the model to return JSON that matches a defined schema, then validating the response before displaying it. OpenAI's API supports this natively with response_format: { type: "json_schema" }. Anthropic achieves it through forced tool calls. For Ollama and other providers, it's a prompt-engineering exercise with client-side validation as a safety net.
This is tracked as an open issue in the repo. Until it ships, the assist output works but isn't programmatically reliable. You can read it and use it. You can't safely pipe it into another tool without a human checking the result.
What we paused and why
Active Assist development is paused. The formatter shipped and works. The AI features are in the codebase, functional enough for internal use, but not yet reliable enough for public contribution.
The specific gaps:
Per-action panels (issue 2): each action should have its own UI instead of sharing one generic text area. A hook generator should show five options in cards you can click to select, not a text block you have to read and manually copy.
Editable prompts (issue 4): users should be able to modify the system and action prompts in Settings. The current prompts are hardcoded. Different audiences and industries need different constraints.
Structured output parsing (issue 5): the model's response needs to be parsed into typed objects (hooks as an array, hashtags as a list, posts with metadata) instead of treated as raw text.
Provider quality and recommendations (issue 6): different models perform differently on these tasks. Ollama with a 7B parameter model produces serviceable hooks. It struggles with tone rewrites. The tool should surface this, not leave users to discover it.
Provider test harness (issue 7): a way to run the same prompt against multiple providers and compare latency, output quality, and cost per request.
These are all scoped, concrete problems. None of them are research questions. They're engineering work that's been deferred in favor of keeping the formatter stable and the codebase clean for public contribution.
What this means for the project
The AI layer in LinkedIn Post Studio is designed as optional infrastructure, not the product's identity. The formatter works without it. The static GitHub Pages demo ships without it. A user who never configures a provider still gets the core value: paste Markdown, get LinkedIn-ready text.
When the AI features ship fully, they add a second layer: the tool also helps you write and refine the post, not just format it. That's a meaningful expansion, but only if the output is reliable enough that users trust it more than a blank text box.
The honest position: the prompts work, the provider system works, the action definitions are clear. What's missing is the structured output layer that makes the results programmatically useful and the per-action Assist UI that makes each workflow pleasant to use. Those are the next pieces of engineering work.
Where to contribute
Every gap described in this article is tracked as an open issue on the repository. If you want to help build this, start here:
- Per-action Assist panels: https://github.com/403ai/linkedin-post-studio/issues/2
- Editable prompts in Settings: https://github.com/403ai/linkedin-post-studio/issues/4
- Structured output parsing: https://github.com/403ai/linkedin-post-studio/issues/5
- Provider quality and model recommendations: https://github.com/403ai/linkedin-post-studio/issues/6
- Provider test harness: https://github.com/403ai/linkedin-post-studio/issues/7
The contribution guide covers setup, code style, and how to open a useful PR: https://github.com/403ai/linkedin-post-studio/blob/main/CONTRIBUTING.md
Sources:
- OpenAI, Structured Outputs documentation (response_format with json_schema): https://platform.openai.com/docs/guides/structured-outputs
- Anthropic, Tool use and structured output: https://docs.anthropic.com/en/docs/build-with-claude/tool-use
- Ollama, API documentation (local model serving): https://github.com/ollama/ollama/blob/main/docs/api.md
- Twardziak, P., "Structured output from LLMs: more than just prompt engineering" (2025): https://medium.com/@twardziak.p/structured-output-from-llms-more-than-just-prompt-engineering-b47408a0f8d3
- Li, G. et al., "Tweetorial Hooks: Generative AI Tools to Motivate Science on Social Media" (2023, AAAI): https://arxiv.org/abs/2305.12265
Research scope: codebase review and documentation analysis. This piece describes the current architecture and planned work, not a benchmark or comparative evaluation.
Idea: the Markdown-to-LinkedIn problem · Research: how LinkedIn handles formatting · Lab: LinkedIn Post Studio