All posts
Updated

Employee portrait and data connections

Line up the employee-portrait data list with the authorized queries in your workspace.

Source docs/en/site/portrait-pipeline.md

In user language: This article is for workspace admins. It explains how to line up the employee-portrait skill’s fixed fetch list (pipeline) with predefined queries on the HR data connection, and what to say to the work agent in Messages to do that once. Everyday users only say “generate so-and-so’s employee portrait”; they do not need to know pipeline or query_id. Implementation notes are in Implementation map at the end.

Date: 2026-07-12 Read first: Building an employee portrait from chat CareTop / Rilong extras: docs/data-connection-templates/caretop-employee-profile/ Query template JSON: examples/employee-profile-pipeline/data-connection/query-defs.example.json


Takeaway

The source of truth for fetch order on the employee-portrait skill is the attached file references/pipeline.json. Each step hard-codes a canonical query_id (e.g. employee_by_name).

If the HR data connection (slug rilong, for example) only has another set of ids such as eaemp_by_name and eacontactinfo_by_empid, the agent still reads the pipeline, but at run time it invents a mapping on the spot, fires extra ad-hoc queries, or even falls back to handwritten HTML — the user can still get a report, but it is not the intended fixed path.

Recommended alignment (path A): do not change the pipeline. In conversation, an admin writes the canonical queries the pipeline needs onto the data connection (query.upsert), then verifies each one.

Not recommended (path B): rewrite the pipeline to Rilong’s native scattered query ids — conversation tools cannot change references/pipeline.json in one step, and that would break the “one step, one save_as” design.


1. What happens when they are not aligned

From a real conversation “Wu Jingrong employee portrait” (work agent 3e30250e-…):

What you seeNotes
Pipeline was readskill_script_read loaded references/pipeline.json
Fetches did not use pipeline query_idPipeline wants employee_by_name; actual call used eaemp_by_name
Extra ad-hoc queriesDepartment / title / salary dictionaries, extra manager lookup, beyond pipeline steps
Fallback after run_script failedError “script output must not be .html”; then handwritten file_write HTML, layout unlike assets/profile.html

After alignment, a similar conversation should look like:

  1. query.run uses employee_by_nameemployee_contact_by_emp_id → … (matches the pipeline)
  2. run_script + assemble_profile.py produce fixed-layout HTML
  3. No on-the-spot mapping of Rilong native ids

2. Which query_id the pipeline needs

Mapping of references/pipeline.json steps to canonical queries (full SQL in the example JSON):

Pipeline stepquery_idPurpose
resolve_employeeemployee_by_nameLook up master record by name; get empId, employee number, etc.
fetch_contactemployee_contact_by_emp_idMobile, email, address, etc.
fetch_orgemployee_org_by_emp_idDepartment, title, direct manager
fetch_contractemployee_contract_by_emp_idContract (optional)
fetch_salaryemployee_salary_by_emp_idSalary summary (optional)
fetch_photoeaemp_photo_by_idID photo (optional; pipeline already uses this id)
Photo fallbackmostayentryphoto_by_empnameOnboarding registration photo by name (optional)

eaemp_photo_by_id and mostayentryphoto_by_empname often already exist as same-name queries on Rilong. What is missing is the employee_-prefixed portrait-specific aggregate queries.


3. Recommended path A: write canonical queries from chat (admin)

3.1 Permissions and environment

  • Must be a workspace admin (query.upsert)
  • Work in a work-agent conversation with a workspace selected
  • Know the HR connection slug (below uses rilong; replace with yours)

3.2 One-shot wording (paste as-is)

Main wording — write + verify (the platform recognizes this and runs upsert directly; the agent does not need to read a JSON file from the repo):

Help me write the predefined queries the employee-portrait pipeline needs onto the rilong data connection.

Please query.upsert each item from the built-in query-defs list (update if it already exists).

After writing, query.list and confirm at least these exist:
employee_by_name, employee_contact_by_emp_id, employee_org_by_emp_id,
employee_contract_by_emp_id, employee_salary_by_emp_id,
eaemp_photo_by_id, mostayentryphoto_by_empname.

Then query.run each step’s query_id with “吴静荣” and “赵江”;
give me the verification list (count, whether ok).

Note: If the wording includes “employee portrait pipeline + predefined queries + query.upsert”, the platform takes the batch-write fast path (built-in CareTop-adapted SQL) and returns a verification table. Do not mix that with “how many data connections do we have” in the same sentence — the latter only lists connections.

Older wording (repo path; development contrast only — the conversation agent cannot read examples/... and used to get stuck):

Please read examples/employee-profile-pipeline/data-connection/query-defs.example.json …

CareTop / Rilong SQL corrections — the built-in template already covers superiorLeader, eacontactinfo, and similar. If the live database still differs, add:

When writing, correct SQL to our CareTop tables:
- employee_org_by_emp_id: join manager via eaemp.superiorLeader, not superiorId;
- employee_contact_by_emp_id: prefer eacontactinfo (mobileNo etc.), do not only query eaemp;
- employee_contract_by_emp_id: contract table eacontract, fields include affectedDate, ctYears, endDate;
- employee_salary_by_emp_id: query `srfixedsalaryreadjustrec` (typeId=1 base, typeId=2 performance); **do not** use often-empty `srbasicsalary` / `eaemp_salary_view`;
- eaemp_photo_by_id / mostayentryphoto_by_empname: ID photos are in **`eaphoto`** (`photo`, `citizenIDPhoto`); **do not** `SELECT photo FROM eaemp` or `mostayentryphoto` (Unknown column 'photo').
WHERE bind columns use real names (emp_id / emp_name); placeholders only `?`, never @empName.

Batch column-name repair (for existing scattered queries on the connection, not the employee_* set):

Please run smart check and fix on the rilong connection’s predefined queries,
change empId to emp_id and empName to emp_name in WHERE.
See docs/data-connection-templates/caretop-employee-profile/query-defs-sql-fixes.json.
After the fix, query.run each key query once with empId=1980 (吴静荣).

3.3 Verification wording

In the same conversation, you can ask whether alignment worked:

query.list and see whether rilong already has employee_by_name through employee_salary_by_emp_id;
if so, employee_by_name for “吴静荣” should return 1 row with empId=1980.

3.4 Single-query patches (examples)

ProblemYou can tell the agent
0 rows by name“Fix employee_by_name: fuzzy name match + in-employment state; verify with 赵江 / 吴静荣”
Manager name wrong“Fix employee_org_by_emp_id: JOIN manager via superiorLeader to eaemp.id”
Contact empty“Fix employee_contact_by_emp_id: query eacontactinfo WHERE empId = ?”
Contract fields wrong“Fix employee_contract_by_emp_id: match real eacontract column names”
Optional salary fails“employee_salary_by_emp_id should query srfixedsalaryreadjustrec (typeId 1/2), not often-empty srbasicsalary
ID photo Unknown column 'photo'eaemp_photo_by_id should query eaphoto photo/citizenIDPhoto, not eaemp.photo”

4. Not recommended path B: change the pipeline to fit Rilong

ApproachWhy it does not work
Say in chat “change the pipeline to eaemp_by_name”skill_update only edits body Markdown; skill_script_write only edits scripts/*.py
“Update /skill, use a fixed pipeline…”Reinstalls the built-in template, still canonical employee_* ids
Hand-edit pipeline.json in Skill center to Rilong scattered idsOrg/manager needs extra lookups; hard to match assemble.input_shape

If you cannot upsert yet, the agent can still produce a report with Rilong native ids, but that is explore / fallback, not the production standard.


5. What to say to the agent: cheat sheet

5.1 By situation

What you wantRecommended wording
Align pipeline and connection onceSee §3.2 main wording
Skill has no pipeline attachment yetUpdate /生成员工画像HTML(含证件照与统计图),按固定 pipeline 取数,脚本组装 html
Day-to-day report after alignment生成吴静荣的员工画像
Stopped halfway继续把吴静荣的员工画像做完
Confirm alignmentSee §3.3 verification wording

5.2 Phrases to avoid

PhraseWhat actually happens
“Turn the flow we just did into a skill”Write-up skill, no fixed pipeline
“Update the skill” without mentioning pipelineOnly Markdown; fetch list is not installed
“Change the pipeline to use eaemp_by_name”Conversation usually cannot change pipeline.json
Ask the user to explain pipeline.json / run_scriptAgainst user language; say “finish so-and-so’s employee portrait”

6. How you know alignment is done

In Messages, start “generate 吴静荣’s employee portrait” and watch the tool trace (or debug mirror):

sequenceDiagram
  participant U as User
  participant A as Work agent
  participant DS as rilong data connection
  participant S as assemble_profile.py

  U->>A: Generate 吴静荣's employee portrait
  A->>A: Read references/pipeline.json
  loop pipeline steps
    A->>DS: query.run employee_* / eaemp_photo_by_id
    DS-->>A: row data / photo upload_id
  end
  A->>S: run_script assemble
  S-->>A: 员工画像-吴静荣-date.html
  A->>U: mindlink://upload download link

Checklist:

  • [ ] query.run query_id values start with employee_ (except the photo step)
  • [ ] Not a pile of eaemp_by_name, eadepart_by_id, and similar standing in for pipeline steps
  • [ ] run_script succeeds, output_files includes .html
  • [ ] Not a large handwritten HTML file_write as the main deliverable
  • [ ] HTML layout matches the skill assets/profile.html (not improvised CSS)

7. Relation to native Rilong queries

Alignment is not deleting existing Rilong queries such as eaemp_by_name and eacontactinfo_by_empid. Those are day-to-day HR lookup assets.

Alignment adds or updates a set of portrait-pipeline-only canonical ids so the agent does not map every time. Both sets can coexist:

Usequery_id style
Employee-portrait fixed pipelineemployee_by_name, employee_org_by_emp_id, …
Day-to-day scattered HR querieseaemp_by_id, srfixedsalaryreadjustrec_by_empid, …

Parameter key names still follow the connection’s query.list; common Rilong mapping is in docs/data-connection-templates/caretop-employee-profile/PARAMS-REFERENCE.md.


8. FAQ

8.1 The agent still uses eaemp_by_name instead of employee_by_name

  • query.list first and confirm employee_by_name exists; if not, the agent can only map.
  • Run §3.2 main wording and retry.

8.2 After upsert, query.run says Unknown column

8.3 run_script says .html is not allowed

  • Platform default script-output whitelist has included .html / .htm since 2026-07-12; restart the backend for it to take effect.
  • If the workspace customized allowed_output_ext without .html, open it in the capability pack.

8.4 Saying “update pipeline” produced a write-up instead


9. Implementation map

User conceptImplementation
Pipeline fetch listSkill references/pipeline.json (bundled: backend/internal/skillfromchat/bundled/employee-profile/)
Canonical query templatesexamples/employee-profile-pipeline/data-connection/query-defs.example.json
Write queries from chatAgent tool data_source_invokequery.upsert / query.run; or employee-portrait query batch fast path datasourcefromchat.tryEmployeeProfilePipelineQueryUpsert
Built-in query templatesbackend/internal/skillfromchat/bundled/employee-profile/references/query-defs.example.json
Upgrade a skill to pipeline from chatskillfromchat.tryEmployeeProfilePipelineUpgrade (keywords pipeline + script assemble)
Script output HTMLbackend/internal/capability/user_script.godefaultAllowedOutputExt includes .html
CareTop fix listdocs/data-connection-templates/caretop-employee-profile/query-defs-sql-fixes.json

Further reading