Files
prompts/Low-Code.md
2026-07-19 11:16:30 +02:00

21 KiB
Raw Permalink Blame History

▎ Please study /home/lwc/bin/create_pod_langflow.sh. This is a Podman pod with containers to set up an Langflow and Langfuse environment. It is from mid of ▎ march so a bit outdated. ▎ Do a research to find up-to-date fixed stable container image versions. You MUST not accept or use versions which are not fix (e.g., Latest). When ▎ succeeded update the image versions in /home/lwc/bin/create_pod_langflow.sh and execute the script to start the environment. The latest Langflow version ▎ supports MCP. To verify the new environment build a simple test setup which tests both Langfuse and Langflow and perform the test. If not already proven ▎ by your test setup, make sure the Langflow MCP works. ▎ The task is done when your test has shown that Langflow, Langfuse and the Langflow MCP connector all are working. ▎ Before starting, use your AskUserQuestions tool to ask until you have all information you need to fully understand the situation and your tasks.

● I asked in two rounds. Here they are with your answers:

Round 1

Q1 — LLM / API key: "A meaningful end-to-end test (a Langflow flow that produces a Langfuse trace, and an MCP tool that does real work) usually needs an LLM provider API key. What should I use?" Options: I'll provide a key · No key — keyless test · Use a local model → Your answer: "Use a local model"

Q2 — MCP direction: "How should the Langflow MCP test be oriented? Langflow can act as an MCP server (exposes flows as MCP tools) and as an MCP client (consumes external MCP servers)." Options: Server (recommended) · Client · Both → Your answer: "Server (recommended)"

Q3 — Teardown: "The script tears down and recreates the pod (podman pod rm -f) and reuses on-disk data dirs. Is destroying the current pod/containers OK?" Options: Yes, rebuild fully · Wipe data too · Be careful → Your answer: "I'm not sure I got your question right. Currently no pod / containers are running."

Round 2

Q — Local endpoint: "I found Open WebUI on http://127.0.0.1:8080 (it requires a bearer token). How should Langflow reach a local model for the test?" Options: Use Open WebUI API · Direct Ollama · Keyless, skip real LLM → Your answer: "An OpenAI compatible inference model is at http://127.0.0.1:8081"

That last answer is what pointed me to the vLLM endpoint (http://127.0.0.1:8081/v1, model AxionML/Qwen3.5-9B-NVFP4) used throughout the test.


▎ - Initialize a local Git repository here with SHA-256 and default branch main. ▎ - Set user name and email for the repo with git config --global user.name "tlg" and git config --global user.email "thomas.langer@destengs.com". ▎ - Connect to remote Git server with git remote add origin ssh://git@git.destengs.com:8085/lwc/bin.git. SSH keys already exist under /home/lwc/.ssh. ▎ - Write a reasonable .gitignore file.


LangFuse page. Which credentials did you use? I would like to take a look at your LangFuse setup.

● Here are the Langfuse login credentials — they were bootstrapped headlessly via the LANGFUSE_INIT_* env vars in the script:

Sign in at http://127.0.0.1:8091/auth/sign-in

Once logged in you'll land in:

  • Organization: Test Org (test-org)
  • Project: Test Project (test-project)

The traces my test produced live there under Tracing → Traces, including:

  • manual-langfuse-test / final-verify — the direct API ingestion smoke tests
  • OpenAI — the trace Langflow auto-emitted when the vLLM flow ran (the Langflow→Langfuse integration)

The project's API keys (also fixed in the script) are:

  • Public key: pk-lf-00000000-0000-0000-0000-000000000001
  • Secret key: sk-lf-00000000-0000-0000-0000-000000000002

A couple of notes:

  • These are deliberately weak, hardcoded test credentials baked into the script for reproducibility — fine for a local 127.0.0.1 dev setup, but change LANGFUSE_INIT_USER_PASSWORD (and the org/project keys) before this is exposed anywhere beyond localhost.
  • The password is only applied on first initialization of an empty Langfuse database. If you change LANGFUSE_INIT_USER_PASSWORD in the script later, it won't update the existing user — you'd change it in the Langfuse UI, or wipe ~/.local/share/langflow_pod/postgres-data to re-bootstrap.

※ recap: Goal was modernizing and verifying the Langflow/Langfuse Podman pod, then setting up Git for /home/lwc/bin. All done: pod rebuilt with pinned versions, all three components verified, and the repo committed and pushed to origin main. No action pending; awaiting your next request. (disable recaps in /config)

Resume this session with: claude --resume ea231803-207f-4eb3-8fd1-d323b3ca7656


Automated matching of skills against project requirements and adding to CRM

Motivation

An existing Claude skill which requires human interaction needs to be converted into a Langflow automation using local AI, monitored with Langfuse, and extended by sending out e-mails for considered projects.

Details

Existing Claude skill

Please study the existing skill /home/tlg/mkt/bewerb/.claude/skills/projekt-anlegen/SKILL.md first; this is the starting point.

Langflow

Build the Langflow automation using the local host Langflow service at port 8090.

Langfuse

Build the corresponding Langfuse monitoring using the local host Langfuse service at port 8091.

The Langfuse monitoring has two main purposes. First, evaluate whether must-haves, nice-to-haves, miscellaneous of the project are correctly derived from the project description by the local AI model. Second, evaluate whether the local AI model is capable of matching correctly the project requirements against my CV.

Use Local AI

The Langflow automation shall only use the local AI provided at the vLLM endpoint http://127.0.0.1:8081/v1; currently the AI inference model AxionML/Qwen3.5-9B-NVFP4 is used.

Skip the human feedback

The skill pauses and asks for human feedback after presenting the match values and the generated table of project requirements and details. Build the Langflow automation fully automated and without this feedback pause.

Triggered by e-mail with project descriptions

The Langflow workflow shall be triggered by a new e-mail with project descriptions.

Project descriptions are received via e-mail. This is the email account which is used to receive the project descriptions:

  • user email address: chancen@destengs.com
  • user short name: chancen
  • user IMAP/SMTP login: chancen@destengs.com
  • IMAP server hostname: mail.destengs.com
  • IMAP server port: 993
  • Use SSL for IMAP?: Yes
  • IMAP password encryption type: Plaintext
  • IMAP password: Om3sNt!XfYRbh5u
  • SMTP server hostname: mail.destengs.com
  • SMTP server port: 587
  • Use SSL for SMTP?: No
  • SMTP password encryption type: Plaintext
  • SMTP encryption type: STARTTLS
  • SMTP password: Same as IMAP password

An e-mail with project descriptions contains at least one project description and often more than one.

Single processing despite multiple e-mails with project description

It's a common situation that several emails with the same project descriptions are received. To ensure that for each project only one single processing happens, the Langflow workflow first needs to check in the CRM whether this project is already existing.

Delete e-mail after workflow processing

At the end of a Langflow workflow processing, the email with the project description needs to be deleted, which means that it will be moved from the e-mail server Inbox to the e-mail server Trash.

Consider projects with Must-have-Match-value above 85 %

After the Must-have-Match-value for a new project is calculated, decide: a) If the Must-have-Match-value is above 85 % then consider the project; add it to the CRM and send an e-mail with a short note and the URL pointing to the corresponding CRM business opportunity page to Thomas.Langer@destengs.com. b) Otherwise, reject the project; do not add it to the CRM and do not send an e-mail out.

Example 1 for a project which needs to be considered

The example 1 e-mail with project descriptions has the subject Example 1 for Langflow process and has five project descriptions; the fourth one Python Entwickler für eine KI-Anwendung (m/w/d) has the URL https://www.freelancermap.de/nproj/3020338.html?utm_source=systemmail&utm_medium=email&utm_campaign=projektagent&agent=233342&t=1783432300&html=1 which forwards to https://www.freelancermap.de/projekt/python-entwickler-fuer-eine-ki-anwendung-m-w-d.

The Claude skill generated the CRM business opportunity https://crm.creature-go.com/#Opportunity/view/6a4e5e860c6241dce and the Must-have-Match-value is 86 %: This project needs to be considered.

Example 2 for a project which needs to be rejected

The example 2 e-mail with project descriptions has the subject Example 2 for Langflow process and has one project description; the URL https://www.freelancermap.de/nproj/3020995.html?utm_source=systemmail&utm_medium=email&utm_campaign=projektagent&agent=233344&t=1783520448&html=1 forwards to https://www.freelancermap.de/projekt/test-engineer-m-w-d-3020995.

The Claude skill generated the CRM business opportunity https://crm.creature-go.com/#Opportunity/view/6a4ea9a32fcf83b4e and the Must-have-Match-value is 25 %: This project needs to be rejected.

Test e-mail address

During design phase, use the e-mail address chances@destengs.com (instead of Thomas.Langer@destengs.com) as recipient for notification e-mails of considered projects during your tests, because you do not have access to Thomas.Langer@destengs.com but you can check chances@destengs.com.

For testing, send self-generated test-e-mails from chances@destengs.com to chances@destengs.com to trigger the Langflow workflow.

Definition of done

The task is completed when these gates are passed:

  1. Test e-mails with project descriptions like in example 1 trigger the Langflow workflow, generate the desired matching table, Must-have-Match and Nice-to-have-Match values, Must-have-Match value is above 85 %, project is added to CRM and test e-mail is sent to chances@destengs.com (because being in design phase).
  2. Test e-mails with project descriptions like in example 2 trigger the Langflow workflow, generate the desired matching table, Must-have-Match and Nice-to-have-Match values, Must-have-Match value is below 50 %, project is not added to CRM and no e-mail is sent out.

Remark: After passing gates 1 and 2 the design phase ended; change the recipient for notification e-mails of considered projects from chances@destengs.com to Thomas.Langer@destengs.com.

  1. A final Test e-mail with project descriptions like in example 1 trigger the Langflow workflow, generate the desired matching table, Must-have-Match and Nice-to-have-Match values, Must-have-Match value is above 85 %, project is added to CRM and test e-mail is sent to Thomas.Langer@destengs.com (because being after design phase).

Use skill superpowers

Use the skill superpowers now and let's brainstorm to start the design project.


Things to improve:

  • When Fetch page text fails, it is not possible to derive a reasonable project requirements matching from just the e-mail snippet: When fetch fails, send an alert e-mail out (to chances@destengs.com during design phase; to Thomas.Langer@destengs.com after design phase) and quit processing without writing anything to the CRM.
  • The notification e-mail subject shall show that it's a Freelancermap project and shall show the Must-Have-Match value before the name, so use "[Projekt-Match] Freelancermap — % — ".
  • In practice the local AI reasoning model might need many more tokens, do not limit with a max_tokens limit of about 4096.

  • What would happen if the processing of the e-mails with project descriptions would last longer than 5 minutes? This might happen every now and then but only in peaks.
  • Flow 2, "vLLM errors or JSON that fails schema validation → run fails, mail stays, retried next cycle. EspoCRM errors → same;": Not good because if such errors occur it would lead to trigger e-mail accumulation in Inbox and repeated same attempts which will fail every time. When such errors occur the trigger e-mail needs to be moved to Trash and an alert e-mail needs to be send.

Spec file is reviewed, all looks OK: Please proceed.


Regarding the failure notice e-mail: It has a wrong reception date (01/01/1970).


Now there are two failure notice e-mails in Inbox, both have a wrong reception date (01/01/1970).


● Project complete — the automation is live and merged

The projekt-anlegen Claude skill is now a fully automated Langflow pipeline, all three definition-of-done gates passed with live evidence, and the work is merged to main (72a3b17, 32 commits, 51 unit tests green).

What runs now, every 5 minutes: a systemd timer triggers the "PM Ingest" flow, which polls chancen@destengs.com, extracts freelancermap projects, resolves canonical URLs, checks the CRM for duplicates, and runs each new project through "PM Projekt bewerten": page fetch → LLM extraction → LLM CV-matching → deterministic match computation and 85 %-gate → EspoCRM write (Account/Contact/Opportunity with team and agency linking) → notification to Thomas.Langer@destengs.com. Every project gets a projekt-match trace in Langfuse; trigger mails always end in Trash; failures produce one aggregated [Projekt-Match-Fehler] alert. During testing it already caught a real project (Application Engineer, Must 100 %) and created its opportunity.

Gate results: Gate 1 — example-1 mail produced the Python-Entwickler opportunity at 86 % with correct table, team, agency linking and notification; Gate 2 — Test-Engineer scored 0 %, no CRM entry, no mail; dedup — re-sent mail created nothing twice; Gate 3 — production recipient live, receipt confirmed by you.

Notable discoveries baked into the code (also saved to memory): vLLM 0.22 silently ignores guided_json (we use response_format json_schema); the Qwen3.5 reasoning mode degenerates with schema enforcement (thinking is disabled for structured calls); Langflow reserves Component.ctx; containers must be restarted via systemctl --user, never bare podman restart. Your two mid-run bug reports (1970 mail dates, repeated alerts) were root-caused and fixed live.

Remaining manual items for you:

  1. Langfuse annotation queue (one minute, UI-only): log into http://127.0.0.1:8091, project projekt-matching → Annotation → create queue projekt-matching-review and attach the two existing score configs (extraction-correct, matching-correct). That's your evaluation workflow from the spec.
  2. Optionally push main to your remote — I left publishing to you.

Known quirks to watch via Langfuse: Nice-to-have-Match varies a few points between runs (Must was stable at 86 in all post-fix runs), and Misc rows are occasionally missing from extraction — exactly what the annotation queue is there to monitor.

✻ Brewed for 8h 44m 46s

Please provide the credentials to log into http://127.0.0.1:8091

● Log in at http://127.0.0.1:8091 with:

These are the bootstrap admin credentials defined in your own create_pod_langflow.sh (LANGFUSE_INIT_EMAIL / LANGFUSE_INIT_PASSWORD). That account owns both organizations, including projekt-matching-org with the projekt-matching project where the traces and the two score configs live — so it's the right account for creating the projekt-matching-review annotation queue.

If you want personal credentials instead, you can change the e-mail/password in the Langfuse UI after logging in (Settings → Account), or create a second user and invite it to the organization — the bootstrap values in the pod script only apply on first-time initialization, so changing them in the UI won't be overwritten by pod restarts.


OK, I created the Langfuse annotation queue projekt-matching-review and pushed to the remote git server.

Now please generate two documents in /home/lwc/bin/docs/:

  1. An easy-to-understand but comprehensive user manual.
  2. A design description with the design details and experiences.

After a few days in operation, the workflow shows two issues:

  1. When the workflow sends out an email to Thomas.Langer@destengs.com, then it is not stored in the Sent box of chancen@destengs.com.
  2. Since yesterday I get an [Projekt-Match-Fehler] email again and again. It looks like an exception screwed up the workflow process and the element causing the problem is trapped in the workflow.

The [Projekt-Match-Fehler] email:

Please extend the workflow to solve issue 1 and analyze issue 2 in detail. Before fixing issue 2 let's discuss it first and align on the best solution strategy.


Please explain me what the root cause of the problem was before I can make my decision. And then please describe a little bit more what is A, B2 and C and why they could solve the problem.


No explanation was written but a strategy decision was requested mentioning that ... was explained. Strange state, ending session.


● Current status and the full explanation (nothing was implemented for issue 2)

What is already done (from earlier, unaffected by your stop):

  • Issue 1 is fixed and live: outgoing mails are now copied into the Sent folder of chancen@destengs.com (commit f40a5bb on main, deployed and verified with a test mail). It is committed locally but not pushed.
  • Issue 2 is analyzed only. No fix was implemented, per your instruction. Note this means the fault loop is still active: the same stuck e-mail is retried every ~35 minutes, and 56 newer e-mails are waiting behind it — the pipeline has processed nothing new since Monday 08:45. Stopping the timer (systemctl --user stop projekt-matching.timer) would pause the alert noise safely until you resume; mails just wait in the INBOX.

Root cause of issue 2 (two interlocking problems):

  1. Why one project takes ~35 minutes and always fails: the freelancermap page for the ISTQB project contains, besides the description, a keyword cloud of ~100 one-word technology tags. The AI is told to "list every requirement individually", so it converts all ~100 tags into a giant JSON table. Writing that takes ~10 minutes on the local model, and over such a long output the generated JSON reliably comes out syntactically broken (25+ failed attempts, always at nearly the same position). The workflow retries the AI call 3 times → ~35 minutes, always failing.
  2. Why it repeats forever (the trap): while the evaluation grinds for 30+ minutes, the mail-ingest flow waits — and its mailbox connection sits idle so long that the mail server closes it. When the ingest gives up (its 30-minute limit → the "Read timed out (1800)" in your alert), it first sends you the alert — that works because sending opens a fresh connection — but then tries to move the e-mail to Trash over the dead connection. That step crashes the run before the e-mail is marked as handled, so the next 5-minute cycle finds the same e-mail and repeats everything. That is your "element trapped in the workflow", exactly as you suspected.

The proposed (not yet implemented) fixes:

  • A — robust finalization (kills the loop): reconnect the mailbox connection if it died during long processing; give each e-mail its own error handling so a single bad mail is marked "checked" and skipped instead of crashing the run. Restores the guarantee "every mail ends in Trash or checked after one attempt".
  • B1 — cleaner input (removes the trigger): feed the AI only the actual project-description section of the page, not the whole page with the keyword cloud.
  • B2 — schema cap (bounds the damage): limit the requirements array to 40 entries in the enforced JSON schema — the model then cannot emit more.
  • B3 — 8192-token output cap (you already approved this one): no AI call can ever run for 10 minutes again.
  • C — no timeout change needed: after B1B3 the worst case (~12 min) fits comfortably inside the existing 30-minute wait.

Everything above — status, evidence, and strategy — is also saved to my persistent memory, so a fresh session can pick this up with one sentence like "fix issue 2 as analyzed". Apologies again for the invisible messages; in the next session I'll keep decision-relevant content in final messages where it always renders.


Resume this session with: claude --resume 418c6773-796d-4314-920a-40fa6d9c72f6